ARM嵌入式学习(一) --- 入门51

一、基本概念:

1.CPU(Central Processing Unit):

中央处理器,计算机系统的运算和控制核心,负责指令解释、数据运算和程序执行

2.1GHZ:处理器主频:

MHZ 1MHZ = 10^6HZ

GHZ 1GHZ = 10^6HZ

时间:1/2.1GHZ= 0.476190476us

处理器架构:

x86、MIPS、ARM 32位

x86_64 64位

8051 8位

2.RAM和ROM的区别:

RAM(RandomAccess Memory):

随机访问内存,可读可写,存取速度快,但掉电后数据丢失。用于临时存储程序运行时的变量、堆栈等(ram大小约256byte(字节))。

ROM(Read-OnlyMemory):

只读存储器,数据可长期保存,掉电不丢失。通常用于存储固件、程序代码和固定常量,但写入速度较RAM慢。

内存和外存的区别:

3.其余处理器:

MCU(Micro Controller Unit):

微控制器,集成度高,将所有功能集成到一块芯片里(CPU、RAM、ROM、GPIO、TIMER、UART),成本低,简单控制

MPU(Micro Processing Unit);

微处理器,集成度低,只有一块单独的CPU,需要外接一些功能模块(RAM、ROM、控制器芯片),成本高,应用处理复杂任务,可以跑Linux操作系统

GPU(Graphics Processing Unit):

图形处理单元,处理图形数据,图像渲染

NPU(Neural Processing Unit):

神经网络处理单元,AI推理、硬件加速(Mate 60达芬奇NPUAI拍照优化)

FPU(Float Point Unit):

浮点数运算单元,完成浮点数运算

SOC(System On Chip):

片上系统,将多个芯片集成到一起

二、51芯片:

51芯片内部结构:

  • 8位CPU:完成运算和控制。

  • 数据存储器RAM:128字节(地址00H~7FH),用于存放变量。

  • 程序存储器ROM:4KB(可扩展至64KB),用于存放用户程序。

  • 并行I/O口:4个8位双向口(P0、P1、P2、P3)。

  • 定时器/计数器:2个16位定时器(T0、T1)。

  • 串行口:1个全双工UART。

  • 中断系统:5个中断源(外部中断0/1、定时器0/1、串口中断),两级优先级。

  • 特殊功能寄存器(SFR):用于控制外设和CPU状态(如累加器A、寄存器B、PSW等)。

  • 时钟和复位电路:提供时序和初始状态。

CPU内核是:

MCS-51 8位架构 ,采用 哈佛结构(程序和数据存储器分开寻址),包含 ALU、累加器A、PSW、DPTR 等核心部件

51单片机最小系统组成:

电源 + 时钟电路( 晶振) + 复位电路

三、位运算:

其余位不变,指定位置1:使用按位或t|=(1<<n);

复制代码
P2 |=(1<<2); //P2的第2位置为1(P2是八位二进制数)

其余位不变,指定位清0:使用按位与t&=~(1<<n)

复制代码
P2 &=~(1<<2); //P2的第2位置置为0(P2是八位二进制数)

^:按位异或:将对应位的bit进行比较,若两个bit相同,结果为0;不相同为1(相同为0,相异为1)

复制代码
P2 = P2 ^ 0xFF;//(P2是八位二进制数)

四、寄存器的概念

寄存器是CPU内部的高速存储单元,容量极小但访问速度最快,能够操作硬件,拥有固定地址的空间。

在单片机中,寄存器分为:

  • 通用寄存器:用于暂存数据和中间结果(如累加器A)。

  • 特殊功能寄存器(SFR):映射到特定地址,用于控制外设(如定时器模式寄存器TMOD)、指示状态(如中断标志)等。程序员通过对SFR的读写来配置单片机功能。

五、数码管动态显示的原理

利用人眼视觉暂留效应(余晖效应) ,依次轮流点亮多位数码管的每一位,并在点亮该位时输出对应的段码。只要刷新频率足够快(通常大于50Hz),人眼就会感觉所有位同时稳定显示,而不是闪烁。优点:节省I/O口线,降低功耗。缺点:需要程序不断扫描,占用CPU时间

六、38译码器工作原理

它有三个输入端(A、B、C,对应二进制编码)和八个输出端(Y0~Y7)

根据输入的三位二进制值(从000到111),只有一个对应的输出端被选通低电平有效

七、流水灯和数码管实验

本篇文章使用

1.普中核心板:

STC宏晶半导体处理器(STC89C52RC)、内核:Intel

PDIP40:芯片封装形式,双列直插40引脚
40个引脚,分为4组:P0-P3
网络编号:相同网络编号的引脚在实际电路中彼此连通主要避免复杂连线

二极管:阳极、阴极

2.安装keil4和STC-ISP烧录软件

