第二天的内容核心是GPIO、中断、定时器和PWM,都是后续实操的基础,把重点捋一遍。
GPIO
通用输入输出接口,单片机和外部交互最基础的方式。
输入模式用来检测引脚电平变化,比如按键、ADC信号,细分有上拉输入、下拉输入、浮空输入、模拟输入。
输出模式包括推挽输出、开漏输出,还有对应的复用模式。
中断
简单说就是CPU跑程序的时候,外部有更紧急的事件过来,先暂停当前任务,去处理紧急事件,处理完再回来接着跑。
51单片机一共有5个中断源:
外部中断0(对应P3.2引脚)
外部中断1(对应P3.3引脚)
定时器0
定时器1
串口
中断有优先级,高优先级可以打断低优先级的中断服务,也就是中断嵌套,最多支持两层嵌套。
完整的中断处理流程:
-
中断源发起中断请求
-
CPU检查中断总开关和对应中断源的子开关是否开启
-
比较多个中断的优先级
-
保护当前程序现场
-
执行对应的中断服务函数
-
恢复现场,回到原程序继续执行
外部中断0的初始化示例:
void int0_init(void) {
IE |= (1 << 7); // 打开中断总开关
IE |= (1 << 0); // 打开外部中断0的开关
}
中断向量可以理解成中断的编号,CPU靠这个编号找到对应的中断服务函数。
定时器
用来实现精准的定时和延时,是16位的自增计数器,计数满溢出后就会向CPU发起中断请求。
51单片机用12MHz晶振时,经过12分频,实际计数频率是1MHz,也就是每1微秒计数器加1。
最常用的1ms定时初值计算:
1ms需要计数1000次,16位计数器最大值是65535,所以初值 = 65535 - 1000 = 64535。
寄存器配置:
TL0 = 64535; // 定时器0低8位
TH0 = 64535 >> 8; // 定时器0高8位
PWM与蜂鸣器
PWM即脉冲宽度调制,让引脚周期性输出高低电平,形成方波。两个核心参数:
周期:一个完整方波的时间长度
占空比:一个周期内高电平所占的比例
常用在背光调节、蜂鸣器音调控制这类场景。
蜂鸣器分两类:
有源蜂鸣器:内部自带震荡源,通电就发出固定频率的声音
无源蜂鸣器:需要外部输入震荡信号才会响,配合定时器PWM可以控制音调
用定时器驱动无源蜂鸣器的计算示例:
200Hz、50%占空比:半周期2.5ms,计数2500次,初值=65535-2500=63035
400Hz、50%占空比:半周期1.25ms,计数1250次,初值=65535-1250=64285
一点补充
按键的原理就是按下时引脚接地变成低电平,配合中断就能实现按键触发功能。像车载中控里测水温、油温这些功能,本质上都是ADC采集、定时器扫描、中断响应组合起来实现的。