找回密码
 立即注册
查看: 2209|回复: 15

PWM输入捕获请教

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-01 12:26:51
已绑定手机

17

主题

81

回帖

382

积分

中级会员

积分
382
发表于 2025-1-9 14:57:46 | 显示全部楼层 |阅读模式
STC8单片机的PWM输入捕获的原理是这样吗:
CNT的计数频率和时钟源频率是一样的(不分频的情况下),检测到上升沿或者下降沿就把CNT的值装载到CCR里面,然后保存CCR的值,用时钟频率÷新的CCR减去旧的CCR再就是信号频率
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2025-1-9 15:11:34 | 显示全部楼层
  1. void PWMA_Isr(void) interrupt PWMA_VECTOR
  2. {
  3.         if(PWMA_SR1&0x02)
  4.         {
  5.                 PWMA_SR1&=~0x02;
  6.                 Cap[0]=Cap[1];
  7.                 Cap[1]=(PWMA_CCR1H<<8)|PWMA_CCR1L;
  8.                 Cap[2]=Cap[1]-Cap[0];
  9.                 Flag=1;
  10.         }
  11. }
复制代码
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=12187&pid=124999


CCR的差乘以时钟频率的倒数是信号的周期,周期的倒数是频率
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-01 12:26:51
已绑定手机

17

主题

81

回帖

382

积分

中级会员

积分
382
发表于 2025-1-9 15:29:42 | 显示全部楼层
Debu*** 发表于 2025-1-9 15:11
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=12187&pid=124999

为什么我测低频他一直跳

点评

被测信号频率多少?是否稳定?可以使用晶振做时钟发出频率来测试。  详情 回复 发表于 2025-1-10 14:23
发原理图和程序  详情 回复 发表于 2025-1-9 17:00
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2025-1-9 17:00:33 | 显示全部楼层
Crysta*** 发表于 2025-1-9 15:29
为什么我测低频他一直跳

发原理图和程序
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-01 12:26:51
已绑定手机

17

主题

81

回帖

382

积分

中级会员

