#C51中断定时(PWM输出+外部中断频率检测)
2022-09-15 来源:csdn
前言
C51单片机自身无PWM输出,可以借用T1定时中断输出一定频率的脉冲信号,且占空比可调,便于继续开发
提示:以下是本篇文章正文内容,下面案例可供参考
一、场景
样例1:P3引脚输出固定频率PWM信号,占空比人为调整
样例2:PWM+外部中断检测频率验证
步步进阶
二、PWM简介
PWM(Pulse Width Modulation)脉冲宽度调制,是一种对模拟信号电平进行数字编码的方法。
占空比:高电平占周期的比例,如f=1Hz,T=1s,T1=0.5s,占空比即为50%
为什么这么说呢?
1.pwm本身就是一个方波信号,1和0对应数字电路中高电平、低电平。
2.思考下:负载两端(如LED、直流电机等)直流供电,高电平时ON,低电平时OFF。
3.若是将PWM信号输出至负载两端(如1Hz/5V,占空比50%)~~==~~理论上0.5s全部导通,0.5s全部关闭。此时,负载两端的等效电压约2.5V(5V*50%)工作时状态。电路中电流发生变化,器件工作状态受到影响。
简言之,在合适的频率信号下,通过调整PWM占空比,可以改变输出电压的有效值
三、编程实现
样例1:PWM+占空比软件调整
1.设计思路:
设计f = 10Hz的PWM信号,T = 100ms。
将T分割成100份,每份1ms
2.代码设计
1.T1定时初始化
void Timer1Init(void) //1ms @11.0592MHz
{
TMOD &= 0x0F; //设置定时模式 GATE C/T^ M1 M0 // 0 0 0 1
TMOD |= 0x10; //设置定时模式 T1 方式1 16位定时器
TH1 = (65536 - 1000) / 256; //初值
TL1 = (65536 - 1000) % 256;
TF1 = 0; //清除TF1标志
ET1 = 1;//打开定时器T1
TR1 = 1; //定时器1开始计时
}
2.T1中断服务函数
//2.PWM输出处理
TR1 = 0;
vPWMCnt++;
if(vPWMCnt <= PWM_DUTY)
{
PWM = 1;
}
else if(vPWMCnt <= 100)
{
PWM = 0;
}
else
{
vPWMCnt = 0;
}
TH1 = (65536 - 1000) % 256; //重装初值
TL1 = (65536 - 1000) / 256;
TR1 = 1;
3.调试验证
P3.0输出PWM,周期比时钟源输出的要大一点
改变占空比,波形改变
#define PWM_DUTY 20 //占空比
样例2:PWM+外部中断检测频率
1.设计思路:
P3.0输出PWM信号
外部中断INT0+T0结合检测频率
数码管显示频率数值
2.代码设计
1.外部中断INT0初始化
void EX0Init(void)
{
IT0 = 1; //外部中断0触发方式 0:电平触发(低电平有效)1:边沿触发(高->低负跳变)
EX0 = 1; //允许外部中断0中断
}
2.外部中断INT0中断服务函数
void Ex0_ISR() interrupt 0
{
//2.外部中断计数方案
EX0 = 0;
vFreqCnt_Ex0++;
EX0 = 1;
}
3.T0定时中断服务函数(1ms)
void Timer0_ISR() interrupt 1
{
UI vFreqCnt;
vFreqCnt++;
if(vFreqCnt > 1000)
{
vFreqCnt = 0;
EX0 = 0;
gFreqCnt = vFreqCnt_Ex0;
vFreqCnt_Ex0 = 0;
EX0 = 1;
}
}
4.频率显示处理
NumDisSpare(gFreqCnt);
void NumDisSpare(unsigned int vDisNum)
{
if(vDisNum >= 1000)
{
SEG_DisBuf[0] = vDisNum / 1000;
}
else
{
SEG_DisBuf[0] = 23;
}
if(vDisNum >= 100)
{
SEG_DisBuf[1] = vDisNum / 100 % 10;
}
else
{
SEG_DisBuf[1] = 23;
}
if(vDisNum >= 10)
{
SEG_DisBuf[2] = vDisNum / 10 % 10;
}
else
{
SEG_DisBuf[2] = 23;
}
SEG_DisBuf[3] = vDisNum % 10;
}
3.调试验证
1.利用上篇简单频率测试方式,进行检测并显示
总结
1.原计划一篇讲完再利用PWM实现LED呼吸灯功能,篇幅过长,下篇继续。
2.仿真环境下与实际的的确有偏差,proteus下输出PWM方波,周期偏差3ms左右。实际电路板示波器观测没有这么大偏差。晶振已经排查,具体原因再研究研究。