找回密码
 立即注册
查看: 179|回复: 19

15W408AS PCA捕获测频率,只能600Hz-180KHz,指导

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-29 08:03:13
已绑定手机

2

主题

17

回帖

56

积分

注册会员

积分
56
发表于 2025-8-26 11:19:17 | 显示全部楼层 |阅读模式
总思路是:PCA中断后记录捕获数据6次,包括中断PCA计数组(6位)、PCA溢出数组(6位),然后关断PCA捕获,将数据处理计算出频率。现在可以在600Hz-180Khz,低频问题,应该是溢出没有处理好,但高频是怎么回事,头大,外部晶振已经是35Mhz,我用串口调试助手打印,发现PCA停止不了,中断次数不是0-5,而是很大。


//此版本可以基本测量频率,35MHz时钟 1T 最高可测到190Khz,再高频率就不对了,以下是源代码,理论来讲35Mhz,怎么也得捕获M级的频率了。
measurement_active = 0;  // 暂停捕获 我用CR=0,CMOD &= ~(1 << 0);都试过PCA关断不了,index 数据很大。
串口信息如下Capture index: 1536                    Capture index: 256                    Capture index: 512                    Capture index: 768                    Capture index: 1024                    Capture index: 1280                    Capture index: 1536                    Capture index: 256                    Capture index: 512                    Capture index: 768                    Capture index: 1024                    Capture index: 1280                    Capture index: 1536                    Capture index: 256                    Capture index: 512                    Capture index: 768                    Capture index: 1024                    Capture index: 1280                    Capture index: 1536                    Capture index: 256

#include <STC15.h>
#include <intrins.h>
#include <stdio.h>

// 引脚定义
sbit RS = P3^2;
sbit RW = P3^3;
sbit EN = P3^4;
sbit LED_IND = P3^7;
#define DATA_PORT P1

// 全局变量 - 优化内存使用
volatile unsigned long pca_overflow_count = 0;
volatile bit new_capture = 0;
volatile unsigned char capture_index = 0;     // 当前捕获索引
volatile bit capture_complete = 0;           // 6次捕获完成标志
volatile bit measurement_active = 1;          // 测量激活标志

// 6次捕获数据存储 - 移到xdata段节省DATA空间
volatile unsigned int xdata capture_values[6];      // 6次捕获值
volatile unsigned long xdata overflow_counts[6];    // 6次溢出计数

// 捕获处理变量
volatile unsigned long last_capture_value = 0;
volatile unsigned long overflow_at_last_capture = 0;
volatile bit first_capture = 1;

unsigned char display_buffer[8];  // 优化:刚好8字符,节省1字节
unsigned char i;
// 串口初始化 - 使用定时器2作为波特率发生器
void uart_init() {
    // 设置串口引脚
    P3M0 &= ~(1 << 0);  // P3.0 输入
    P3M1 &= ~(1 << 0);
    P3M0 |=  (1 << 1);  // P3.1 推挽输出
    P3M1 &= ~(1 << 1);
   
    SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                //定时器时钟1T模式
        T2L = 0xB4;                        //设置定时初始值
        T2H = 0xFF;                        //设置定时初始值
        AUXR |= 0x10;                //定时器2开始计时
   
   // ET1 = 0;                        //禁止定时器中断
    //TR1 = 1;                                //定时器1开始计时
   // ES = 1;             // 使能串口中断
   // EA = 1;             // 使能总中断
}

// printf重定向到串口
char putchar(char c) {
    SBUF = c;
    while (!TI);
    TI = 0;
    return c;
}
// 打印PCA捕获值
void print_pca_values() {
    unsigned char i;
   
    printf("PCA Values:\r\n");
    for (i = 0; i < 6; i++) {
        printf("Capture[%d]: %u Overflow: %lu\r\n",
               i, capture_values, overflow_counts);
    }
    printf("----------------\r\n");
}

// 延时函数
void delay_us(unsigned int us) {
    while (us--) {
        _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
        _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
    }
}

void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 120; j++)  // 优化:从240减少到120,节省代码空间
            delay_us(1);
}

// LCD函数
void lcd_busy() {
    delay_us(50);
}

void lcd_write_cmd(unsigned char cmd) {
    lcd_busy();
    RS = 0;
    RW = 0;
    DATA_PORT = cmd;
    EN = 1;
    _nop_(); _nop_();
    EN = 0;
    delay_us(50);
}

