裸机:编写的代码直接操作硬件。
一、基本概念
1、CPU,MPU,MCU,GPU,SOC的定义
1)CPU(中央处理器)
计算机的核心运算与控制单元,负责执行系统指令、处理数据,是通用计算的 "大脑"。
2)MPU(微处理器)
集成了 CPU 核心及少量外围电路的微处理器,需搭配外部存储、外设才能工作,常用于早期计算机或简单控制场景。
3)MCU(微控制器)
将 CPU 核心、存储器、I/O 接口等集成在单芯片上的 "微控制器",可独立完成控制任务,广泛用于家电、物联网等嵌入式设备。
4)GPU(图像处理器)
专门处理图形渲染和并行计算的处理器,擅长海量数据的并行运算,也用于 AI 训练、科学计算等场景。
5)SOC(高性能集成芯片)
将 CPU、GPU、存储器、外设接口及专用功能模块(如 AI 加速单元)等高度集成在单芯片上的 "系统级芯片",可实现完整电子系统功能。
2、外设寄存器
外设寄存器是嵌入在芯片外设(如GPIO、UART、定时器等)中的特殊存储单元,用于配置外设功能、读取状态或发送/接收数据。
每个寄存器对应特定功能(如配置引脚方向、设置波特率),通过读写寄存器的值可控制外设工作。
寄存器有固定的地址,CPU通过访问这些地址来操作外设(例如向GPIO的控制寄存器写入值,可设置引脚为输入/输出)。
3、LED实验中常用的寄存器(以8051或STM32为例)
LED实验的核心是控制GPIO引脚输出高低电平,常用寄存器包括:
方向寄存器(如8051的P1口寄存器、STM32的GPIOx_MODER):
配置引脚为输入或输出(例如设置为输出模式才能控制LED亮灭)。
数据寄存器(如8051的P1口数据寄存器、STM32的GPIOx_ODR):
向寄存器写入0或1,控制引脚输出低电平(LED导通)或高电平(LED截止)。
(部分芯片)上拉/下拉寄存器:若LED通过引脚高电平点亮,可能需要配置上拉电阻确保电平稳定。
4、GPIO
GPIO(General Purpose Input/Output,通用输入输出)
GPIO是芯片上的通用引脚,可通过软件配置为输入或输出,实现与外部设备的交互:
输出模式:可输出高低电平,用于控制LED、继电器、电机等。
输入模式:可读取外部信号(如按钮状态、传感器数据)。
灵活性高,是嵌入式开发中最基础、最常用的外设,几乎所有MCU/MPU都包含GPIO模块。
例如:LED实验中,GPIO被配置为输出模式,通过输出高低电平控制LED的亮灭。
5、中断与中断源
1)中断(Interrupt)
当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作。
2)中断源(Interrupt Source)
指能主动向CPU发送"中断请求",暂停当前任务、迫使其优先处理紧急事件的硬件或软件实体。
6、中断处理流程
1)中断源发送中断请求
2)内核检查是否响应中断,以及该中断是否被屏蔽
3)内核会检查中断的中断优先级
4)保护现场
5)执行中断服务函数
6)恢复现场
7、中断嵌套
中断嵌套是高优先级中断打断低优先级中断处理过程的机制,核心是"优先处理更紧急的事件"。51单片机有2个优先级(高优先级、低优先级),可通过IP寄存器设置(如PT0=1设T0为高优先级);
低优先级中断执行时,若有高优先级中断请求,CPU会暂停低优先级中断,先处理高优先级中断;同优先级中断不会嵌套(如两个低优先级中断,先响应的先处理,后请求的需等前一个处理完);高优先级中断执行时,其他中断(无论优先级)都无法打断它。
8、中断向量表
中断向量表是存储"中断源"与"对应中断服务程序入口地址"的表格,本质是CPU的"中断导航图"------当某个中断源触发时,CPU通过查表就能快速找到该中断该去哪里执行处理逻辑。