网上有教程和资源,不过多赘述(keil4选择atmel:AT89C51

使用逻辑分析仪,通过杜邦线连接引脚CH1-CH8,能观察引脚电平变化(软件:Logic2.4.9)

3.示例1流水灯:

main.c:

复制代码
#include <reg51.h>
#include "led.h"
#include "delay.h"

int main(void)
{	  	int i=0;
   
	while(1)
	{	

    
       for(i=0;i<8 ;i++)
         {
           
            	led_on(1<<i);
            	 delay(0x5fff);
            	 led_all_off();
                 
         }
			 
          for( i=7;i>=0;i--)
         {
            
            	 led_on(1<<i);
            	 delay(0x5fff);
            	 led_all_off();
          
        }
        
       
	}
	return 0;
}

led.c:

复制代码
#include <reg51.h>
#include "led.h"

// led 全亮
void led_all_on(void)
{
	P2 = 0;
}

// led 全灭
void led_all_off(void)
{
	P2 = 0xFF;
}
//指定某个灯亮
void led_on(unsigned char n)
{
	P2 = ~n;
}

void led_nor(void)
{
	P2 = P2 ^ 0xFF;
}
总结:

1.for循环中的led_on(1<<i)非常巧妙,能让参数给到1,2,4,8。

2.delay函数自己根据晶振频率计算(HZ换算成ms)

4.示例2数码管:

seg.c:

复制代码
#include <reg51.h>
#include "seg.h"
#include "delay.h"
unsigned char seg_table[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char display_buf[8]={0};
void bit_select(unsigned char n)
{
    P2 &=~(7<<2);//给p22 p23 p24清零
    switch(n)
    {
        case 1:  //a:0,b:0,c:0
        P2 &=~(1<<2);
        P2 &=~(1<<3);
        P2 &=~(1<<4);
        break;
        case 2:  //a:1,b:0,c:0
        P2 |=(1<<2);
        P2 &=~(1<<3);
        P2 &=~(1<<4);
        break;
        case 3:  //a:0,b:1,c:0
        P2 &=~(1<<2);
        P2 |=(1<<3);
        P2 &=~(1<<4);
        break;
        case 4:  //a:1,b:1,c:0
        P2 |=(1<<2);
        P2 |=(1<<3);
        P2 &=~(1<<4);
        break;
        case 5:  //a:0,b:0,c:1
        P2 &=~(1<<2);
        P2 &=~(1<<3);
        P2 |=(1<<4);
        break;
        case 6:  //a:1,b:0,c:1
        P2 |=(1<<2);
        P2 &=~(1<<3);
        P2 |=(1<<4);
        break;
        case 7:  //a:0,b:1,c:1
        P2 &=~(1<<2);
        P2 |=(1<<3);
        P2 |=(1<<4);
        break;
        case 8:  //a:1,b:1,c:1
        P2 |=(1<<2);
        P2 |=(1<<3);
        P2 |=(1<<4);
        break;
        default:
        break;
    }
}
            
        
void seg_select(unsigned char n)
{    
        P0= seg_table[n];
        
}
    
void num_to_buff(unsigned long n)
{
    int i =0;
    
    for(i = 0;i<8;i++)
    {
        display_buf[i]=0;
    }
    i= 0;
    while(n!=0 && i<8)
    {
        display_buf[i++]= n%10;
        n/=10;
    }
    
}
    
void digiter_show(void) 
{
    static int pos = 1;
    P0 = 0;
    bit_select(pos);
    // 段选
	if (display_buf[pos-1] != 0)
	{
		seg_select(display_buf[pos-1]);
	}
	delay(100);
	pos++;
	if (pos > 8)
	{
		pos = 1;
	}
    
    
    
    
}   

main.c:

复制代码
#include <reg51.h>
#include "delay.h"
#include "seg.h"
int main(void)
{
    	unsigned long i = 0;
 	num_to_buff(1234);


	while (1)
	{
//		digiter_show();	
		for (i = 0; i < 99999999; i++)
		{
			num_to_buff(i);
			digiter_show();
		}
	}
return 0;
}
总结:

1.switch来操作位选(选择第几个数码管亮)

2.用数组存数字(0为0x3F、1为0x06.....)来操作段选

3.显示数字函数要动态扫描,在while(1)中进行for循环遍历每一个位选

相关推荐
技术小黑2 小时前
TensorFlow学习系列07 | 实现咖啡豆识别
人工智能·学习·tensorflow
invicinble2 小时前
学习视频的全域理解
学习
herinspace2 小时前
管家婆iShop如何调整商品成本?
服务器·数据库·学习·电脑·excel
Coovally AI模型快速验证2 小时前
国产小龙虾方案实战:nanobot + 通义千问,钉钉上随时派活
人工智能·深度学习·学习·计算机视觉·3d
亚里随笔3 小时前
OpenClaw-RL:让AI Agent在对话中自主学习进化
人工智能·学习·llm·rl·agentic
嘉琪0013 小时前
Day4 完整学习包(this 指向)——2026 0313
前端·javascript·学习
for_ever_love__3 小时前
Objective-C 学习 单例模式
学习·ios·单例模式·objective-c
WJSKad12353 小时前
Ghost瓶颈轻量化改进YOLOv26双路径特征生成与残差学习协同突破
学习·yolo
张永清-老清3 小时前
每周读书与学习->Jmeter中如何使用Bean Shell脚本(二)Bean Shell的基础语法之变量与数据类型
学习·测试工具·jmeter·压力测试·性能调优·jmeter性能测试·性能分析