一、基本概念:
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循环遍历每一个位选
