ma99821 发表于 2025-2-20 16:46:29

8A8K64S4A12 高速PCA问题

输出4路高速PCA 分别位为 100KHz82KHz   40KHz   和200Hz      

问题:高速PCA无法调节PWM 宽窄 最好有试验程序

//========================================================================
// 函数: void      PCA_config(void)
// 描述: PCA配置函数。
// 参数: none
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
void      PCA_config(void)
{
      CR = 0;
      CH = 0;
      CL = 0;
//      AUXR1 = (AUXR1 & ~(3<<4)) | PCA_P12_P17_P16_P15_P14;                //切换IO口      PCA_P12_P17_P16_P15_P14, PCA_P22_P23_P24_P25_P26, PCA_P74_P70_P71_P72_P73, PCA_P35_P33_P32_P31_P30
//      P1n_push_pull(0xf0);                //将PWM或高速输出设置为推挽输出

      AUXR1 = (AUXR1 & ~(3<<4)) | PCA_P22_P23_P24_P25_P26;                //切换IO口      PCA_P12_P17_P16_P15_P14, PCA_P22_P23_P24_P25_P26, PCA_P74_P70_P71_P72_P73, PCA_P35_P33_P32_P31_P30
      P2n_push_pull(0x7c);                //将PWM或高速输出设置为推挽输出

//      AUXR1 = (AUXR1 & ~(3<<4)) | PCA_P35_P33_P32_P31_P30;                //切换IO口      PCA_P12_P17_P16_P15_P14, PCA_P22_P23_P24_P25_P26, PCA_P74_P70_P71_P72_P73, PCA_P35_P33_P32_P31_P30
//      P3n_push_pull(0x0f);                //将PWM或高速输出设置为推挽输出

//      AUXR1 = (AUXR1 & ~(3<<4)) | PCA_P74_P70_P71_P72_P73;                //切换IO口      PCA_P12_P17_P16_P15_P14, PCA_P22_P23_P24_P25_P26, PCA_P74_P70_P71_P72_P73, PCA_P35_P33_P32_P31_P30
//      P7n_push_pull(0x0f);                //将PWM或高速输出设置为推挽输出

      CMOD= (CMOD& ~0x0f) | PCA_Clock_1T | DISABLE;                        //选择时钟源 溢出中断      PCA_Clock_1T, PCA_Clock_2T, PCA_Clock_4T, PCA_Clock_6T, PCA_Clock_8T, PCA_Clock_12T, PCA_Clock_Timer0_OF, PCA_Clock_ECI
      PPCA = 1;      //高优先级中断

      CCAPM0   = PCA_Mode_HighPulseOutput | ENABLE;                //工作模式, 中断模式, (PCA_Rise_Active or PCA_Fall_Active) | (ENABLE or DISABLE)
      CCAP0_tmp= 100;      //按用户需要给一个初值
      CCAP0L = (u8)CCAP0_tmp;                        //先写CCAP0L
      CCAP0H = (u8)(CCAP0_tmp >> 8);      //后写CCAP0H

      CCAPM1   = PCA_Mode_HighPulseOutput | ENABLE;                //工作模式, 中断模式, (PCA_Rise_Active or PCA_Fall_Active) | (ENABLE or DISABLE)
      CCAP1_tmp= 200;      //按用户需要给一个初值
      CCAP1L = (u8)CCAP1_tmp;                        //先写CCAP1L
      CCAP1H = (u8)(CCAP1_tmp >> 8);      //后写CCAP1H

      CCAPM2   = PCA_Mode_HighPulseOutput | ENABLE;                //工作模式, 中断模式, (PCA_Rise_Active or PCA_Fall_Active) | (ENABLE or DISABLE)
      CCAP2_tmp= 300;      //按用户需要给一个初值
      CCAP2L = (u8)CCAP2_tmp;                        //先写CCAP2L
      CCAP2H = (u8)(CCAP2_tmp >> 8);      //后写CCAP2H

      CCAPM3   = PCA_Mode_HighPulseOutput | ENABLE;                //工作模式, 中断模式, (PCA_Rise_Active or PCA_Fall_Active) | (ENABLE or DISABLE)
      CCAP3_tmp= 400;      //按用户需要给一个初值
      CCAP3L = (u8)CCAP3_tmp;                        //先写CCAP3L
      CCAP3H = (u8)(CCAP3_tmp >> 8);      //后写CCAP3H

      CR = 1;
}


