高级16位PWM,输入捕获测量低频率信号,可低至0.014Hz,8H/STC32G/AI8051U 通用
使用高级16位PWM的输入捕获功能,大家可能会发现,高频率的捕获没有问题,但如果捕获的信号频率较低,两次捕获之间超过了内部计数器的长度,此时的捕获就会失败。版本,经过实际测试,可以正常捕获1Hz~50Khz之间的信号(再低的没有测,并非不支持,理论上可以捕获低至0.014Hz的信号,仅受限于重复计数变量的大小)程序框架通过AiCube生成,在程序main函数的43行,可以通过取消注释代码,来屏蔽T
高级16位PWM, 输入捕获测量低频率信号, 可低至0.014Hz,8H/STC32G/AI8051U 通用
使用高级16位PWM的输入捕获功能,大家可能会发现,高频率的捕获没有问题,但如果捕获的信号频率较低,两次捕获之间超过了内部计数器的长度,此时的捕获就会失败。
所以,这里给出一个使用Ai8051U实验箱V1.2测试通过的软件版本,经过实际测试,可以正常捕获1Hz~50Khz之间的信号(再低的没有测,并非不支持,理论上可以捕获低至0.014Hz的信号,仅受限于重复计数变量的大小)
程序使用40Mhz主频,通过PLL倍频到120Mhz,其他如AI8和AI32单片机,拥有同样的高级PWM部分可以一样移植参考,程序是通用的
本程序主要使用了PWM的更新中断(计数器设置为向上计数,上溢时触发更新中断)
程序默认通过T0中断改变P00口,输出250Hz的信号,这里通过计算器计算可以看到,实际捕获值为249.98Hz,占空比默认为50%
程序框架通过AiCube生成,在程序main函数的43行,可以通过取消注释代码,来屏蔽T0的方波输出,从而使用外部信号输入给P00来进行测量
以下是核心代码部分:
- void PWMA_ISR() interrupt 26
- {
- char _pwma_sr1;
- _pwma_sr1 = ReadPWMA((char)&PWMA_SR1);
- if(_pwma_sr1 & 0x01)//更新中断
- {
- if(cnt != 0)cnt++;
- }
- if (_pwma_sr1 & 0x02)//CC1捕获,上升沿
- {
- cc1 = ReadPWMA((char)&PWMA_CCR1H);//先读高字节,此时会锁定低字节
- cc1<<=8;
- cc1 += ReadPWMA((char)&PWMA_CCR1L);
- if(cnt>1)//分为重复触发和未重复触发
- {
- cnt -= 2;
- if(cnt<0)cnt = 0;
- low_time = (65536L-cc2)+(65536L*cnt)+(cc1);
- }else
- {
- low_time = cc1 - cc2;
- }
- cnt = 1;
- // CC1 捕获周期宽度
- }
- if (_pwma_sr1 & 0x04)//CC2捕获,下降沿
- {
- cc2 = ReadPWMA((char)&PWMA_CCR2H);
- cc2<<=8;
- cc2 += ReadPWMA((char)&PWMA_CCR2L);
- if(cnt>1)
- {
- cnt -= 2;
- if(cnt<0)cnt = 0;
- high_time = (65536L-cc1)+(65536L*cnt)+(cc2);
- }else
- {
- high_time = cc2-cc1;
- }
- cnt = 1;
- // CC2 捕获占空比(高电平宽度)
- }
- WritePWMA((char)&PWMA_SR1, 0x00);//清空PWMA_SR1寄存器
- }
更多推荐
所有评论(0)