STM8S003F3有三个定时器,分别为16位高级定时器TIM1、16位通用定时器TIM2和8位基础定时器TIM4。其中,TIM1和TIM2支持PWM输出,本项目中用到了TIM1-CH1和TIM2-CH1两个通道作为PWM输出,以及TIM4作为时基,下面进入正文。
编译环境:IAR for STM8 3.10.2
库版本:V2.2.0
关于定时器没什么好说的,直接看下配置代码
void TIM1_Init(u16 psc, u16 arr, u16 duty)
{
TIM1_TimeBaseInit(psc, TIM1_COUNTERMODE_UP, arr, 0);
TIM1_OC1Init(TIM1_OCMODE_PWM1, \
TIM1_OUTPUTSTATE_ENABLE, \
TIM1_OUTPUTNSTATE_ENABLE,\
duty, \
TIM1_OCPOLARITY_LOW, \
TIM1_OCNPOLARITY_HIGH, \
TIM1_OCIDLESTATE_SET, \
TIM1_OCNIDLESTATE_RESET);
TIM1_CCxCmd(TIM1_CHANNEL_1, ENABLE);
TIM1_OC1PreloadConfig(ENABLE);
TIM1_CtrlPWMOutputs(ENABLE);
TIM1_Cmd(ENABLE);
}
void TIM2_Init(TIM2_Prescaler_TypeDef TIM2_Prescaler, u16 arr, u16 duty)
{
TIM2_TimeBaseInit(TIM2_Prescaler, arr);
TIM2_OC1Init(TIM2_OCMODE_PWM1, \
TIM2_OUTPUTSTATE_ENABLE,\
duty, \
TIM2_OCPOLARITY_HIGH); \
TIM2_OC1PreloadConfig(ENABLE);
TIM2_Cmd(ENABLE);
}
其中TIM2_Prescaler_TypeDef定义为:
typedef enum
{
TIM2_PRESCALER_1 = ((uint8_t)0x00),
TIM2_PRESCALER_2 = ((uint8_t)0x01),
TIM2_PRESCALER_4 = ((uint8_t)0x02),
TIM2_PRESCALER_8 = ((uint8_t)0x03),
TIM2_PRESCALER_16 = ((uint8_t)0x04),
TIM2_PRESCALER_32 = ((uint8_t)0x05),
TIM2_PRESCALER_64 = ((uint8_t)0x06),
TIM2_PRESCALER_128 = ((uint8_t)0x07),
TIM2_PRESCALER_256 = ((uint8_t)0x08),
TIM2_PRESCALER_512 = ((uint8_t)0x09),
TIM2_PRESCALER_1024 = ((uint8_t)0x0A),
TIM2_PRESCALER_2048 = ((uint8_t)0x0B),
TIM2_PRESCALER_4096 = ((uint8_t)0x0C),
TIM2_PRESCALER_8192 = ((uint8_t)0x0D),
TIM2_PRESCALER_16384 = ((uint8_t)0x0E),
TIM2_PRESCALER_32768 = ((uint8_t)0x0F)
}TIM2_Prescaler_TypeDef;
void TIM4_Init(TIM4_Prescaler_TypeDef TIM4_Prescaler, u8 arr)
{
TIM4_DeInit();
TIM4_TimeBaseInit(TIM4_Prescaler, arr);
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
TIM4_Cmd(ENABLE);
}
其中TIM4_Prescaler_TypeDef定义为:
typedef enum
{
TIM4_PRESCALER_1 = ((uint8_t)0x00),
TIM4_PRESCALER_2 = ((uint8_t)0x01),
TIM4_PRESCALER_4 = ((uint8_t)0x02),
TIM4_PRESCALER_8 = ((uint8_t)0x03),
TIM4_PRESCALER_16 = ((uint8_t)0x04),
TIM4_PRESCALER_32 = ((uint8_t)0x05),
TIM4_PRESCALER_64 = ((uint8_t)0x06),
TIM4_PRESCALER_128 = ((uint8_t)0x07)
} TIM4_Prescaler_TypeDef;
高级定时器之所以高级是有原因的,更多的参数使功能更强大,当然这也不是绝对的,在项目开发中,有时候逻辑简化能使参数归一,但是并不影响实际功能。这里的参数一个是开放给开发者,一个是用户,并没有太大可比性,只是说明一种观点。
PWM1和PWM2两种模式的区别
TIM_OCMode_PWM1:
TIM_OCMode_PWM2:
------------------------------------------------------------我是分隔线-----------------------------------------------------------------
下面划重点
下面划重点
下面划重点
当一切准备就绪后,却发现PWM怎么都无法输出,折腾了好久,后来只好回归手册,在引脚说明表中对引脚说明如下:
很明显,这两个IO要作为PWM输出需要复用,但是复用方法很特殊,需要修改对应option bit,这里需要修改AFR0位才能输出PWM。那么现在的问题就是如何配置AFR0这个位了。
网上查找了相关问题后,这里做一下总结。
AFR0等选项组成Option-Bytes,那么如何配置Option-Bytes,这里总结三种方法。
#define OPTION_BYTES_ADDR 0x4803
void Set_OptionByte(void)
{
u16 Option_Bytes;
Option_Bytes = FLASH_ReadOptionByte(OPTION_BYTES_ADDR);
if(Option_Bytes & 0x01 == 0)
{
FLASH_ProgramOptionByte(OPTION_BYTES_ADDR, (u8)Option_Bytes | 0x01);
}
}