找回密码
 立即注册
查看: 76|回复: 2

AI8H4K64TL在做捕获方波周期时,发现数码管显示会突跳,频率越低越厉害 | 已解决

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:258
  • 最近打卡:2025-05-01 13:09:51
已绑定手机

17

主题

122

回帖

1307

积分

金牌会员

STC-镇江-老蔡

积分
1307
发表于 2025-4-20 22:00:50 | 显示全部楼层 |阅读模式
各位大佬:

      本人在用AI8H4K64TL单片机在做捕获方波周期时,发现数码管显示会突跳,频率越低越厉害
      请有时间的大佬给予些指点。
      系统时钟20MHZ;
      

      谢谢!
  1. //包含头文件
  2. #include "all.h"
  3. ulong cap;
  4. ulong cap_new;
  5. ulong cap_old;
  6. unsigned long num = 0;
  7. //数码管显示函数
  8. void Display()
  9. {
  10.         SMG_Write_Buffer[0] = SEG_DISPLAY[num/10000];//赋值给每一位寄存器;
  11.         SMG_Write_Buffer[1] = SEG_DISPLAY[num%10000/1000];
  12.         SMG_Write_Buffer[2] = SEG_DISPLAY[num%1000/100];
  13.         SMG_Write_Buffer[3] = SEG_DISPLAY[num%100/10];
  14.         SMG_Write_Buffer[4] = SEG_DISPLAY[num%10];
  15.         DISPLAY_SER();
  16. }
  17. //PWMA初始化程序
  18. void PWMA_INIT()
  19. {
  20.         PWMA_PS = 0x00;
  21.         PWMA_PSCR = 0x13;        //设置预分频器的值为50
  22.         PWMA_CCER1 = 0x00;        //先清零后写入
  23.         PWMA_CCMR1 = 0x01;        //(CC1连续捕获TI1上升沿)
  24.         PWMA_CCER1 = 0x01;        //CC1为输入模式,且映射到TI1FP1上
  25.         PWMA_IER = 0x02;        //使能PWMA中断
  26.         PWMA_CR1 |= 0x01;        //使能PWMA捕获
  27. }
  28. // 定义数组存储数据
  29. #define accumulative_frequency 20
  30. unsigned int calculate_average() {
  31.     unsigned long sum = 0;
  32.         unsigned int i;
  33.     // 累加数组中的所有数据
  34.     for (i = 0; i < accumulative_frequency; i++) {
  35.         sum += cap;
  36.     }
  37.         num = (unsigned int)(sum / accumulative_frequency);
  38.         return num;
  39. }   
  40. //主程序
  41. void main()
  42. {
  43.         P_SW2 |= 0x80;        //允许访问特殊功能寄存器XFR;
  44.         P0M0 |= 0x0f;
  45.         P0M1 &= ~0x0f;
  46.         P1M0 &= ~0x3b;
  47.         P1M1 &= ~0x3b;
  48.         P2M0 = 0x1f;
  49.         P2M1 = 0x1f;
  50.         P3M0 = 0xf0;
  51.         P3M1 = 0x00;
  52.         P3DR &= ~0xf0;
  53.         P0DR &= ~0x0f;
  54.         P2DR &= ~0x1f;
  55.         XOSCCR = 0xc0;                              //启动外部晶振
  56.     while (!(XOSCCR & 1));                      //等待时钟稳定
  57.     CLKDIV = 0x00;                              //时钟不分频
  58.     CLKSEL = 0x01;                              //选择外部晶振
  59.         PWMA_INIT();
  60.         EA = 1;                   //开总中断
  61.         while(1)
  62.         {
  63.                 calculate_average();
  64.                 Display();
  65.         }
  66. }
  67. void PWMA_ISR() interrupt 26        //PWMA中断服务程序
  68. {
  69.         if(PWMA_SR1 & 0x02)
  70.         {        
  71.                 cap_old = cap_new;
  72.                 cap_new = PWMA_CCR1;
  73.                 cap = cap_new - cap_old;
  74.                 PWMA_SR1 &= ~0x02;        //清除中断标志位
  75.         }
  76. }
  77.         
复制代码
  1. #include "stc8h.h"      //包含stc8h.h文件
  2. #include "intrins.h"    //包含intrins.h文件
  3. typedef unsigned int uint;      //定义uint类型
  4. typedef unsigned char uchar;        //定义uchar类型   
  5. typedef unsigned long ulong;    //定义ulong类型
  6. #include "Dis_Play.h"   //包含Dis_Play.h文件
复制代码
  1. #include "all.h"
  2. uchar data SMG_Write_Buffer[5];//用于给数码管各个位赋值之用
  3.                                                //0,   1,        2,   3,          4,   5,        6,   7,   8,   9,   A,   B,   C,   D,   E   F,   -,    空,  ℃,  ℉
  4. uchar code SEG_DISPLAY[20] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0xB9,0x71,0x40,0x00,0x79,0xF1};
  5. // 主函数
  6. void DISPLAY_SER()         //显示服务函数;
  7. {
  8.         //P_SW2 |= 0x80;        //允许访问特殊功能寄存器XFR;
  9.         COMEN = 0x1f;                //打开低位的5个COM口;
  10.         SEGENL = 0x00;        //不使能低8位SEG口;
  11.         SEGENH = 0xff;        //使能高8位SEG口;
  12.         LEDCTRL = 0x80; //设置打开LED驱动,使用共阴模式,亮度100%;
  13.         LEDCKS = 0x2a;                //调整刷新频率;
  14.         COM0_DC_H = SMG_Write_Buffer[0];//赋值给每一位寄存器;
  15.         COM1_DC_H = SMG_Write_Buffer[1];
  16.         COM2_DC_H = SMG_Write_Buffer[2];
  17.         COM3_DC_H = SMG_Write_Buffer[3];
  18.         COM4_DC_H = SMG_Write_Buffer[4];
  19.         LEDCTRL |= 0x80;        //启动LED驱动;
  20. }
