金南京 发表于 2025-4-20 22:00:50

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

各位大佬:

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

      谢谢!
//包含头文件
#include "all.h"

ulong cap;
ulong cap_new;
ulong cap_old;
unsigned long num = 0;
//数码管显示函数
void Display()
{
      SMG_Write_Buffer = SEG_DISPLAY;//赋值给每一位寄存器;
      SMG_Write_Buffer = SEG_DISPLAY;
      SMG_Write_Buffer = SEG_DISPLAY;
      SMG_Write_Buffer = SEG_DISPLAY;
      SMG_Write_Buffer = SEG_DISPLAY;
      DISPLAY_SER();
}
//PWMA初始化程序
void PWMA_INIT()
{
      PWMA_PS = 0x00;
      PWMA_PSCR = 0x13;      //设置预分频器的值为50
      PWMA_CCER1 = 0x00;      //先清零后写入
      PWMA_CCMR1 = 0x01;      //(CC1连续捕获TI1上升沿)
      PWMA_CCER1 = 0x01;      //CC1为输入模式,且映射到TI1FP1上
      PWMA_IER = 0x02;      //使能PWMA中断
      PWMA_CR1 |= 0x01;      //使能PWMA捕获

}
// 定义数组存储数据
#define accumulative_frequency 20
unsigned int calculate_average() {
    unsigned long sum = 0;
      unsigned int i;

    // 累加数组中的所有数据
    for (i = 0; i < accumulative_frequency; i++) {
      sum += cap;
    }
      num = (unsigned int)(sum / accumulative_frequency);
      return num;
}   
//主程序
void main()
{
      P_SW2 |= 0x80;      //允许访问特殊功能寄存器XFR;
      P0M0 |= 0x0f;
      P0M1 &= ~0x0f;
      P1M0 &= ~0x3b;
      P1M1 &= ~0x3b;
      P2M0 = 0x1f;
      P2M1 = 0x1f;
      P3M0 = 0xf0;
      P3M1 = 0x00;
      P3DR &= ~0xf0;
      P0DR &= ~0x0f;
      P2DR &= ~0x1f;
      XOSCCR = 0xc0;                              //启动外部晶振
    while (!(XOSCCR & 1));                      //等待时钟稳定
    CLKDIV = 0x00;                              //时钟不分频
    CLKSEL = 0x01;                              //选择外部晶振
      PWMA_INIT();
      EA = 1;                   //开总中断
      while(1)
      {
                calculate_average();
                Display();
      }
}
void PWMA_ISR() interrupt 26      //PWMA中断服务程序
{
      if(PWMA_SR1 & 0x02)
      {      
                cap_old = cap_new;
                cap_new = PWMA_CCR1;
                cap = cap_new - cap_old;
                PWMA_SR1 &= ~0x02;      //清除中断标志位
      }
}


      #include "stc8h.h"      //包含stc8h.h文件
#include "intrins.h"    //包含intrins.h文件

typedef unsigned int uint;      //定义uint类型
typedef unsigned char uchar;      //定义uchar类型   
typedef unsigned long ulong;    //定义ulong类型

#include "Dis_Play.h"   //包含Dis_Play.h文件#include "all.h"

uchar data SMG_Write_Buffer;//用于给数码管各个位赋值之用
                                             //0,   1,      2,   3,          4,   5,      6,   7,   8,   9,   A,   B,   C,   D,   E   F,   -,    空,℃,℉
uchar code SEG_DISPLAY = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0xB9,0x71,0x40,0x00,0x79,0xF1};

// 主函数
void DISPLAY_SER()         //显示服务函数;
{
      //P_SW2 |= 0x80;      //允许访问特殊功能寄存器XFR;
      COMEN = 0x1f;                //打开低位的5个COM口;
      SEGENL = 0x00;      //不使能低8位SEG口;
      SEGENH = 0xff;      //使能高8位SEG口;
      LEDCTRL = 0x80; //设置打开LED驱动,使用共阴模式,亮度100%;
      LEDCKS = 0x2a;                //调整刷新频率;
      COM0_DC_H = SMG_Write_Buffer;//赋值给每一位寄存器;
      COM1_DC_H = SMG_Write_Buffer;
      COM2_DC_H = SMG_Write_Buffer;
      COM3_DC_H = SMG_Write_Buffer;
      COM4_DC_H = SMG_Write_Buffer;
      LEDCTRL |= 0x80;      //启动LED驱动;
}


国芯人工智能 发表于 2025-4-20 22:03:00

在使用STC8H4K64TL单片机进行方波周期捕获时,数码管显示出现突跳现象,尤其是在频率较低时更为明显。这种现象可能由多种因素引起,以下是一些可能的原因及相应的解决方案。

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

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

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

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

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

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

代码优化建议
根据提供的代码,以下是一些优化建议:

c
// 包含头文件
include "allh"

ulong cap;
ulong capnew;
ulong capold;
unsigned long num = 0;

// 数码管显示函数
void Display()
{
    SMGWriteBuffer = SEGDISPLAY; // 赋值给每一位寄存器
    SMGWriteBuffer = SEGDISPLAY;
    SMGWriteBuffer = SEGDISPLAY;
    SMGWriteBuffer = SEGDISPLAY;
    SMGWriteBuffer = SEGDISPLAY;
    DISPLAYSER();
}

// PWMA初始化程序
void PWMAINIT()
{
    PWMAPS = 0x00;
    PWMAPSCR = 0x13; // 设置预分频器的值为50
    PWMACCER1 = 0x00; // 先清零后写入
    PWMACCMR1 = 0x01; // (CC1连续捕获TI1上升沿)
    PWMACCER1 = 0x01; // CC1为输入模式,且映射到TI1FP1上
    PWMAIER = 0x02; // 使能PWM
}

// 捕获中断处理程序
void PWMAIRQHandler() interrupt PWMAVECTOR
{
    if (PWMASR1 & 0x02) // 检查捕获中断标志
    {
      capnew = PWMACCR1; // 获取捕获值
      if (capnew > capold)
      {
            cap = capnew - capold; // 计算周期
      }
      else
      {
            cap = (0xFFFF - capold) + capnew; // 处理溢出情况
      }
      capold = capnew; // 更新旧值
      num = cap; // 更新显示值
      PWMASR1 &= ~0x02; // 清除中断标志
    }
}

// 主函数
void main()
{
    PWMAINIT(); // 初始化PWMA
    EA = 1; // 使能全局中断
    while (1)
    {
      Display(); // 显示数据
    }
}

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

[本文内容由国芯人工智能辅助生成,仅供参考]

金南京 发表于 2025-4-21 07:56:09

国芯人工智能 发表于 2025-4-20 22:03
在使用STC8H4K64TL单片机进行方波周期捕获时,数码管显示出现突跳现象,尤其是在频率较低时更为明显。这种 ...

大佬你真厉害!已经解决了,无比感谢!
页: [1]
查看完整版本: AI8H4K64TL在做捕获方波周期时,发现数码管显示会突跳,频率越低越厉害 | 已解决