void lcd_write_data(unsigned char dat) {
    lcd_busy();
    RS = 1;
    RW = 0;
    DATA_PORT = dat;
    EN = 1;
    _nop_(); _nop_();
    EN = 0;
    delay_us(50);
}

void lcd_init() {
    delay_ms(15);
    lcd_write_cmd(0x30);
    delay_ms(5);
    lcd_write_cmd(0x30);
    delay_us(100);
    lcd_write_cmd(0x30);
    delay_us(100);
    lcd_write_cmd(0x38);
    lcd_write_cmd(0x0C);
    lcd_write_cmd(0x01);
    lcd_write_cmd(0x06);
    delay_ms(2);
}

// 显示8字符字符串
void lcd_show_line(unsigned char line, unsigned char *str) {
    if (line == 0) {
        lcd_write_cmd(0x80);
    } else {
        lcd_write_cmd(0xC0);
    }
   
    for(i = 0; i < 8 && str != '\0'; i++) {
        lcd_write_data(str);
    }
    for(; i < 8; i++) {
        lcd_write_data(' ');
    }
}

// IO初始化
void io_init() {
    P1M0 = 0x00;
    P1M1 = 0x00;
    P1 = 0xFF;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P3 = 0xFF;
    P3M1 |= 0x20;
    P3M0 |= 0x80;
    LED_IND = 0;
}

// PCA初始化
void pca_init() {
    CR = 0;
    P_SW1 &= ~(1 << 5);
    P_SW1 |=  (1 << 4);
    CMOD = 0x09;
    CCAPM0 = 0x21;
    CL = 0;
    CH = 0;
    CCAP0L = 0;
    CCAP0H = 0;
    CCON = 0x00;
   
    // 初始化捕获相关变量
    pca_overflow_count = 0;
    capture_index = 0;
    capture_complete = 0;
    measurement_active = 1;
   
    CR = 1;
}

// PCA中断服务函数 - 只记录数据,不做计算
void pca_isr() interrupt 7 {
    if (CF) {
        CF = 0;
        pca_overflow_count++;
    }
   
    if (CCF0 && measurement_active) {
        CCF0 = 0;
        
        // 直接存储捕获值和溢出值
        capture_values[capture_index] = (CCAP0H << 8) | CCAP0L;
        overflow_counts[capture_index] = pca_overflow_count;
        capture_index++;
        
             // 检查是否完成6次捕获
        if (capture_index >= 6 && !capture_complete) {
            capture_complete = 1;
            measurement_active = 0;  // 暂停捕获
            new_capture = 1;        // 通知主循环处理
        }
    }
}

// 直接显示频率值
void display_frequency() {
    if (capture_complete) {
        // 计算频率:使用相邻捕获值计算周期
        unsigned long period;
        float freq;
        unsigned char i;
        
        // 计算相邻捕获值之间的周期(取平均值)
        period = 0;
        for ( i = 1; i < 6; i++) {
            if (capture_values >= capture_values[i-1]) {
                period += (capture_values - capture_values[i-1]);
            } else {
                period += ((65536UL - capture_values[i-1]) + capture_values);
            }
        }
        period = period / 5;  // 取平均值
        
        // 计算频率
        if (period > 0) {
            freq = 35000000.0 / period;  // 35MHz时钟
            
            // 第一行显示频率值
            if (freq < 1000) {
                sprintf(display_buffer, "%7.1f ", freq);
            } else if (freq < 1000000) {
                sprintf(display_buffer, "%7.3f ", freq/1000);
            } else {
                sprintf(display_buffer, "%7.3f ", freq/1000000);
            }
            lcd_show_line(0, display_buffer);
            
            // 第二行显示单位
            if (freq < 1000) {
                lcd_show_line(1, "Hz      ");
            } else if (freq < 1000000) {
                lcd_show_line(1, "kHz     ");
            } else {
                lcd_show_line(1, "MHz     ");
            }
        } else {
            lcd_show_line(0, "Error   ");
            lcd_show_line(1, "Calc    ");
        }
        
        // 重置捕获状态,准备下一轮测量
        capture_complete = 0;
        capture_index = 0;
        first_capture = 1;
        measurement_active = 1;
    }
}