积分
382
发表于 2025-1-10 11:50:56 | 显示全部楼层
Debu*** 发表于 2025-1-9 17:00
发原理图和程序
  1. #include <STC8H.H>
  2. #include <Seg.h>
  3. uchar Seg_Buf[] = {10,10,10};
  4. uchar pos = 0;
  5. uint Seg_Slow_Down = 0;
  6. uint Time_1000ms = 0;
  7. uint Freq = 0;
  8. uchar Time1ms = 0;
  9. uchar led_light = 2;
  10. uchar take_time = 0;   //保存进入中断的次数
  11. #define FILTER_SIZE 10
  12. int filter_buffer[FILTER_SIZE];  // 存储最新的10个频率值
  13. int filter_index = 0;            // 用于指示当前存储位置
  14. int filtered_freq = 0;           // 存储滤波后的频率值
  15. typedef struct {
  16.         int cap;
  17.         int cap_new;
  18.         int cap_old;
  19. }Freq_Type;
  20. Freq_Type Freq1;
  21. Freq_Type Freq2;
  22. Freq_Type Freq3;
  23. void Timer1_Isr(void) interrupt 3
  24. {
  25.         if(++Seg_Slow_Down == 2000) Seg_Slow_Down = 0;
  26.         if(++Time1ms == 10){
  27.                 Time1ms = 0;
  28.                 if(++pos ==3) pos = 0;
  29.         }
  30.         if(Time1ms <= led_light)  //亮
  31.         {
  32.                 Seg_Disp(pos,Seg_Buf[pos]);
  33.         }
  34.         else
  35.                 Seg_Disp(pos,10);  //灭
  36. }
  37. void Timer1_Init(void)                //100微秒@12.000MHz
  38. {
  39.         AUXR &= 0xBF;                        //定时器时钟12T模式
  40.         TMOD &= 0x0F;                        //设置定时器模式
  41.         TL1 = 0x9C;                                //设置定时初始值
  42.         TH1 = 0xFF;                                //设置定时初始值
  43.         TF1 = 0;                                //清除TF1标志
  44.         TR1 = 1;                                //定时器1开始计时
  45.         ET1 = 1;                                //使能定时器1中断
  46. }
  47. void System_Init()
  48. {
  49.         P_SW2 |= 0x80; //扩展外部XFR
  50.         PWMB_PS = 0x54; //01 01 01 00 选用P54\P33\P34作为输入捕获引脚
  51.         PWMB_PSCRH = 0x2E; //预分频寄存器
  52.         PWMB_PSCRL = 0xDF;
  53.         /*必须先关闭CCER才能设置CC1*/
  54.         PWMB_CCER1 = 0x00;PWMB_CCER2 = 0x00 ;
  55.         PWMB_CCMR2 = 0x01;PWMB_CCMR3 = 0x01;        PWMB_CCMR4 = 0x01;                       //通道6、7、8设为输入
  56.         //PWMB_CCMR2 |= 0xC0; PWMB_CCMR3 |= 0xC0; PWMB_CCMR4 |= 0xC0;  //8个事件触发一次
  57.         PWMB_CCER1 = 0x10; PWMB_CCER2 = 0x11; //使能通道6、7、8
  58.         PWMB_IER = 0x1C;
  59.         PWMB_CR1 |= 0x01; //使能计数器
  60.         IP |= 0x0f; //拉低定时器1的优先级
  61.         P1M0 = 0xff; P1M1 = 0x00;
  62.         P5M0 = 0x00; P5M1 = 0x00;
  63.   P3M0 = 0xe0; P3M1 = 0x00;
  64.        
  65.         Timer1_Init();
  66.         EA = 1;
  67. }
  68. void Seg_Proc()
  69. {
  70.         if(Seg_Slow_Down) return;
  71.         Seg_Slow_Down = 1;
  72.         //Freq = Freq1.cap + Freq2.cap + Freq3.cap;
  73. //        if(Freq <= 999){
  74. //                Seg_Buf[0] = (Freq/100)?Freq/100:10;
  75. //                Seg_Buf[1] = (Freq/10)?Freq/10%10:10;
  76. //                Seg_Buf[2] = Freq%10;       
  77. //        }
  78. //        else
  79. //                Seg_Buf[0] = Seg_Buf[1] = Seg_Buf[2] = 9;
  80.        
  81.         filtered_freq = 1000 / filtered_freq;
  82.   Seg_Buf[0] = (filtered_freq/100)?filtered_freq/100:10;
  83.         Seg_Buf[1] = (filtered_freq/10)?filtered_freq/10%10:10;
  84.         Seg_Buf[2] = filtered_freq%10;       
  85.        
  86. }
  87. void main()
  88. {
  89.         System_Init();
  90.         while(1)
  91.         {
  92.                 Seg_Proc();
  93.         }
  94. }
  95. void PWMB_ISR() interrupt 27
  96. {
  97.         long sum;
  98.         uchar i;
  99.         if(PWMB_SR1 & 0x04) //是CC6的中断
  100.         {
  101.                 Freq1.cap_old = Freq1.cap_new;
  102.                 Freq1.cap_new = PWMB_CCR6;
  103.                 Freq1.cap = Freq1.cap_new - Freq1.cap_old;       
  104.                
  105.                 filter_buffer[filter_index] = (Freq1.cap >= 0) ? Freq1.cap : -Freq1.cap;
  106.                 filter_index = (filter_index + 1) % FILTER_SIZE;
  107.                 for(i = 0;i<FILTER_SIZE;i++)
  108.                         sum += filter_buffer[i];
  109.                 filtered_freq = sum / FILTER_SIZE;
  110.                
  111.                 PWMB_SR1 &= ~0x04;
  112.                
  113.         }
  114. //        if(PWMB_SR1 & 0x08) //是CC7的中断
  115. //        {
  116. //                Freq2.cap_old = Freq2.cap_new;
  117. //                Freq2.cap_new = PWMB_CCR7;
  118. //                Freq2.cap = Freq2.cap_new - Freq2.cap_old;
  119. //                PWMB_SR1 &= ~0x08;               
  120. //        }
  121. //        if(PWMB_SR1 & 0x10) //是CC8的中断
  122. //        {
  123. //                Freq3.cap_old = Freq3.cap_new;
  124. //                Freq3.cap_new = PWMB_CCR8;
  125. //                Freq3.cap = Freq3.cap_new - Freq3.cap_old;
  126. //                PWMB_SR1 &= ~0x10;               
  127. //        }
  128. }
复制代码


点评

被测信号频率范围是多少 被测信号周期不能大于PWM计数器溢出时间,溢出前后被测信号处于同一个周期,结果就会乱跳  详情 回复 发表于 2025-1-10 12:50
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-01 07:10:25
已绑定手机

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2025-1-10 12:50:57 | 显示全部楼层

被测信号频率范围是多少
被测信号周期不能大于PWM计数器溢出时间,溢出前后被测信号处于同一个周期,结果就会乱跳
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2025-1-10 14:23:58 | 显示全部楼层
Crysta*** 发表于 2025-1-9 15:29
为什么我测低频他一直跳

被测信号频率多少?是否稳定?可以使用晶振做时钟发出频率来测试。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-01 12:26:51
已绑定手机

17

主题

81

回帖

382

积分

中级会员

积分
382
发表于 2025-1-10 14:42:24 | 显示全部楼层
梁*** 发表于 2025-1-10 14:23
被测信号频率多少?是否稳定?可以使用晶振做时钟发出频率来测试。

这样的
截图202501101441291996.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:173
  • 最近打卡:2025-05-01 12:26:51
已绑定手机

17

主题

81

回帖

382

积分

中级会员

积分
382
发表于 2025-1-10 14:48:23 | 显示全部楼层
我还有个疑问就是PWMB_CNTR和PWMB_CCR1不是16位的吗为什么要用int类型?int类型不是-32768-32767吗,要是计数值达到了32767以上,那这里面的捕获值不是有问题了吗
截图202501101448169298.jpg

点评

应该用unsigned int型  详情 回复 发表于 2025-1-10 16:56
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2025-1-10 16:56:37 | 显示全部楼层
Crysta*** 发表于 2025-1-10 14:48
我还有个疑问就是PWMB_CNTR和PWMB_CCR1不是16位的吗为什么要用int类型?int类型不是-32768-32767吗,要是计 ...

应该用unsigned int型,已通知修改手册。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:35 , Processed in 0.216414 second(s), 114 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表