STM8S003F3使用总结——定时器

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

1.定时器

关于定时器没什么好说的,直接看下配置代码

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:

  • 当计时器值小于比较器设定值时则TIMX输出脚此时输出有效高电位。
  • 当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出低电位。

TIM_OCMode_PWM2:

  • 当计时器值小于比较器设定值时则TIMX输出脚此时输出有效低电位。
  • 当计时器值大于或等于比较器设定值时则TIMX输出脚此时输出高电位。

------------------------------------------------------------我是分隔线-----------------------------------------------------------------

下面划重点
下面划重点
下面划重点

当一切准备就绪后,却发现PWM怎么都无法输出,折腾了好久,后来只好回归手册,在引脚说明表中对引脚说明如下:
STM8S003F3使用总结——定时器_第1张图片
很明显,这两个IO要作为PWM输出需要复用,但是复用方法很特殊,需要修改对应option bit,这里需要修改AFR0位才能输出PWM。那么现在的问题就是如何配置AFR0这个位了。

2.Option-Bytes配置

网上查找了相关问题后,这里做一下总结。
AFR0等选项组成Option-Bytes,那么如何配置Option-Bytes,这里总结三种方法。

  1. 基于IAR
    点击顶部菜单栏ST-LINK–>Option Bytes…
    STM8S003F3使用总结——定时器_第2张图片
    打开Option Bytes选项框,右键置位Alternate Active
    STM8S003F3使用总结——定时器_第3张图片

  2. 基于STVP
    如图所示,点击底部切换到OPTION BYTE界面,选择对应配置字即可。
    STM8S003F3使用总结——定时器_第4张图片

  3. 基于程序代码
    选项字节在片内地址如下:
    STM8S003F3使用总结——定时器_第5张图片STM8S003F3使用总结——定时器_第6张图片
    从表中可见,需要将OPT2的最低位AFR0置1,代码如下:

#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);
	}
}

你可能感兴趣的:(单片机)