打印
[STC单片机]

请教一下STC12H1K输出PWM的问题

[复制链接]
2195|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenczyaa|  楼主 | 2024-7-3 14:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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输出正常。
STC12H系列-PCA相关程序.rar (45.8 KB)
#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.
        }
}

//========================================================================
// 函数: void  delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 版本: V1.0, 2016-5-10
// 备注:
//========================================================================
void  delay_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        //定义主时钟

收到,谢谢。我试下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

44

帖子

0

粉丝