定义
PWM(Pulse Width Modulation),脉冲宽度调制。
脉冲:方波,频率(freq)
宽度:高电平的宽度,占空比(duty)
PWM的模式分为1和2
PWM1:TIMx_CNT<TIMx_CCR1,通道1便为有效状态,否则为无效状态
PWM2:TIMx_CNT<TIMx_CCR1,通道1便为无效状态,否则为有效状态
TIMx_CNT由TIM_TimeBaseStructure.TIM_Period决定
TIMx_CCR1由TIM_SetComparex(x:1、2、3、4)函数决定
有效状态由TIM_OCInitStructure.TIM_OCPolarity决定
其中频率值由计数值决定,占空比由比较值决定
例
#include "stm32f4xx.h"
#include "sys.h"
static GPIO_InitTypeDef GPIO_InitStructe;
static USART_InitTypeDef USART_InitStructe;
static NVIC_InitTypeDef NVIC_InitStructe;
static TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructe;
//串口初始化
void usart_init(uint32_t baud)
{
//使端口A通电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//使串口1通电
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//配置引脚9、10为复用功能
GPIO_InitStructe.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructe.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructe.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructe.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructe.GPIO_PuPd = GPIO_PuPd_UP;//上拉电阻,串口空闲位为高电平
GPIO_Init(GPIOA,&GPIO_InitStructe);
//将引脚9、10链接到串口1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
//串口参数初始化:设置波特率,字长,奇偶校验等参数
USART_InitStructe.USART_BaudRate = baud;//设置波特率
USART_InitStructe.USART_WordLength = USART_WordLength_8b;//设置数据位
USART_InitStructe.USART_StopBits = USART_StopBits_1;//设置停止位
USART_InitStructe.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制
USART_InitStructe.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//设置收发模式
USART_Init(USART1,&USART_InitStructe);
//设置串口的中断模式
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启中断,接受到数据时产生中断
//设置串口1的优先级
NVIC_InitStructe.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority =0;//抢占优先级
NVIC_InitStructe.NVIC_IRQChannelSubPriority = 0;//响应优先级
NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;//使能串口1
NVIC_Init(&NVIC_InitStructe);
//使串口1工作
USART_Cmd(USART1,ENABLE);
}
//定时器1初始化
void tim1_init(void)
{
//使TIM1通电
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//【重点】设置定时器1的计数值,决定它的定时时间
//定时器1的时钟频率=84MHz/8400=10000Hz
//分频就是降低频率
TIM_TimeBaseInitStructe.TIM_Period=(10000/100)-1;//定时为100ms
TIM_TimeBaseInitStructe.TIM_Prescaler = 8400-1;//设置预分频值8400,第一次分频
TIM_TimeBaseInitStructe.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructe);
//设置TIM1的触发方式:时间更新中断
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
//设置TIM1的优先级
NVIC_InitStructe.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;//中断信号1
NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructe.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructe);
//使定时器1工作
TIM_Cmd(TIM1,ENABLE);
}
//定时器2初始化
void tim2_init(void)
{
//使TIM2通电
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//【重点】设置定时器2的计数值,决定它的定时时间
//定时器2的时钟频率=84MHz/8400=10000Hz
//分频就是降低频率
TIM_TimeBaseInitStructe.TIM_Period=(10000/50)-1;//定时为200ms
TIM_TimeBaseInitStructe.TIM_Prescaler = 8400-1;//设置预分频值8400,第一次分频
TIM_TimeBaseInitStructe.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructe);
//设置TIM2的触发方式:时间更新中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//设置TIM2的优先级
NVIC_InitStructe.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructe.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructe);
//使定时器2工作
TIM_Cmd(TIM2,ENABLE);
}
void tim3_init(void)
{
//使TIM3通电
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
//【重点】设置定时器3的计数值,决定它的定时时间
//定时器3的时钟频率=84MHz/8400=10000Hz
//分频就是降低频率
TIM_TimeBaseInitStructe.TIM_Period=(10000/2)-1;//定时为500ms
TIM_TimeBaseInitStructe.TIM_Prescaler = 8400-1;//设置预分频值8400,第一次分频
TIM_TimeBaseInitStructe.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructe);
//设置TIM3的触发方式:时间更新中断
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
//设置TIM3的优先级
NVIC_InitStructe.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructe.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructe);
//使定时器3工作
TIM_Cmd(TIM3,ENABLE);
}
//定时器8初始化
void tim8_init(void)
{
//使TIM8通电
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);
//【重点】设置定时器8的计数值,决定它的定时时间
//定时器8的时钟频率=84MHz/8400=10000Hz
//分频就是降低频率
TIM_TimeBaseInitStructe.TIM_Period=(10000*2)-1;//设置计数值为9999,定时为2s
TIM_TimeBaseInitStructe.TIM_Prescaler = 8400-1;//设置预分频值8400,第一次分频
TIM_TimeBaseInitStructe.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM8,&TIM_TimeBaseInitStructe);
//设置TIM8的触发方式:时间更新中断
TIM_ITConfig(TIM8,TIM_IT_Update,ENABLE);
//设置TIM8的优先级
NVIC_InitStructe.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;//中断信号1
NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructe.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructe.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructe);
//使定时器1工作
TIM_Cmd(TIM8,ENABLE);
}
int main(void)
{
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF
|RCC_AHB1Periph_GPIOE
,ENABLE);
GPIO_InitStructe.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructe.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructe.GPIO_OType =GPIO_OType_PP;
GPIO_InitStructe.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructe.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF,&GPIO_InitStructe);
GPIO_InitStructe.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
GPIO_Init(GPIOE,&GPIO_InitStructe);
GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14);
//串口1工作波特率为115200bps
usart_init(115200);
//初始化定时器1
tim1_init();
//初始化定时器2
tim2_init();
//初始化定时器3
tim3_init();
//初始化定时器3
tim8_init();
while(1)
{
}
}
void TIM1_UP_TIM10_IRQHandler(void)
{
if((TIM_GetITStatus(TIM1,TIM_IT_Update)) ==SET)
{
PFout(9) ^=1;
//清空标志位
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}
}
void TIM2_IRQHandler(void)
{
if((TIM_GetITStatus(TIM2,TIM_IT_Update)) ==SET)
{
PFout(10) ^=1;
//清空标志位
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
void TIM3_IRQHandler(void)
{
if((TIM_GetITStatus(TIM3,TIM_IT_Update)) ==SET)
{
PEout(13) ^=1;
//清空标志位
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
void TIM8_UP_TIM13_IRQHandler(void)
{
if((TIM_GetITStatus(TIM8,TIM_IT_Update)) ==SET)
{
PEout(14) ^=1;
//清空标志位
TIM_ClearITPendingBit(TIM8,TIM_IT_Update);
}
}