yanwei0433 发表于 2022-12-14 15:46:27

PWM捕获问题

芯片为STC32,问题是cnt1 和cnt2的值根本和发送过来的波形值对不上,占空比和周期都不对 。发送波形为200HZ,40%占比 占空比和周期乱跳。


这是P10端口输入波形

==============================================



void PWM_Init() //PWM捕捉初始化
{
                PWMA_CCER1=0x00;
                PWMA_CCMR1=0x31;    //CC1为输入模式,且映射到TI1FP1上
                PWMA_CCMR2=0x32;    //CC2为输入模式,且映射到TI1FP2上
                PWMA_CCER1=0x11;    //使能CC1/CC2上的捕获功能
                PWMA_CCER1|=0x00;   //设置捕获极性为CC1的上升沿
                PWMA_CCER1|=0x20;   //设置捕获极性为CC2的下降沿
                PWMA_SMCR=0x54;   //TS=TI1FP1,SMS=TI1上升沿复位模式
                PWMA_CR1=0x01;      //开启计数器
                PWMA_IER=0x06;                        //使能CC1/CC2捕获中断       
}




void PWMA_ISR() interrupt 26    //PWM中断 P10脚
{
        if (PWMA_SR1 & 0x02)
        {
                PWMA_SR1 &= ~0x02;
                cnt1=(PWMA_CCR1H<<8)+PWMA_CCR1L;//CC1捕捉周期
                PWMA_INT=1;
        }
        if (PWMA_SR1 & 0x04)
        {
                PWMA_SR1 &= ~0x04;
                cnt2=(PWMA_CCR2H<<8)+PWMA_CCR2L;                //CC2捕捉占空比
                PWMA_INT1=1;
        }
}



                                if(PWMA_INT==1)
                                {
                                        printf("t3.txt=\"%d\"",cnt1);
                                        UART_Send_END();
                                        for(l=0;l<20;l++)
                                        {
                                                printf("add 2,0,80");
                                                UART_Send_END();          //发送3个FF
                                        }
                                        PWMA_INT=0;
                                }
                                if(PWMA_INT1==1)
                                {
                                        printf("t5.txt=\"%d\"",cnt2);
                                        UART_Send_END();
                                        for(l=0;l<20;l++)
                                        {
                                                printf("add 2,0,130");
                                                UART_Send_END();          //发送3个FF
                                        }
                                        PWMA_INT1=0;
                                }


=======================================================

一轮明月 发表于 2022-12-14 16:21:45

可以先参考下我们手册和下载软件上的范例,也请论坛大师帮忙看下此客户问题!

yanwei0433 发表于 2022-12-15 09:08:42

这个是完全按照例程做的

zhp 发表于 2022-12-15 09:31:49



没有你的源代码,只能猜测,有没有可能是你下面的两个串口发送数据占用时间太长
导致无法及时处理PWMA_INT和PWMA_INT1两个信号

yanwei0433 发表于 2022-12-15 09:55:11

PWMA_INT和PWMA_INT1这两是标志   今天我也把循环去掉了还是显示的不对CNT1和cnt2正常就是读到数 我就发出去了,上面的代码都是和捕获有关系的

yanwei0433 发表于 2022-12-15 10:02:48

是不是和定时器有关系呢我用时钟是片内24M得 外部没接晶振   PWM这个定时器 和 其他定时器是独立的还是一起的 MAIN_Fosc是24M
//===================   本地常量声明   ====================
                        
#define Timer0_Reload   (65536UL -(MAIN_Fosc / 1000))       //Timer 0 中断频率, 1000次/秒

void Timer0_Init() //定时器初始化
{
                AUXR = 0x80;                                          //定时器0设置为1T,16位定时器自动重新加载,
                TH0 = (u8)(Timer0_Reload / 256);
                TL0 = (u8)(Timer0_Reload % 256);
                ET0 = 1;                                                // 定时器0中断
                TR0 = 1;                                                //定时器0开启
}

这个是串口的
#define BRT_A    (65536-(MAIN_Fosc/9600)/4)
void UART_Init()   
{
// PCON|=0x00; //PCON的最高位SMOD=1时波特率加倍
TMOD=0x00;//时器1为方式2 初值自动装入 产生波特率
TH1=BRT_A>>8;   //定时器初始为0xFF0XF7,晶振为24MHz,本函数实际产生的波特率为9600bps
TL1=BRT_A;       //同上f70xF4
SCON=0x50;       //串口设置为方式1,REN=1,允许接收
TR1=1;      //启动定时器1
T1x12=1;
S1BRT=0;
ES=1;       //使能串口接收中断,
EA=1;   //打开所有中断
}

yanwei0433 发表于 2022-12-15 10:22:54

PWMA_SMCR=0x54;   //TS=TI1FP1,SMS=TI1上升沿复位模式
这句具体含义,我看资料说就是每当捕捉到上升沿的时候,计数器的值会存到PWMA_CCR1里并且计数器清零,这样就得到了周期得值当下降沿时就读到了高电平的宽度了感觉跟计数器的时间有关系    还有就是数组乱跳

flyarm 发表于 2022-12-15 10:36:40

把捕获的 优先级调到最高

梁工 发表于 2022-12-15 10:44:50

yanwei0433 发表于 2022-12-15 10:22
PWMA_SMCR=0x54;   //TS=TI1FP1,SMS=TI1上升沿复位模式
这句具体含义,我看资料说就是每当捕捉到上升沿 ...

计数器只要不改变输入时钟,就不会有跳动的可能,除非你在不好做过程中,不断的改变时钟频率。

zhp 发表于 2022-12-15 12:20:22

本帖最后由 zhp 于 2022-12-15 13:18 编辑

yanwei0433 发表于 2022-12-15 09:55
PWMA_INT和PWMA_INT1这两是标志   今天我也把循环去掉了还是显示的不对CNT1和cnt2正常就是读到数 我就 ...
我们可以大概计算一下,你的信号源是200Hz,一个周期就是5ms
你的串口波特率为9600,传输一个字节(起始+数据+停止),10个bit的时间大概为1ms
一个信号源周期内部顶多传输5个字节的串口数据

不知你的代码后面有怎么修改,但你之前的代码中,
检测到PWMA_INT为1时,串口差不多要传输275个字节的数据,
检测到PWMA_INT1为1时,串口差不多要传输295个字节的数据

PWMA_INT和PWMA_INT1两个信号的处理严重滞后,串口打印出来的数据肯定是不正确的


附件是我按照你的程序模式,写的测试程序,
提高串口波特率,传输字节少一点,捕获到的周期和占空比都非常稳定


页: [1] 2
查看完整版本: PWM捕获问题