kookeda 发表于 2024-8-1 08:28:21

【PWM问题】STC8H8K64U是否可以实现2路PWM输出和6路检测

现在基于开天斧三.2开发板,通过使用高级PWM内部模块CC1,CC2,CC3,CC4,CC7,CC8进行捕获模块,进行外部PWM信号进行检测周期检测。通过PWM5,PWM6输出两路PWM信号。现象是CC1,CCC2,CC3,CC4能够正常检测到周期信号,PWM5,PWM6也能够正常输出占空比不同的PWM信号。PWM7,PWM8完全没有反应,希望各位前辈和大拿给指点一二,不胜感激。配置代码如下:
所有IO都配置成了准双向口了。


void pwm_init()
{
    PWMA_CCER1 = 0x00;
    PWMA_CCMR1 = 0x01;// CC1为输入模式,切映射到TI1FP1
    PWMA_CCMR2 = 0x01;// CC2为输入模式,切映射到TI2FP2
    PWMA_CCER1 = 0x11;// 使能 CC1 上的捕获功能,使能CC2上的捕获功能
    PWMA_CCER1 |= 0x02; //设置捕获极性为CC1 的下降沿
    PWMA_CCER1 |= 0x20; //设置捕获极性为CC2的下升沿

    PWMA_CCER2 = 0x00;
    PWMA_CCMR3 = 0x01; //ICC3 为输入模式且映射到TI3FP3 上
    PWMA_CCMR4 = 0x01;//CC4 为输入模式且映射到TI4FP4上

    PWMA_CCER2 =0x11;//使能 CC3 上的捕获功能,使能CC4 上的捕获功能
    PWMA_CCER2 |= 0x02; //设置捕获极性为CC3 的下升沿
    PWMA_CCER2 |= 0x20; //设置捕获极性为CC4 的下降沿
    PWMA_CR1 = 0x01;
    PWMA_IER = 0x1E;    //使能CCI/CC2/CC3/CC4 捕获中断
               
                PWMA_PS =0x00;
                PWMA_PS |= PWM1_2;//C0 -P2.0
                PWMA_PS |= PWM2_2;//C1 -P2.2
                PWMA_PS |= PWM3_2;//C2 -P2.4
                PWMA_PS |= PWM4_2;//C3 -P2.6
               
               
                PWMB_CCER1 = 0x00; // 写 CCMRx 前必须先清零 CCxE 关闭通道
    PWMB_CCMR1 = 0x68; //通道模式配置 PWM5
    PWMB_CCMR2 = 0x68; // 通道模式配置 PWM6
    PWMB_CCER1 = 0x33; // 配置通道输出使能和极性 PWM5 PWM6

    PWMB_ARRH = (u8)(PWM_PERIOD >> 8); // 设置周期时间
    PWMB_ARRL = (u8)PWM_PERIOD;

    PWMB_ENO = 0x00;
    PWMB_ENO |= ENO6P; // 使能输出
          PWMB_ENO |= ENO5P; // 使能输出
          
       
       
    PWMB_PS = 0x00;    // 高级 PWM 通道输出脚选择位
                PWMB_PS |= PWM5_4;   //7.4
    PWMB_PS |= PWM6_4; // 选择 PWM6_4 通道 P7.5
                PWMB_PS |= PWM7_4;   //7.6
                PWMB_PS |= PWM8_4;   //7.7

    PWMB_BKR = 0x80;// 使能主输出
    PWMB_CR1 |= 0x81; // ARR预装载,开始计时

    PWM6_Duty = PWM_PERIOD / 100 * 30;
    PWMB_CCR6H = (u8)(PWM6_Duty >> 8); // 设置占空比时间
    PWMB_CCR6L = (u8)(PWM6_Duty);
               
                PWMB_CCR5H = (u8)(PWM6_Duty >> 8); // 设置占空比时间
    PWMB_CCR5L = (u8)(PWM6_Duty);

    PWMB_CCER2 = 0x00;
    PWMB_CCMR3 = 0x01;   //CC7 为输入模式且映射到TITFP8上
    PWMB_CCMR4 = 0x01;   //CC8 为输入模式且映射到TITFP8 上
    PWMB_CCER2 = 0x11;   //使能 CC7上的捕获功能,使能CC8 上的捕获功能
    PWMB_CCER2 |= 0x02;//设置捕获极性为CC7的下升沿
    PWMB_CCER2 |= 0x20;//设置捕获极性为CC8 的下降沿
    PWMB_CR1 = 0x01;   //使能计数器B
               
    PWMB_IER = 0x18;    //使能CC7/CC8 捕获中断 18
}


