STM8学习笔记---定时器输出7路PWM波

STM8S003F3P6单片机共有三个定时器定时器1、定时器2、定时器4。其中定时器1为16位高级定时器,定时器2为16位通用定时器,定时器4为8位基本定时器。定时器1和定时器2可以输出PWM波。其中定时器1有4个通道,定时器2有3个通道。
现在让定时器1和定时器2所有通道同时输出PWM波。
首先初始化定时器IO口
在这里插入图片描述
通过最小系统图可以看出定时器通道对应的IO口为:
TIM1_CH1–>PC6,
TIM1_CH2–>PC7,
TIM1_CH3–>PC3,
TIM1_CH4–>PC4,
TIM2_CH1–>PC5,
TIM2_CH2–>PD3,
TIM2_CH3–>PA3,
将定时器对应的IO口都设置为推挽输出模式。因为要输出PWM波,IO口必须要有输出高低电平的能力。所以设置为推挽输出。
IO口初始化代码如下:

void PWM_GPIO_Init( void )
{
    PC_DDR |= ( 1 << 6 );  //PC6 推挽输出
    PC_CR1 |= ( 1 << 6 );
	
    PC_DDR |= ( 1 << 7 );  //PC7 推挽输出
    PC_CR1 |= ( 1 << 7 );
	
    PC_DDR |= ( 1 << 3 );  //PC3 推挽输出
    PC_CR1 |= ( 1 << 3 );
	
    PC_DDR |= ( 1 << 4 );  //PC4 推挽输出
    PC_CR1 |= ( 1 << 4 );
	
    PC_DDR |= ( 1 << 5 );  //PC5 推挽输出
    PC_CR1 |= ( 1 << 5 );
	
    PD_DDR |= ( 1 << 3 );  //PD3 推挽输出
    PD_CR1 |= ( 1 << 3 );
	
    PA_DDR |= ( 1 << 4 );  //PA3 推挽输出
    PA_CR1 |= ( 1 << 4 );
}

将定时器相关IO口都设置为推挽输出。
下来初始化定时器1

//定时器1初始化
void TIM1_Init( void )
{
    PWM_GPIO_Init();
    TIM1_CCMR1 = 0x60;        //TIM1 CH1 输出模式 PWM1
    TIM1_CCER1 |= 0x01;        //CC1为输出
	
    TIM1_CCMR2 = 0x60;        //TIM1 CH2 输出模式 PWM1
    TIM1_CCER1 |= 0x10;        //CC2为输出
	
    TIM1_CCMR3 = 0x60;        //TIM1 CH3 输出模式 PWM1
    TIM1_CCER2 |= 0x01;        //CC3为输出
	
    TIM1_CCMR4 = 0x60;        //TIM1 CH4 输出模式 PWM1
    TIM1_CCER2 |= 0x10;        //CC4为输出
	
	
    TIM1_PSCRH = 0x00;
    TIM1_PSCRL = 0x00;        //16M/(1+0)=16 1分频 16M
    TIM1_ARRH = FRE >> 8;     //设定自动重装载值高8位
    TIM1_ARRL = FRE;          //设置自动重装载值低8位
    TIM1_BKR = 0x80;      //刹车寄存器 使能OC1输出 定时器不工作时输出无效电平
    TIM1_CR1 |= 0x01;         //允许定时器中断
}

将定时器1的4个通道都设置为PWM1模式
在这里插入图片描述
当计数器的值小于比较寄存器的值时输出为有效电平,否则输出为无效电平。假如设置1为有效电平,那么0就是无效电平。如果设置0为有效电平,那么1就是无效电平。电平有效位设置是在CCER寄存器中。
在这里插入图片描述
CC1P是设置通道1的有效电平,CC1NP是设置通道1的互补通道有效电平。寄存器复位值为0,也就是默认高电平有效。此处用默认值就可以。
CC1E是开启通道输出PWM波功能,我们要输出PWM波就必须打开此功能。CC1E是设置打开通道1PWM输出功能,CC1NE是设置打开通道1互补输出功能。互补功能在此例程中用不到不需要打开。只需打开4个通道的PWM输出功能就可以了。

    TIM1_CCMR1 = 0x60;        //TIM1 CH1 输出模式 PWM1
    TIM1_CCER1 |= 0x01;        //CC1为输出
	
    TIM1_CCMR2 = 0x60;        //TIM1 CH2 输出模式 PWM1
    TIM1_CCER1 |= 0x10;        //CC2为输出
	
    TIM1_CCMR3 = 0x60;        //TIM1 CH3 输出模式 PWM1
    TIM1_CCER2 |= 0x01;        //CC3为输出
	
    TIM1_CCMR4 = 0x60;        //TIM1 CH4 输出模式 PWM1
    TIM1_CCER2 |= 0x10;        //CC4为输出

这几行代码就是设置TIM1的4个通道输出模式为PWM1模式,然后分别打开各个通道的输出功能。
下来设置定时器的自动装载值和预分频值

 	TIM1_PSCRH = 0x00;
    TIM1_PSCRL = 0x00;        //16M/(1+0)=16 1分频 16M
    TIM1_ARRH = FRE >> 8;     //设定自动重装载值高8位
    TIM1_ARRL = FRE;          //设置自动重装载值低8位

设置预分频值为0,也就是不分频,使用系统时钟,系统时钟为内部16M晶振。所以定时器1的时钟频率为16MHz,下来设置自动装载值,也就是设置PWM的输出频率。为了方便修改频率值,这块设置了一个宏定义。

#define  FRE   200          //frequency  频率

