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

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

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-03-02 14:37:49

3

主题

7

回帖

85

积分

注册会员

积分
85
发表于 2024-8-1 08:28:21 | 显示全部楼层 |阅读模式
现在基于开天斧三.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[0] = ccr - ccr1;
                ccr1 = ccr;
        }
       
        if(PWMA_SR1 &0x04)
        {
                PWMA_SR1 &=  ~0x04;
                ccr = (PWMA_CCR2H<<8)+PWMA_CCR2L;
                Cycles[1] = ccr - ccr2;
                ccr2 = ccr;
        }
       
        if(PWMA_SR1 &0x08)
        {
                PWMA_SR1 &=  ~0x08;
                ccr = (PWMA_CCR3H<<8)+PWMA_CCR3L;
                Cycles[2] = ccr - ccr3;
                ccr3 = ccr;
        }
       
        if(PWMA_SR1 &0x10)
        {
                PWMA_SR1 &=  ~0x10;
                ccr = (PWMA_CCR4H<<8)+PWMA_CCR4L;
                Cycles[3] = 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[4] = ccr - ccr5;
                ccr5 = ccr;
        }
       

       
        if(PWMB_SR1 &0x10)
        {
                PWMB_SR1 &=  ~0x10;
                ccr = (PWMB_CCR8H<<8)+PWMB_CCR8L;
                Cycles[5] = 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[i]);
                                 Cycles[i] = 0;
                        }
                }

        }
}




               



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:445
  • 最近打卡:2025-06-17 12:12:21
已绑定手机

40

主题

2059

回帖

7077

积分

论坛元老

积分
7077
发表于 2024-8-1 14:53:34 | 显示全部楼层
由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每次捕获都刚好PWM溢出,计算出的周期值始终是0.

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

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

高级PWMA-捕获模式测量脉冲周期 - 同组同时输出PWM.zip

16.22 KB, 下载次数: 90

回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-03-02 14:37:49

3

主题

7

回帖

85

积分

注册会员

积分
85
发表于 2024-8-1 23:27:27 来自手机 | 显示全部楼层
乘风飞扬 发表于 2024-8-1 14:53
由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每 ...

感谢感谢,我学习一下。
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-17 12:59 , Processed in 0.140328 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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