中断程序:

void PWMA_ISR() interrupt PWMA_VECTOR
{
        u16 ccr;
        if(PWMA_SR1 &0x02)
        {
                PWMA_SR1 &=~0x02;
                ccr = (PWMA_CCR1H<<8)+PWMA_CCR1L;
                Cycles = ccr - ccr1;
                ccr1 = ccr;
        }
       
        if(PWMA_SR1 &0x04)
        {
                PWMA_SR1 &=~0x04;
                ccr = (PWMA_CCR2H<<8)+PWMA_CCR2L;
                Cycles = ccr - ccr2;
                ccr2 = ccr;
        }
       
        if(PWMA_SR1 &0x08)
        {
                PWMA_SR1 &=~0x08;
                ccr = (PWMA_CCR3H<<8)+PWMA_CCR3L;
                Cycles = ccr - ccr3;
                ccr3 = ccr;
        }
       
        if(PWMA_SR1 &0x10)
        {
                PWMA_SR1 &=~0x10;
                ccr = (PWMA_CCR4H<<8)+PWMA_CCR4L;
                Cycles = ccr - ccr4;
                ccr4 = ccr;
        }
}


void PWMB_ISR() interrupt PWMB_VECTOR
{
        u16 ccr;
        if(PWMB_SR1 &0x02)
        {
                PWMB_SR1 &=~0x02;
                ccr = (PWMB_CCR5H<<8)+PWMB_CCR5L;
                Cycles = ccr - ccr5;
                ccr5 = ccr;
        }
       

       
        if(PWMB_SR1 &0x10)
        {
                PWMB_SR1 &=~0x10;
                ccr = (PWMB_CCR8H<<8)+PWMB_CCR8L;
                Cycles = ccr - ccr6;
                ccr6 = ccr;
        }
}


主程序:

void SystemInit()
{
        GPIO_config();
        UART_config();
       
        //Timer0初始化
        TMOD &= 0xf0; // 16 bits timer auto-reload
        AUXR |= 0x80; // Timer0 set as 1T
        TH0 = (u8)(Timer0_Reload / 256);
        TL0 = (u8)(Timer0_Reload % 256);
        ET0 = 1; // Timer0 interrupt enable
        TR0 = 1; // Tiner0 run
       
        pwm_init();
       
        EA = 1;
}

/**********************************************/
void main(void)
{
        u8 i;
        EAXSFR(); /* 扩展寄存器访问使能 */
       
        SystemInit();

        while (1)
        {
                if(SystemTick%2000 == 0)
                {
                        for(i=0;i<6;i++)
                        {
                               printf("CH%d: %d ",(int)i,Cycles);
                               Cycles = 0;
                        }
                }

      }
}




               



乘风飞扬 发表于 2024-8-1 14:53:34

由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每次捕获都刚好PWM溢出,计算出的周期值始终是0.

在发生捕获动作时将当前的计数值保存到PWMx_CCRn里面,如果同时使能了PWM输出,计数值记到PWMx_ARR后就立即归零了.
(正常的计算方法是按照记到FFFF再归零,开启输出后计数值是记到ARR值就立即归零,所以PWMx_ARR最好设置FFFF)

附件是PWMA通道既有捕获输入,又有PWM输出的实现例子,供参考。

kookeda 发表于 2024-8-1 23:27:27

乘风飞扬 发表于 2024-8-1 14:53
由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每 ...

感谢感谢,我学习一下。
页: [1]
查看完整版本: 【PWM问题】STC8H8K64U是否可以实现2路PWM输出和6路检测