zhang1314hong 发表于 2024-11-15 17:31:46

本帖最后由 zhang1314hong 于 2024-11-15 17:37 编辑

这是修改梁工的程序,不解的是 我修改#define      delay               90 显示正常 ,但是我想延时时间短一些,就改成#define      delay               48,就不正常了波形,不知道什么原因,下面有图,请帮忙修改谢谢。
用的是打狗棒   用的io是P20 P22 P24 P26


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

#include"STC8Hxxx.h"



u8      PWMA_ISR_En;      //每个通道可以单独允许中断处理, bit4:通道4, bit3:通道3, bit2:通道2, bit1:通道1, bit0:更新中断.

#define      PWMA_DUTY                1200                        //周期
#define      PWMA_PHASE2               (PWMA_DUTY/2)      //通道2相位差
#define      delay               48      


u16                pwma1;                //PWMA1输出高电平时间
u16                pwma2;                //PWMA2输出高电平时间
bit                B_OutState1;      //中断使用, 用户层不可见.
bit                B_OutState2;      //中断使用, 用户层不可见.
bit                B_OutState3;      //中断使用, 用户层不可见.


void PWMA_config(void);


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

      P_SW2= 0x80;
    P1M0 = 0x00; P1M1 = 0x01;
      P2M0 = 0xff; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;

      pwma1 = 440;      //通道1占空比
      PWMA_config();
      EA = 1;

      while (1)
      {

               
      }
}

void PWMA_config(void)
{
      u8      ccer1;
      u8      ccer2;
      u8      ps;
      u8      eno;

      P_SW2 |= 0x80;                //SFR enable   
      PWMA_ENO    = 0;      // IO输出禁止
      PWMA_IER    = 0;      // 禁止中断
      PWMA_SR1    = 0;      // 清除状态
      PWMA_SR2    = 0;      // 清除状态
      PWMA_CR1    = 0;      // 清除控制寄存器
      PWMA_CR2    = 0;      // 清除控制寄存器
      ccer1 = 0;
      ccer2 = 0;
      ps    = 0;
      eno   = 0;
      PWMA_ISR_En = 0;

      PWMA_PSCR = 0;      // 预分频寄存器, PWM时钟 = 12MHz/(11+1)=1MHz, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
      PWMA_DTR= 0;      // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
                                                //                              0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
      PWMA_ARR   = PWMA_DUTY-1;      // 自动重装载寄存器,控制PWM周期
      PWMA_ISR_En |= 0x01;                // 使能更新中断

      PWMA_CCMR1 = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
      PWMA_CCR1= pwma1;                // 比较值, 控制占空比(高电平时钟数)
      ccer1 |= 0x05;                        // 开启比较输出, 高电平有效
      ps    |= 1;                              // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
      eno   |= 0x03;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
//      PWMA_ISR_En |= 0x02;      // 使能中断

      PWMA_CCMR2 = 0x40;                // 强制输出低
      PWMA_CCR2= pwma1;      // 匹配值
      ccer1 |= 0x50;                        // 开启比较输出, 高电平有效
      ps    |= (1<<2);                // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
      eno   |= 0x0C;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
      PWMA_ISR_En |= 0x04;      // 使能通道2匹配中断

      PWMA_CCMR2 = 0x40;                // 强制输出低
      PWMA_CCR3= PWMA_PHASE2;      // 匹配值
      ccer2 |= 0x05;                        // 开启比较输出, 高电平有效
      ps    |= (1<<4);                // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
      eno   |= 0x30;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
      PWMA_ISR_En |= 0x08;      // 使能通道3匹配中断

      PWMA_CCMR2 = 0x40;                // 强制输出低
      PWMA_CCR4= PWMA_PHASE2+pwma1;      // 匹配值
      ccer2 |= 0x50;                        // 开启比较输出, 高电平有效
      ps    |= (1<<6);                // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
      eno   |= 0xC0;                        // IO输出允许,bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,bit3: ENO2N,bit2: ENO2P,bit1: ENO1N,bit0: ENO1P
      PWMA_ISR_En |= 0x10;      // 使能通道4匹配中断


      PWMA_CCER1= ccer1;      // 捕获/比较使能寄存器1
      PWMA_CCER2= ccer2;      // 捕获/比较使能寄存器2
      PWMA_PS   = ps;                // 选择IO
      PWMA_IER    = PWMA_ISR_En;      //设置允许通道1~4中断处理

      PWMA_BKR    = 0x80;                // 主输出使能 相当于总开关
      PWMA_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
      PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
      PWMA_ENO    = eno;                // 允许IO输出
}

