chenczyaa 发表于 2024-7-3 14:33

请教一下STC12H1K输出PWM的问题

本帖最后由 chenczyaa 于 2024-7-3 15:08 编辑

代码如下,我的P3.5脚 没PWM输出的,好奇怪。不知道是那里没设置对,来个大神指导下啊。
芯片用的是STC12H1K16,内部晶振11.0592MHz.
芯片电路没有外接任何元器件,只测芯片脚位的信号。
void pwm_init()
{
      
          CCON = 0x00;                         //
    CL = 0;                                 //PCA计数器 低8位
    CH = 0;                                  //PCA计数器 高8位
    CMOD = 0x00;                     //选择时钟源为系统时钟源的1/12

    CCAPM0 = 0x42;                   //0100 0010允许比较器,允许PWM0引脚输出
          //PCA_PWM0=0x00;                   //8位PWM
          PCA_PWM0=0x40;                   //7位PWM
          CCAP0H = CCAP0L = 0x00;         //设置占空比为 0
          PWMA_PS = 0xff;
          PWMB_PS = 0xf3;//P3.5输出PWM
      
    CR = 1;                        //启动 PCA 计数器阵列
      
}

main()
{
         uchar key1up=0,key2up=0,gear1=0,gear2=0;
      
      /*
      TMOD =0x00; //0模式16位自动重装载
      TL0=0x66;   //1ms初值
      TH0=0xfc;
      TR0=1;// 启动定时器0
      ET0=1;// 开启定时器0中断
      EA=1;// 开启整个中断系统
      */
      
      P1M0=0x00;//设置P1为准双向口
      P1M1=0x00;
      
      P3M0=0x00;//设置P3为准双向口
      P3M1=0x00;
      
      //P1=0xff;
      //P35=0;
      
      pwm_init();
      

      //PCA_PWM0=0x02;CCAP0H= CCAP0L=0xFF;   //固定输出低
      //PCA_PWM0=0x00;CCAP0H= CCAP0L=0x00;   //固定输出高

      //CCAP0L=0x20;//PWM占空比(100H-20H)/100H(87.5%)//8位PWM
      //CCAP0H=0x20;
          CR = 0;
          //CCAP0L=0xCC;//PWM占空比(100H-CCH)/100H(20%)//8位PWM
          //CCAP0H=0xCC;
                CCAP0L=0x20;//PWM占空比(80H-20H)/80H(75%)//7位PWM
          CCAP0H=0x20;
                CR = 1;

    P34=0;
      
      while(1)
{
                delay(4000);
                P34 = ~P34;
      }


chenczyaa 发表于 2024-7-4 10:00

没有大神帮看下吗?或者谁有用PCA中断输出PWM的代码能发出来参考下吗?

coody 发表于 2024-7-4 15:25

chenczyaa 发表于 2024-7-4 10:00
没有大神帮看下吗?或者谁有用PCA中断输出PWM的代码能发出来参考下吗?

测试了下,没有问题,4路PWM输出正常。

#define MAIN_Fosc                24000000UL        //定义主时钟

#include        "..\..\STC12H.h"

/*************        功能说明        **************

请先别修改程序, 直接下载"01-PCA-4路PWM-C语言"里的"PCA.hex"测试.

4路PCA都配置成10位PWM的应用.

本例 PWM0(CCP0)-->P3.7, PWM1(CCP1)-->P3.5, PWM2(CCP2)-->P2.0, PWM3(CCP3)-->P2.4, 用户可以自行修改切换到其它端口.
PWM0、PWM1、PWM2输出呼吸灯效果,PWM3间歇输出。

******************************************/

/*************        本地常量声明        **************/


/*************        本地变量声明        **************/

u16        pwm;                //pwm
bit        B_PWM_Dir;        //方向, 0为+, 1为-.
u8        cnt;

/*************        本地函数声明        **************/
void        UpdatePwm(u8 ch, u16 pwm_value);        // ch: PCA序号, 0~3对应 PCA0 ~ PCA3,pwm_value: pwm值, 这个值是输出低电平的时间.
void        PCA_config(u8 clk, u8 wide);          // clk: 选择时钟, 0: 12T,1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T,5: 4T,6: 6T,7: 8T
                                                                                        // wide: pwm的宽度, 0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM
void        PwmOutContinue(u8 ch, u8 level);        // ch: PCA序号, 0~3对应 PCA0 ~ PCA3,level: 连续输出的电平,0为低电平, 1为高电平.
void        delay_ms(u8 ms);

/*************外部函数和变量声明 *****************/



/******************** 主函数 **************************/
void main(void)
{

        PCA_config(4, 3);        //clk=4: 选择时钟1T, 3: 10位PWM
        P3n_push_pull(Pin7+Pin5);        // P3.7 P3.5设置为推挽输出
        P2n_push_pull(Pin4+Pin0);        // P2.4 P2.0设置为推挽输出

        pwm = 128;
        B_PWM_Dir = 0;

        while (1)
        {
                delay_ms(2);

                if(B_PWM_Dir)
                {
                        if(--pwm <= 8)                B_PWM_Dir = 0;
                }
                else
                {
                        if(++pwm >= 1016)        B_PWM_Dir = 1;
                }
                UpdatePwm(PCA0, pwm);        //更新PWM.
                UpdatePwm(PCA1, pwm);        //更新PWM.
                UpdatePwm(PCA2, pwm);        //更新PWM.


                if(++cnt >= 4)                //8ms一个周期, 演示如何关闭 开启PWM.
                {
                        cnt = 0;
                        UpdatePwm(PCA3, 256);        //输出占空比1/4的PWM, 时间为2ms.
                }
                else if(cnt == 1)        PwmOutContinue(PCA3, 0);        //连续输出低电平0, 时间为2ms.
                else if(cnt == 2)        UpdatePwm(PCA3,768);                //输出占空比3/4的PWM, 时间为2ms.
                else if(cnt == 3)        PwmOutContinue(PCA3, 1);        //连续输出高电平1, 时间为2ms.
        }
}

//========================================================================
// 函数: voiddelay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
voiddelay_ms(u8 ms)
{
        u16 i;
        do
        {
                i = MAIN_Fosc / 10000;
                while(--i)        ;
        }while(--ms);
}



//========================================================================
// 函数: void        PCA_config(u8 clk, u8 wide)
// 描述: PCA配置函数。
// 参数:clk: 选择时钟, 0: 12T,1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T,5: 4T,6: 6T,7: 8T
//               wide: pwm的宽度, 0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
void        PCA_config(u8 clk, u8 wide)
{
        P_SW2 |= 0x80;
        CR = 0;
        CH = 0;
        CL = 0;

        CMOD = (CMOD & ~0x0E) | ((clk & 7) << 1);                // PCA时钟选择, 0: 12T,1: 2T, 2: Timer0溢出率, 3: ECI引脚输入, 4: 1T,5: 4T,6: 6T,7: 8T

        PCA0_PWM(wide);        //PWM宽度        0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM
        PCA1_PWM(wide);        //PWM宽度        0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM
        PCA2_PWM(wide);        //PWM宽度        0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM
        PCA3_PWM(wide);        //PWM宽度        0: 8位PWM,1: 7位PWM,2: 6位PWM,3: 10位位PWM

        PWM0_OUT_0();        //初始输出0
        PWM1_OUT_0();        //初始输出0
        PWM2_OUT_0();        //初始输出0
        PWM3_OUT_0();        //初始输出0

//        PPCA = 1;        //高优先级中断
//        CMOD |= 0x01;        //允许PCA计数器溢出中断

        CR = 1;
}



//========================================================================
// 函数: void PwmOutContinue(u8 ch, u8 level)
// 描述: 设置PWM连续输出电平(高或低).
// 参数:    ch: PCA序号, 0~3对应 PCA0 ~ PCA3
//               level: 连续输出的电平,0为低电平, 1为高电平.
// 返回: none.
// 版本: V1.0, 2018-5-10
//========================================================================
void        PwmOutContinue(u8 ch, u8 level)
{
        if(ch == 0)
        {
                if(level == 0)        PWM0_OUT_0();
                else                        PWM0_OUT_1();
        }
        else if(ch == 1)
        {
                if(level == 0)        PWM1_OUT_0();
                else                        PWM1_OUT_1();
        }
        else if(ch == 2)
        {
                if(level == 0)        PWM2_OUT_0();
                else                        PWM2_OUT_1();
        }
        else if(ch == 3)
        {
                if(level == 0)        PWM3_OUT_0();
                else                        PWM3_OUT_1();
        }
}

//========================================================================
// 函数: void UpdatePwm(u8 ch, u16 pwm_value)
// 描述: 更新PWM值.
// 参数:      ch: PCA序号, 0~3对应 PCA0 ~ PCA3
//               pwm_value: pwm值, 这个值是输出低电平的时间.
// 返回: none.
// 版本: V1.0, 2018-5-10
//========================================================================
void        UpdatePwm(u8 ch, u16 pwm_value)
{
        if(ch == 0)
        {
                PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
                CCAP0H = (u8)pwm_value;
        //        PWM0_NORMAL();
        }
        else if(ch == 1)
        {
                PCA_PWM1 = (PCA_PWM1 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
                CCAP1H = (u8)pwm_value;
        //        PWM1_NORMAL();
        }
        else if(ch == 2)
        {
                PCA_PWM2 = (PCA_PWM2 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
                CCAP2H = (u8)pwm_value;
        //        PWM2_NORMAL();
        }
        else if(ch == 3)
        {
                PCA_PWM3 = (PCA_PWM3 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
                CCAP3H = (u8)pwm_value;
        //        PWM3_NORMAL();
        }
}

chenczyaa 发表于 2024-7-4 15:37

coody 发表于 2024-7-4 15:25
测试了下,没有问题,4路PWM输出正常。

#define MAIN_Fosc                24000000UL        //定义主时钟


收到,谢谢。我试下
页: [1]
查看完整版本: 请教一下STC12H1K输出PWM的问题