9、51单片机的定时器工作原理
可编程的 16 位加 1 计数器,先通过程序向定时器寄存器(THx 高 8 位、TLx 低 8 位)写入初始计数值,随后定时器在系统时钟(经 12 分频后)或外部引脚输入脉冲的驱动下开始累加计数,当计数值累加到最大值(如 16 位时为 0xFFFF)并产生溢出时,会自动触发定时器中断请求(若中断使能),同时可选择自动重装初始值(仅模式 2)或需程序重新赋值,以此实现定时(基于内部时钟)或计数(基于外部脉冲)功能。
10、PWM及其重要参数
1)PWM(脉冲宽度调制,Pulse Width Modulation)
是一种利用数字信号(高低低电平脉冲)模拟模拟信号的技术,核心原理是通过周期性地输出高低电平脉冲,通过改变高(或低电平)在一个周期内的占比。
2)PWM的核心参数
占空比、周期与频率、分辨率、幅值。
二、功能实现(应用示例)
1、LED灯:全亮(led_all_on)、全灭(led_all_off)、指定灯亮(led_on)
cs
#include "led.h"
#include <reg52.h>
void led_all_on(void)
{
P2 = 0;
}
void led_all_off(void)
{
P2 = 0xFF;
}
void led_on(unsigned char n)
{
P2 = n;
}
2、数码管显示屏:位选(bit_select)、0~9显示(segment------select)、9999以内数字显示(show_number)
cs
#include "delay.h"
#include "digiter.h"
#include <reg52.h>
//位选
void bit_select(int n)
{
P1 &= ~(0x0F << 0);
P1 |= (1 << n);
}
void segment_select(int n) //0~9
{
unsigned char t[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
P0 = t[n];
delay(400);//保证二极管导通
P0 = 0;//消去残影
delay(100);
}
void show_number(int n)
{
int t = 0;
if(t > 9999)
{
return ;
}
else if(n == 0)
{
bit_select(0);
segment_select(0);
}
while(n)
{
bit_select(t++);
segment_select(n % 10);
n /= 10;
}
}
3、延迟函数:delay
cs
#include "delay.h"
#include <reg52.h>
void delay(unsigned int n) //0~65535
{
while(n--);
}
4、来回显示跑马灯
cs
#include <reg52.h>
#include "led.h"
#include "delay.h"
int main(void)
{
//跑马灯
led_all_off();
P2 = 0xFF;
while(1)
{
int i = 0;
for(i = 0; i < 8; i++)
{
led_on(1 << i);
delay(9000);
}
for(i = 6; i >= 0; --i)
{
led_on(1 << i);
delay(9000);
}
}
}
5、数码管显示:重复显示0~9
cs
#include <reg52.h>
#include "led.h"
#include "digiter.h"
#include "delay.h"
int main(void)
{
int i = 0;
bit_select(2);
while(1)
{
segment_select(i++);
if(i > 9)
{
i = 0;
}
delay(20000);
}
}
6、按键:初始化按键(init_key)、按键选择(key_pressed)
cs
#include <reg52.h>
#include "digiter.h"
#include "key.h"
#include "delay.h"
void init_key(void)
{
P1 |= (0x0F << 4);//0000 1111
P3 |= (0x0F << 4);
}
int key_pressed(void)
{
int ret = 0;
if((P1 & (1 << 4)) == 0)
{
ret = 1;
}
else if((P1 & (1 << 5)) == 0)
{
ret = 2;
}
else if((P1 & (1 << 6)) == 0)
{
ret = 3;
}
else if((P1 & (1 << 7)) == 0)
{
ret = 4;
}
else if((P3 & (1 << 5)) == 0)
{
ret = 5;
}
return ret;
}
int main(void)
{
init_key();
P2 = 0xFF;
while(1)
{
int key;
key = key_pressed();
if(key != 0)
{
P2 = 0;//亮灯
}
delay(0x9000);
}
return 0;
}
7、外部中断:外部中断0---加、外部中断0---减
cs
#include <reg52.h>
#include "delay.h"
#include "digiter.h"
void init_eint0(void)
{
IE |= (1 << 7) | (1 << 0) | (1 << 2);
TCON |= (1 << 2);
TCON &= ~(1 << 0);//enit0 low
P3 |= (1 << 2) | (1 << 3);
}
int num = 0;
void enit0_handle(void) interrupt 0
{
++num;
if(num > 9999)
{
num = 0;
}
}
void enit1_handle(void) interrupt 2
{
--num;
if(num < 0)
{
num = 9999;
}
}
int main(void)
{
init_eint0();
P2 = 0xFF;
while(1)
{
show_number(num);
}
}
8、定时器:实现类似电子琴的效果
cs
#include <reg52.h>
#include "key.h"
#define Hz200 63035
#define Hz400 64285
#define Hz600 64702
#define Hz800 64910
#define Hz1000 65035
unsigned short n = Hz200;
void init_timer0(void)
{
TMOD &= ~(3 << 2);
TMOD &= ~(3 << 0);
TMOD |= (1 << 0);
TH0 = n >> 8;
TL0 = n;
IE |= (1 << 7) | (1 << 1);
}
void timer0_handler(void) interrupt 1
{
P2 ^= (1 << 1);
TH0 = n >> 8;
TL0 = n;
}
int main(void)
{
init_timer0();
init_key();
while(1)
{
int key;
key = key_pressed();
if(key == 1)
{
n = Hz200;
TCON |= (1 << 4);
}
else if(key == 2)
{
n = Hz400;
TCON |= (1 << 4);
}
else if(key == 3)
{
n = Hz600;
TCON |= (1 << 4);
}
else if(key == 4)
{
n = Hz800;
TCON |= (1 << 4);
}
else if(key == 5)
{
n = Hz1000;
TCON |= (1 << 4);
}
else if(key == 0)
{
TCON &= ~(1 << 4);
}
}
return 0;
}
【END】