复制代码


IMG20250420215853.jpg
平安快乐
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-20 22:03:00 | 显示全部楼层
在使用STC8H4K64TL单片机进行方波周期捕获时,数码管显示出现突跳现象,尤其是在频率较低时更为明显。这种现象可能由多种因素引起,以下是一些可能的原因及相应的解决方案。

1. 捕获中断处理不当
在捕获方波周期时,如果中断处理程序没有正确计算周期时间,或者中断响应时间过长,可能导致显示数据不准确。建议检查以下几点:
中断优先级:确保捕获中断的优先级足够高,以避免被其他中断打断。
中断处理程序:在中断处理程序中,尽量减少不必要的计算和操作,确保快速响应并更新周期数据。

2. 数码管刷新频率与捕获频率不匹配
数码管的刷新频率如果与捕获频率不匹配,可能导致显示数据出现突跳。建议:
调整数码管刷新频率:确保数码管的刷新频率足够高,以避免显示数据滞后或突跳。
使用双缓冲机制:在更新数码管显示时,使用双缓冲机制,避免在显示过程中直接修改显示数据。

3. 系统时钟配置
系统时钟的配置可能影响捕获精度和数码管显示的稳定性。建议:
检查系统时钟:确保系统时钟配置正确,且时钟源稳定。
调整预分频器:根据实际需求,调整捕获模块的预分频器,以确保捕获精度。

4. 捕获模块配置
捕获模块的配置不当可能导致捕获数据不准确。建议:
检查捕获模式:确保捕获模式配置正确,例如上升沿捕获或下降沿捕获。
检查捕获寄存器:确保捕获寄存器的值在每次捕获后正确更新,并避免溢出。

5. 软件滤波
在捕获低频信号时,噪声和干扰可能导致显示数据突跳。建议:
增加软件滤波:在捕获数据后,增加简单的软件滤波算法,例如移动平均滤波,以平滑显示数据。

6. 硬件设计
硬件设计中的问题也可能导致显示数据突跳。建议:
检查电路设计:确保电路设计合理,避免信号干扰和噪声。
增加硬件滤波:在信号输入端口增加硬件滤波电路,例如RC滤波,以减少噪声干扰。

代码优化建议
根据提供的代码,以下是一些优化建议:
  1. c
  2. // 包含头文件
  3. include "allh"
  4. ulong cap;
  5. ulong capnew;
  6. ulong capold;
  7. unsigned long num = 0;
  8. // 数码管显示函数
  9. void Display()
  10. {
  11.     SMGWriteBuffer[0] = SEGDISPLAY[num / 10000]; // 赋值给每一位寄存器
  12.     SMGWriteBuffer[1] = SEGDISPLAY[num % 10000 / 1000];
  13.     SMGWriteBuffer[2] = SEGDISPLAY[num % 1000 / 100];
  14.     SMGWriteBuffer[3] = SEGDISPLAY[num % 100 / 10];
  15.     SMGWriteBuffer[4] = SEGDISPLAY[num % 10];
  16.     DISPLAYSER();
  17. }
  18. // PWMA初始化程序
  19. void PWMAINIT()
  20. {
  21.     PWMAPS = 0x00;
  22.     PWMAPSCR = 0x13; // 设置预分频器的值为50
  23.     PWMACCER1 = 0x00; // 先清零后写入
  24.     PWMACCMR1 = 0x01; // (CC1连续捕获TI1上升沿)
  25.     PWMACCER1 = 0x01; // CC1为输入模式,且映射到TI1FP1上
  26.     PWMAIER = 0x02; // 使能PWM
  27. }
  28. // 捕获中断处理程序
  29. void PWMAIRQHandler() interrupt PWMAVECTOR
  30. {
  31.     if (PWMASR1 & 0x02) // 检查捕获中断标志
  32.     {
  33.         capnew = PWMACCR1; // 获取捕获值
  34.         if (capnew > capold)
  35.         {
  36.             cap = capnew - capold; // 计算周期
  37.         }
  38.         else
  39.         {
  40.             cap = (0xFFFF - capold) + capnew; // 处理溢出情况
  41.         }
  42.         capold = capnew; // 更新旧值
  43.         num = cap; // 更新显示值
  44.         PWMASR1 &= ~0x02; // 清除中断标志
  45.     }
  46. }
  47. // 主函数
  48. void main()
  49. {
  50.     PWMAINIT(); // 初始化PWMA
  51.     EA = 1; // 使能全局中断
  52.     while (1)
  53.     {
  54.         Display(); // 显示数据
  55.     }
  56. }
复制代码

总结
通过优化中断处理程序、调整数码管刷新频率、检查系统时钟和捕获模块配置,以及增加软件滤波和硬件滤波,可以有效减少数码管显示突跳的现象。希望以上建议能帮助您解决问题。如果问题仍然存在,建议进一步调试和排查硬件设计中的潜在问题。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:258
  • 最近打卡:2025-05-01 13:09:51
已绑定手机

17

主题

122

回帖

1307

积分

金牌会员

STC-镇江-老蔡

积分
1307
发表于 2025-4-21 07:56:09 | 显示全部楼层
国芯人*** 发表于 2025-4-20 22:03
在使用STC8H4K64TL单片机进行方波周期捕获时,数码管显示出现突跳现象,尤其是在频率较低时更为明显。这种 ...

大佬你真厉害!已经解决了,无比感谢!
平安快乐
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-1 22:12 , Processed in 0.120566 second(s), 61 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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