//========================================================================
// 函数: void      PCA_Handler (void) interrupt PCA_VECTOR
// 描述: PCA中断处理程序.
// 参数: None
// 返回: none.
// 版本: V1.0, 2016-5-10
//========================================================================
void      PCA_Handler (void) interrupt PCA_VECTOR
{
      if(CCF0)                //PCA模块0中断
      {
                CCF0 = 0;                //清PCA模块0中断标志
                CCAP0_tmp += 1200;
                CCAP0L = (u8)CCAP0_tmp;                        //先写CCAP0L
                CCAP0H = (u8)(CCAP0_tmp >> 8);      //后写CCAP0H

      }

      if(CCF1)      //PCA模块1中断
      {
                CCF1 = 0;                //清PCA模块1中断标志
                CCAP1_tmp += 2400;
                CCAP1L = (u8)CCAP1_tmp;                        //先写CCAP1L
                CCAP1H = (u8)(CCAP1_tmp >> 8);      //后写CCAP1H
      }

      if(CCF2)      //PCA模块2中断
      {
                CCF2 = 0;                //清PCA模块1中断标志
                CCAP2_tmp += 4800;
                CCAP2L = (u8)CCAP2_tmp;                        //先写CCAP2L
                CCAP2H = (u8)(CCAP2_tmp >> 8);      //后写CCAP2H
      }

      if(CCF3)      //PCA模块3中断
      {
                CCF3 = 0;                //清PCA模块1中断标志
                CCAP3_tmp += 6000;
                CCAP3L = (u8)CCAP3_tmp;                        //先写CCAP3L
                CCAP3H = (u8)(CCAP3_tmp >> 8);      //后写CCAP3H
      }

      if(CF)      //PCA溢出中断
      {
                CF = 0;                        //清PCA溢出中断标志
      }

}

乘风飞扬 发表于 2025-2-20 17:25:27

中断里面有行代码:
CCAPn_tmp += xxx;
通过修改xxx来调节频率。

ma99821 发表于 2025-2-21 07:42:42

乘风飞扬 发表于 2025-2-20 17:25
中断里面有行代码:
CCAPn_tmp += xxx;
通过修改xxx来调节频率。

不是要调节频率 是要调节当前频率的宽窄

乘风飞扬 发表于 2025-2-21 09:16:06

ma99821 发表于 2025-2-21 07:42
不是要调节频率 是要调节当前频率的宽窄

如果是想调节占空比的话,建议使用PWM模式,会简单很多:


ma99821 发表于 2025-2-21 09:23:08

乘风飞扬 发表于 2025-2-21 09:16
如果是想调节占空比的话,建议使用PWM模式,会简单很多:

pwm 做互补波形输出了 被占用了

梁工 发表于 2025-2-21 09:37:08

首先,你说的“高速PCA无法调节PWM”指的是PCA高速输出脉冲,不是PWM,你是想配合软件(中断)模拟PWM,原理上是可以的,但是对于100KHz,需要5us中断一次,装载匹配点,对MCU来说,这么频繁的中断,会严重占用CPU时间,甚至会拖死CPU。
使用PCA高速脉冲输出的方式来做PWM,中断频率超过20KHz我就不推荐,最小中断间隔不能少于100个主频时钟(因为中断处理需要时间)。

建议使用STC8G2K64S4,这个MCU有6组45路增强型15位PWM,你可以一组只用一路PWM,这样每组的PWM频率可以不同,PWM是硬件的,产生PWM不需要消耗CPU时间。
页: [1]
查看完整版本: 8A8K64S4A12 高速PCA问题