// 主函数
void main() {
    io_init();
    lcd_init();
    uart_init();
    pca_init();
    EA = 1;
   
    lcd_show_line(0, "Freq Meter");
    delay_ms(1000);
   
    while(1) {
   
        
        if (new_capture) {
            // 有新的捕获数据,显示一次
            new_capture = 0;
            display_frequency();
            print_pca_values();
        } else {
            // 等待捕获完成,显示等待状态
            if (!capture_complete) {
                lcd_show_line(0, "Waiting");
                lcd_show_line(1, "Signal");
            }
        }
        
        delay_ms(100);  // 100ms检查一次
    }
}

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-29 08:03:13
已绑定手机

2

主题

17

回帖

56

积分

注册会员

积分
56
发表于 2025-8-26 11:23:09 | 显示全部楼层
请大神帮忙分析 PCA为什么不按预期只中断6次停下来,中断次数数据这么大的原因。 这款单片机能不能测频1Hz-600Khz

点评

PCA不大可能测频600KHz。 PCA捕获进入中断、退出中断就要各1us,还要处理数据,所以做不到了。 应该是10KHz以内可以使用PCA捕获周期计算频率,超过10KHz就应该用定时器对外计数来测频。  详情 回复 发表于 2025-8-26 12:56
回复

使用道具 举报 送花

3

主题

2001

回帖

850

积分

等待验证会员

积分
850
发表于 2025-8-26 11:23:00 | 显示全部楼层
针对您在使用STC15W408AS的PCA模块进行频率捕获时遇到的问题,以下为专业分析与解决方案:

一、问题概述

您在使用PCA模块进行频率测量时,发现:
低频段(600Hz~180kHz):可正常工作,但存在溢出处理不准确的情况;
高频段(超过180kHz):出现中断次数异常(数值过大),且无法停止PCA捕获;
外部晶振为35MHz,理论上应支持更高频率的测量。

当前代码中通过记录6次PCA中断和溢出事件来计算频率,但实际运行中出现异常现象,需进一步排查原因。

二、可能原因分析

1. PCA模式配置错误

PCA(可编程计数器阵列)在不同模式下对输入信号的响应方式不同。若未正确设置PCA模式(如CCAPM0/CCAPM1寄存器),可能导致捕获行为异常。
建议检查:
CCAPM0 和 CCAPM1 的配置是否正确;
是否启用了捕获模式(CCAPMx 中的 CAPN 和 CAPM 位);
是否设置了正确的捕获边沿(上升沿或下降沿)。

2. 中断优先级或使能设置不当

如果PCA中断未被正确关闭或优先级设置冲突,可能导致中断频繁触发,导致数据异常。
建议检查:
EA(全局中断使能)是否开启;
PCAP 和 PCAIE 是否启用;
中断服务函数中是否正确清除了中断标志位(PCAIF)。

3. 溢出计数逻辑不完善

在记录6次捕获数据后,若未正确处理PCA计数器溢出,可能导致计算结果偏差。
建议改进:
在每次捕获前读取并保存当前的PCA计数值;
对溢出次数进行累加,并在计算频率时考虑溢出影响;
确保在捕获结束后及时关闭PCA模块(CMOD &= ~0x01)。

4. 高频下捕获速度不足

虽然系统时钟为35MHz,但在1T模式下,PCA的捕获精度和速度可能受限于硬件资源分配。
建议优化:
考虑降低系统时钟频率以提高稳定性;
或采用更高效的中断处理机制,避免因中断延迟导致的数据丢失。

5. 外部信号干扰或输入波形不稳定

高频信号可能受到外部噪声干扰,导致捕获误判。
建议检查:
输入信号是否稳定;
使用示波器观察输入波形,确认无毛刺或畸变;
可尝试增加滤波电路或软件去抖处理。

三、建议的改进方案

1. 完善PCA初始化流程

确保PCA模块初始化正确,包括:
  1. c
  2. // 初始化PCA
  3. CMOD = 0x00;           // 设置为1T模式
  4. CCAPM0 = 0x0A;         // 启用捕获模式(上升沿捕获)
  5. CCAPM1 = 0x00;         // 关闭CCAP1
  6. PCAIF = 0;             // 清除中断标志
  7. PCAIE = 1;             // 使能PCA中断
  8. EA = 1;                // 全局中断使能
复制代码

2. 增强中断处理逻辑

