STM8学习笔记---PWM互补波形输出

1,531 阅读3分钟

       脉宽调制(PWM,Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

      常见的用法是输出一路PWM波,可以通过调节PWM的频率和占空比来控制电路。还有另一种方法是输出一组互补的PWM波,这两个波形频率相同,相位相反,两组波形之间有死区控制时间。

     STM8单片机自带PWM互补波形输出功能,通过资料可以看出 STM8共有3个死区时间可调的互补输出。

    本次实验用的STMs8003单片机有2个互补输出。

PC6口和PC3口是定时器1通道1互补输出。PC7口和PC4口是定时器1通道2互补输出。

要配置输出互补PWM波,只需要在输出PWM的基础上,开启互补输出功能就行。

只需要在CCER寄存器中开启CCxNE寄存器,就能开启互补输出功能。

如果需要设置死区时间,还需要配置DTR寄存器。

 

 

下来看一下程序中如何配置

void PWM_GPIO_Init( void )
{
    PC_DDR |= ( 1 << 6 );  //PC6 推挽输出
    PC_CR1 |= ( 1 << 6 );
    
    PC_DDR |= ( 1 << 3 );  //PC3 推挽输出
    PC_CR1 |= ( 1 << 3 );
    
    PC_DDR |= ( 1 << 7 );  //PC7 推挽输出
    PC_CR1 |= ( 1 << 7 );
    
    PC_DDR |= ( 1 << 4 );  //PC4 推挽输出
    PC_CR1 |= ( 1 << 4 );
}

设置 IO口,将IO口设置为推挽输出。

下来初始化定时器

#define  FRE   320 
//定时器1初始化
void TIM1_Init( void )
{
    PWM_GPIO_Init();
    TIM1_CR1 = (1<<7);                        //自动预装载允许
    //设置TIM1 CH1 与 TIM1 CH1N通道
    TIM1_CCMR1 = (6<<4)|(1<<3)|(1<<2);        //TIM1 CH1 PWM1  输出比较1预装载使能  输出比较1 快速使能
    //TIM1_CCER1 |= 0x01;                       //CC1为输出 高电平有效
    TIM1_CCER1 |= (1<<0)|(1<<2);              //CC1为输出 OC1高电平有效 开启OC1N OC1N高电平有效 
    
    //设置TIM1 CH2 与 TIM1 CH2N通道
    TIM1_CCMR2 =(6<<4)|(1<<3)|(1<<2);        //TIM1 CH2 输出模式 PWM1 输出比较2预装载使能  输出比较2 快速使能
    //TIM1_CCER1 |= (1<<4);                   //CC2为输出   关闭互补输出
    TIM1_CCER1 |= (1<<4)|(1<<6);             //CC2为输出   互补输出使能
    
    TIM1_PSCRH = 0x00;                        //预分频 0 
    TIM1_PSCRL = 0x00;                        //16M
    
    TIM1_ARRH = FRE >> 8;                     //设定自动重装载值高8位
    TIM1_ARRL = FRE;                          //设置自动重装载值低8位
  
    //TIM1_BKR |= (1<<7)|(1<<4);                 //刹车寄存器 使能OC1输出 定时器不工作时输出无效电平  开启刹车输入 刹车输入低电平有效
    TIM1_BKR |= (1<<7);                       //主输出使能  关闭刹车输入
    TIM1_DTR = 0x18;                          //死区时间 24*125ns=3000ns
    TIM1_EGR = (1<<0);                        //产生更新事件
    TIM1_CR1 |= 0x01;                           //使能计数器
}

定时器初始化完成后,用一个单独的函数来调节PWM的占空比。

//TIM1 CH1  PC6
void TIM1_CH1_OUT( unsigned int DC )
{
    TIM1_CCR1H = DC >> 8;   //捕获比较寄存器高8位
    TIM1_CCR1L = DC;        //捕获比较寄存器低8位 占空比值
}

//TIM1 CH2  PC7
void TIM1_CH2_OUT( unsigned int DC )
{
    TIM1_CCR2H = DC >> 8;
    TIM1_CCR2L = DC;
}

下来在主函数中调用占空比修改函数,就能设置占空比了。

void main( void )
{
    SysClkInit();
    __asm( "sim" );                       //禁止中断
    TIM1_Init();
    __asm( "rim" );                       //开启中断

    delay_ms( 500 );  
    TIM1_CH1_OUT(FRE/3);                  //设置占空比为33%
    TIM1_CH2_OUT(FRE/3);
    
    while( 1 )
    {
       
    }
}

主函数就比较简单了,初始化完定时器,然后设置输出占空比就可以了。

下来还有一个最重要的步骤,需要配置STM8的选项字。因为互补输出不是IO口的默认功能,要使用互补输出还需要将引脚功能手动设置为互补输出。

设置选项字比较简单的方法就是通过STVP软件设置,详细设置方法参见  如何设置STM8单片机选项字  这篇博客。

打开STVP软件,然后添加要烧写的HEX文件。

然后切换到 OPTION BYTE界面

AR7 ---- AR0就是设置IO口默认功能选项。

点一下AFR7后面选项那个倒三角符号

然后在出现的下拉框中选择 Port C3 Alternate Function = TIM1_CH1N,Port C4 Alternate Function = TIM1_CH2N选项。

这个选项的意思就是将PC3设置为定时器1通道1互补输出功能,将PC4设置为定时器1通道2互补输出功能。而默认选项的是将PC3设置为定时器1通道3,将PC4设置为定时器1通道4。

如果不设置选项字,刚才的程序烧写后,单片机的PC3和PC4引脚是没有任何波形输出的。

按照同样的方法设置AFR0选项,将PC6和PC7设置为定时器功能。

设置完成后如下图所示

只需要设置AFR7和AFR0两个选项就行,其他的为默认值。如果互补输出时用到了刹车功能,这里就还要设置一个AFR4选项。本次实验中没有用到刹车功能,所以就不需要设置AFR4。设置完成后烧写程序就行。

输出波形如下所示

可以看到两个波形是互补输出的,但是两个波形占空比相差比较大,这是因为为了方便观察,将死区时间设置的比较大,代码中的死区时间为3us。

在代码中将死区时间设置为250ns

再看下输出波形

死区时间设置比较小的时候,输出的波形,看起来基本对称了。

这时PWM的互补输出功能就成功实现了。