void PWMA_ISR(void) interrupt PWMA_VECTOR
{
      u8      sr1;
      sr1 = PWMA_SR1;      //为了快速, 中断标志用一个局部变量处理
      PWMA_SR1 = 0;      //清除中断标志
      
      PWMA_SR2 = 0;      //清除中断标志
      sr1 &= PWMA_ISR_En;      //每个通道可以单独允许中断处理
      if(sr1 & 0x01)      //更新中断标志
      {
                PWMA_CCR1= pwma1;      // 匹配值
               
                PWMA_CCR2= pwma1;      // 匹配值
               
                PWMA_CCR3= PWMA_PHASE2;      // 匹配值
                PWMA_CCR4= PWMA_PHASE2+pwma1;      // 匹配值
               
                PWMA_CCMR2 = 0x70;                        // 通道模式配置, PWM模式2, 禁止预装载, 匹配时输出高
                PWMA_CCMR3 = 0x70;      
                PWMA_CCMR4 = 0x70;      
                B_OutState1 = 0;
                B_OutState2 = 0;
                B_OutState3 = 0;
      }

      if(sr1 & 0x04)      //通道2匹配中断标志
      {
                if(!B_OutState1)
                {
                        B_OutState1 = 1;
                        PWMA_CCMR2= 0x50;                // 通道模式配置, 强制为有效电平
                        PWMA_CCR2   = pwma1 +delay;          // 匹配值, PWM6在400时刻输出低电平
                        PWMA_CCMR2= 0x60;                // 通道模式配置, PWM模式1, 匹配时输出低电平
                }
                else      PWMA_CCMR2= 0x40;      // 通道模式配置, 强制为无效电平
      }
      if(sr1 & 0x08)      //通道3匹配中断标志
      {
                if(!B_OutState2)
                {
                        B_OutState2 = 1;
                        PWMA_CCMR3= 0x50;                // 通道模式配置, 强制为有效电平
                        PWMA_CCR3   = PWMA_PHASE2+pwma1;          // 匹配值, PWM6在400时刻输出低电平
                        PWMA_CCMR3= 0x60;                // 通道模式配置, PWM模式1, 匹配时输出低电平
                }
                else      PWMA_CCMR3= 0x40;      // 通道模式配置, 强制为无效电平
      }
      if(sr1 & 0x10)      //通道4匹配中断标志
      {
                if(!B_OutState3)
                {
                        B_OutState3 = 1;
                        PWMA_CCMR4= 0x50;                // 通道模式配置, 强制为有效电平
                        PWMA_CCR4   = PWMA_PHASE2+pwma1 + delay;          // 匹配值, PWM6在400时刻输出低电平
                        PWMA_CCMR4= 0x60;                // 通道模式配置, PWM模式1, 匹配时输出低电平
                }
                else      PWMA_CCMR4= 0x40;      // 通道模式配置, 强制为无效电平
      }
}







梁工 发表于 2024-11-15 21:24:07

zhang1314hong 发表于 2024-11-15 17:31
这是修改梁工的程序,不解的是 我修改#define      delay               90 显示正常 ,但是我想延时时 ...

这种波形使用STC8G2K64S4产生很容易。

zhang1314hong 发表于 2024-11-16 13:29:47

梁工 发表于 2024-11-15 21:24
这种波形使用STC8G2K64S4产生很容易。

谢谢梁工,我之前在Stc8a8k64d4实现过,用的15位增强型pwm,但是我想找一个引脚少的,16或者20引脚的,一个adc引脚,就够了,发现就需要使用16位pwm,用的stc8h系列,我想通过检测外部的电压,控制波形的占空比,用在半桥驱动上

页: 1 [2]
查看完整版本: 在互补pwm输出的下降沿产生一个短脉冲问题