在中断服务函数中,确保正确记录捕获值和溢出次数:
  1. c
  2. void PCAISR(void) interrupt 23 {
  3.     static uint8t count = 0;
  4.     static uint16t capturevalues[6];
  5.     static uint16t overflowcounts[6];
  6.     if (count < 6) {
  7.         capturevalues[count] = CCAP0L;  // 读取捕获值
  8.         overflowcounts[count] = PCAOV;  // 读取溢出次数
  9.         count++;
  10.     } else {
  11.         // 数据采集完成,关闭PCA
  12.         CMOD &= ~0x01;
  13.         measurementactive = 0;
  14.     }
  15.     PCAIF = 0;  // 清除中断标志
  16. }
复制代码

3. 优化频率计算算法

根据捕获值和溢出次数计算频率:
  1. c
  2. float calculatefrequency(uint16t capture, uint16t overflow, uint8t count) {
  3.     uint32t totaltime = 0;
  4.     for (uint8t i = 0; i < count; i++) {
  5.         totaltime += (uint32t)(overflow[i]  65536 + capture[i]);
  6.     }
  7.     return (float)(35000000 / (totaltime / count));
  8. }
复制代码

4. 添加调试输出

通过串口打印关键变量,帮助定位问题:
  1. c
  2. printf("Capture: %d, Overflow: %d\n", capturevalues[i], overflowcounts[i]);
复制代码

四、总结

您的设计思路基本合理,但在高频场景下,可能存在以下问题:
PCA模式或中断配置不准确;
溢出计数逻辑未充分考虑;
中断处理效率不足;
外部信号稳定性不佳。

建议从上述几个方面逐一排查,并结合实际测试数据进行优化。如需进一步协助,可提供完整代码及测试波形图以便深入分析。

如需进一步技术文档或参考资料,请告知,我将为您整理相关资料。

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

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:505
  • 最近打卡:2025-09-02 16:59:35
已绑定手机

45

主题

2194

回帖

7662

积分

论坛元老

积分
7662
发表于 2025-8-26 12:04:21 | 显示全部楼层
附件的例子供参考,通过调整PCA时钟源可以修改捕获频率范围
捕获高频脉冲可用系统时钟作为PCA时钟源
截图202508261208005551.jpg

PCA的16位捕获测量脉宽.zip

30.29 KB, 下载次数: 13

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:546
  • 最近打卡:2025-09-02 06:28:13
已绑定手机

85

主题

6045

回帖

1万

积分

超级版主