FRE的值定义为200,时钟频率是16MHz,自动装载值为200,那么PWM的输出频率就为16MHz / 200 = 80KHz。所以定时器1通道的输出频率就为80KHz,由于一个定时器只有一个自动重装载寄存器,所以每个定时器的所有通道输出频率都是一样的。也就是说定时器1的通道1到通道4的输出频率都为80KHz。
设置好频率之后,使能定时器就可以了。定时器1是高级定时器,所以设置控制寄存器CR1使能计时器输出之后,还必须设置一下刹车寄存器,在刹车寄存器中开启主输出使能。
在这里插入图片描述
定时器开启后,下来就可以输出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;
}
//TIM1 CH3  PC3
void TIM1_CH3_OUT( unsigned int DC )
{
    TIM1_CCR3H = DC >> 8;
    TIM1_CCR3L = DC;
}
//TIM1 CH4  PC4
void TIM1_CH4_OUT( unsigned int DC )
{
    TIM1_CCR4H = DC >> 8;
    TIM1_CCR4L = DC;
}

通过4个函数单独设置通道1到通道4的占空比。
定时器1初始化完成之后,下来初始化定时器2,定时器2初始化方法和定时器1比较类似。唯一的区别就是,定时器2没有刹车寄存器,直接使能定时器输出就可以了。
定时器2初始化代码如下:

void TIM2_Init( void )
{
    TIM2_CCER1 |= 0x01;      //CC1输出
    TIM2_CCMR1 = 0x60;       //TIM2 CH1 输出模式PWM1
    
    TIM2_CCER1 |= 0x10;      //CC2输出
    TIM2_CCMR2 = 0x60;       //TIM2 CH2 输出模式PWM1
    
    TIM2_CCER2 |= 0x01;      //CC3输出
    TIM2_CCMR3 = 0x60;       //TIM2 CH3 输出模式PWM1
    
    TIM2_PSCR = 0x01;
    TIM2_ARRH = FRE >> 8;
    TIM2_ARRL = FRE;
    TIM2_CR1 |= 0x01;
}
//TIM2 CH1 PC5
void TIM2_CH1_OUT( unsigned int DC )
{
    TIM2_CCR1H = DC >> 8;
    TIM2_CCR1L = DC;
}
//TIM2 CH2 PD3
void TIM2_CH2_OUT( unsigned int DC )
{
    TIM2_CCR2H = DC >> 8;
    TIM2_CCR2L = DC;
}
//TIM2 CH3 PA3
void TIM2_CH3_OUT( unsigned int DC )
{
    TIM2_CCR3H = DC >> 8;
    TIM2_CCR3L = DC;
}

定时器2初始化完成之后,就可以在主函数中分别控制各个通道的占空比了。

#include "iostm8s103F3.h"
#include "led.h"
#include "pwm.h"

void SysClkInit( void )
{
    CLK_SWR = 0xe1;       //HSI为主时钟源  16MHz CPU时钟频率
    CLK_CKDIVR = 0x00;    //CPU时钟0分频,系统时钟0分频
}


void delay_ms( unsigned int ms )
{
    unsigned char i;
    while( ms != 0 )
    {
        for( i = 0; i < 250; i++ );
        for( i = 0; i < 75; i++ );
        ms--;
    }
}
void delay_us( unsigned int Tus )
{
    __asm( "nop" );
}
void main( void )
{
    SysClkInit();
    __asm( "sim" );                       //禁止中断
    LED_GPIO_Init();
    TIM1_Init();
    TIM2_Init();
    __asm( "rim" );                       //开启中断
    delay_ms( 500 );
    TIM1_CH1_OUT( 100 );
    TIM1_CH2_OUT( 100 );
    TIM1_CH3_OUT( 100 );
    TIM1_CH4_OUT( 100 );
    TIM2_CH1_OUT( 100 );
    TIM2_CH2_OUT( 100 );
    TIM2_CH3_OUT( 100 );
    while( 1 )
    {
        LED = 0;                       
        delay_ms(500);
            LED = 1;
        delay_ms(500); 
    }
}

定时器1和定时器2的频率可以设置不一样,但是定时器每个通道的频率不能单独设置。也就是说定时1的4个通道是一个频率,定时器2的3个通道是一个频率。每个通道的占空比可以独立控制。
在烧写程序的时候要注意一个问题:STM8单片机有些引脚默认功能不是定时器功能,需要通过设置选项字,将定时器功能打开。选项字可以在程序中通过代码设置,也可以在烧写软件上设置。一般在烧写软件上设置比较简单。
首先打开烧写软件 在这里插入图片描述

点击左上角第二个文件夹的按钮打开要烧写的文件,然后点右下方OPTION BYTE 选项字设置选项。
在这里插入图片描述
AFR7-----AFR0 就是设置每个引脚的默认功能,此处需要设置AFR0,也就是PC5引脚。
在这里插入图片描述
可以看到PC5、PC6、PC7引脚默认功能是SPI,而我们需要将这三个脚设置为定时器功能。
在这里插入图片描述
用鼠标在PC5那一行字上点一下,然后最右边会出现一个黑色小三角,然后用鼠标点一下黑色小三角。
在这里插入图片描述
这时就会出现一个下拉框,在下拉框中选择最下面一项。
在这里插入图片描述
选择好之后就可以看到PC5的默认功能为定时器2通道1,PC6的默认功能为定时器1通道1,PC7的功能为定时器1通道2。也就是说这个选项一次设置的是3个IO口的默认功能,当选择一个一个IO口的功能后,其他两个默认IO口功能都会改变。
设置好IO口默认功能后,点下载按钮下载程序就可以了。
在这里插入图片描述
下载按钮是第二个,红色向下箭头的图标。这样单片机就可以同时输出7路PWM波了。如果单片机某些引脚没有输出波形,可能是定时器的功能未开启,就要检查烧写软件上的选项字设置是否正确了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值