积分
11106
发表于 2025-8-26 12:10:32 | 显示全部楼层
15系列16位PCA捕获测量脉宽

  1. //本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
  2. //若无特别说明,工作频率一般为11.0592MHz
  3. #include "reg51.h"
  4. #include "intrins.h"
  5. #define FOSC    11059200L
  6. typedef unsigned char BYTE;
  7. typedef unsigned int WORD;
  8. typedef unsigned long DWORD;
  9. sfr P0M1 = 0x93;
  10. sfr P0M0 = 0x94;
  11. sfr P1M1 = 0x91;
  12. sfr P1M0 = 0x92;
  13. sfr P2M1 = 0x95;
  14. sfr P2M0 = 0x96;
  15. sfr P3M1 = 0xb1;
  16. sfr P3M0 = 0xb2;
  17. sfr P4M1 = 0xb3;
  18. sfr P4M0 = 0xb4;
  19. sfr P5M1 = 0xC9;
  20. sfr P5M0 = 0xCA;
  21. sfr P6M1 = 0xCB;
  22. sfr P6M0 = 0xCC;
  23. sfr P7M1 = 0xE1;
  24. sfr P7M0 = 0xE2;
  25. sfr P_SW1       = 0xA2;             //外设功能切换寄存器1
  26. #define CCP_S0 0x10                 //P_SW1.4
  27. #define CCP_S1 0x20                 //P_SW1.5
  28. sfr CCON        =   0xD8;           //PCA控制寄存器
  29. sbit CCF0       =   CCON^0;         //PCA模块0中断标志
  30. sbit CCF1       =   CCON^1;         //PCA模块1中断标志
  31. sbit CR         =   CCON^6;         //PCA定时器运行控制位
  32. sbit CF         =   CCON^7;         //PCA定时器溢出标志
  33. sfr CMOD        =   0xD9;           //PCA模式寄存器
  34. sfr CL          =   0xE9;           //PCA定时器低字节
  35. sfr CH          =   0xF9;           //PCA定时器高字节
  36. sfr CCAPM0      =   0xDA;           //PCA模块0模式寄存器
  37. sfr CCAP0L      =   0xEA;           //PCA模块0捕获寄存器 LOW
  38. sfr CCAP0H      =   0xFA;           //PCA模块0捕获寄存器 HIGH
  39. sfr CCAPM1      =   0xDB;           //PCA模块1模式寄存器
  40. sfr CCAP1L      =   0xEB;           //PCA模块1捕获寄存器 LOW
  41. sfr CCAP1H      =   0xFB;           //PCA模块1捕获寄存器 HIGH
  42. sfr CCAPM2      =   0xDC;           //PCA模块2模式寄存器
  43. sfr CCAP2L      =   0xEC;           //PCA模块2捕获寄存器 LOW
  44. sfr CCAP2H      =   0xFC;           //PCA模块2捕获寄存器 HIGH
  45. sfr PCA_PWM0    =   0xf2;           //PCA模块0的PWM寄存器
  46. sfr PCA_PWM1    =   0xf3;           //PCA模块1的PWM寄存器
  47. sfr PCA_PWM2    =   0xf4;           //PCA模块2的PWM寄存器
  48. BYTE cnt;                           //存储PCA计时溢出次数
  49. DWORD count0;                       //记录上一次的捕获值
  50. DWORD count1;                       //记录本次的捕获值
  51. DWORD length;                       //存储信号的时间长度(count1 - count0)
  52. void main()
  53. {
  54.     P0M0 = 0x00;
  55.     P0M1 = 0x00;
  56.     P1M0 = 0x00;
  57.     P1M1 = 0x00;
  58.     P2M0 = 0x00;
  59.     P2M1 = 0x00;
  60.     P3M0 = 0x00;
  61.     P3M1 = 0x00;
  62.     P4M0 = 0x00;
  63.     P4M1 = 0x00;
  64.     P5M0 = 0x00;
  65.     P5M1 = 0x00;
  66.     P6M0 = 0x00;
  67.     P6M1 = 0x00;
  68.     P7M0 = 0x00;
  69.     P7M1 = 0x00;
  70.     ACC = P_SW1;
  71.     ACC &= ~(CCP_S0 | CCP_S1);      //CCP_S0=0 CCP_S1=0
  72.     P_SW1 = ACC;                    //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)
  73.    
  74. //  ACC = P_SW1;
  75. //  ACC &= ~(CCP_S0 | CCP_S1);      //CCP_S0=1 CCP_S1=0
  76. //  ACC |= CCP_S0;                  //(P3.4/ECI_2, P3.5/CCP0_2, P3.6/CCP1_2, P3.7/CCP2_2)
  77. //  P_SW1 = ACC;  
  78. //  
  79. //  ACC = P_SW1;
  80. //  ACC &= ~(CCP_S0 | CCP_S1);      //CCP_S0=0 CCP_S1=1
  81. //  ACC |= CCP_S1;                  //(P2.4/ECI_3, P2.5/CCP0_3, P2.6/CCP1_3, P2.7/CCP2_3)
  82. //  P_SW1 = ACC;  
  83.     CCON = 0;                       //初始化PCA控制寄存器
  84.                                     //PCA定时器停止
  85.                                     //清除CF标志
  86.                                     //清除模块中断标志
  87.     CL = 0;                         //复位PCA寄存器
  88.     CH = 0;
  89.     CCAP0L = 0;
  90.     CCAP0H = 0;
  91.     CMOD = 0x09;                    //设置PCA时钟源为系统时钟,且使能PCA计时溢出中断
  92.     CCAPM0 = 0x21;                  //PCA模块0为16位捕获模式(上升沿捕获,可测从高电平开始的整个周期),且产生捕获中断
  93. //  CCAPM0 = 0x11;                  //PCA模块0为16位捕获模式(下降沿捕获,可测从低电平开始的整个周期),且产生捕获中断
  94. //  CCAPM0 = 0x31;                  //PCA模块0为16位捕获模式(上升沿/下降沿捕获,可测高电平或者低电平宽度),且产生捕获中断
  95.     CR = 1;                         //PCA定时器开始工作
  96.     EA = 1;
  97.     cnt = 0;
  98.     count0 = 0;
  99.     count1 = 0;
  100.     while (1);
  101. }
  102. void PCA_isr() interrupt 7
  103. {
  104.     if (CCF0)
  105.     {
  106.         CCF0 = 0;
  107.         if (CF && ((CCAP0H & 0x80) == 0))
  108.         {
  109.             CF = 0;
  110.             cnt++;
  111.         }
  112.         count0 = count1;            //备份上一次的捕获值
  113.         ((BYTE *)&count1)[3] = CCAP0L;  //保存本次的捕获值
  114.         ((BYTE *)&count1)[2] = CCAP0H;
  115.         ((BYTE *)&count1)[1] = cnt;
  116.         ((BYTE *)&count1)[0] = 0;
  117.         length = count1 - count0;   //计算两次捕获的差值,即得到时间长度
  118.         ((BYTE *)&length)[0] = 0;
  119.     }
  120.     if (CF)
  121.     {
  122.         CF = 0;
  123.         cnt++;                      //PCA计时溢出次数+1
  124.     }
  125. }
复制代码


回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:168
  • 最近打卡:2025-09-02 10:14:23

76

主题

6682

回帖

1万

积分

超级版主

积分
14003
发表于 2025-8-26 12:56:49 | 显示全部楼层
Prin*** 发表于 2025-8-26 11:23
请大神帮忙分析 PCA为什么不按预期只中断6次停下来,中断次数数据这么大的原因。 这款单片机能不能测频1Hz- ...

PCA不大可能测频600KHz。
PCA捕获进入中断、退出中断就要各1us,还要处理数据,所以做不到了。
应该是10KHz以内可以使用PCA捕获周期计算频率,超过10KHz就应该用定时器对外计数来测频。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-29 08:03:13
已绑定手机

2

主题

17

回帖

56

积分

注册会员

积分
56
发表于 2025-8-26 13:36:52 | 显示全部楼层
之前我用是P3.4 脚接外部脉冲的,就是看网上贴子说PCA可以测频率更准,就改成了P3.5 CCP0_2 引脚 PCA。哎。外部定时器T0确定可以测1-600K吗,我要换P3.4重新弄

点评

将P3.4、P3.5连在一起,Timer0通过P3.4-T0对外计频率,当频率较小时,启动P3.5-CCP0-2捕获测周期计算频率。  详情 回复 发表于 2025-8-26 16:10
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-29 08:03:13
已绑定手机

2

主题

17

回帖

56

积分

注册会员

积分
56
发表于 2025-8-26 13:41:23 | 显示全部楼层
乘风*** 发表于 2025-8-26 12:04
附件的例子供参考,通过调整PCA时钟源可以修改捕获频率范围
捕获高频脉冲可用系统时钟作为PCA时钟源

用的是35M  1T 测频率,但只能调200Khz以内  ,麻烦帮我看看可以测到600K吗,不可以,改用定时器外部计数是否可以
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:505
  • 最近打卡:2025-09-02 16:59:35
已绑定手机

45

主题

2194

回帖

7662

积分

论坛元老

积分
7662
发表于 2025-8-26 14:20:19 | 显示全部楼层
Prin*** 发表于 2025-8-26 13:41
用的是35M  1T 测频率,但只能调200Khz以内  ,麻烦帮我看看可以测到600K吗,不可以,改用定时器外部计数 ...

按照例子里面的计算公式:捕获脉宽时间=捕捉的时钟数/PCA时钟源
捕获脉冲频率=PCA时钟源/捕捉的时钟数
用35M时钟源捕获600K脉冲,捕捉的时钟数=58左右
高频脉冲捕获最好使用带PLL高速时钟的PWM,可参考下面帖子:

如何测量72MHz以下的外部信号,STC32的144MHz的高速PWM
https://www.stcaimcu.com/thread-1360-1-1.html
(出处: 国芯人工智能技术交流网站)
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-29 08:03:13
已绑定手机

2

主题

17

回帖

56

积分

注册会员

积分
56
发表于 2025-8-26 15:06:33 | 显示全部楼层
乘风*** 发表于 2025-8-26 14:20
按照例子里面的计算公式:捕获脉宽时间=捕捉的时钟数/PCA时钟源
捕获脉冲频率=PCA时钟源/捕捉的时钟数
用 ...

58按理说STC15W408AS应该可以做到吧
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-9-3 08:33 , Processed in 0.137593 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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