1.实验器材:
STM32F103c8
2.实验目的:
学习定时器的PWM功能3.硬件资源:
DS0(连接在PB5) 定时器3(TIM3),使用TIM3的通道2(CH2),开启部分重映射,将TIM3_CH2输出到PB5. 从而实现PWM输出控制DS0亮度.
4.实验现象:
本实验,DS0由暗到亮,再由亮到暗,再由暗到亮,依次循环.
一、LED初始化
代码分析:
1.声明GPIO _Initure:
GPIO_InitTypeDef GPIO_Initure
2.初始化GPIOB、GPIOE的时钟:
__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();
3.对GPIOB和GPIOE进行配置
GPIO_Initure.Pin=GPIO_PIN_5; //PB5
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
4.调用GPIO初始化函数,进行初始化:
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
5.GPIOE也类似进行初始化,GPIOE和GPIOB的配置是一样的。
GPIO_Initure.Pin=GPIO_PIN_5; //PE5
HAL_GPIO_Init(GPIOE,&GPIO_Initure);
6.设置GPIOB和GPIOE的默认状态
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); //PB5置1,默认初始化后灯灭
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET); //PE5置1,默认初始化
LED_Init整体代码:
void LED_Init(void)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟__HAL_RCC_GPIOE_CLK_ENABLE(); //开启GPIOE时钟GPIO_Initure.Pin=GPIO_PIN_5; //PB5GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出GPIO_Initure.Pull=GPIO_PULLUP; //上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速HAL_GPIO_Init(GPIOB,&GPIO_Initure);GPIO_Initure.Pin=GPIO_PIN_5; //PE5HAL_GPIO_Init(GPIOE,&GPIO_Initure);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); //PB5置1,默认初始化后灯灭HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET); //PE5置1,默认初始化后灯灭
}
二、TIM3时钟初始化
1.配置定时器TIM3的句柄和TIM3通道2的句柄
TIM_HandleTypeDef TIM3_Handler; //定时器句柄
TIM_OC_InitTypeDef TIM3_CH2Handler; //定时器3通道2句柄
2.通用定时器3中断初始化函数
arr:自动装载值psc:时钟预分频数CounterMode:控制模式ClockDivsion分频模式
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Init(u16 arr,u16 psc)
{ TIM3_Handler.Instance=TIM3; //通用定时器3TIM3_Handler.Init.Prescaler=psc; //分频系数TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器TIM3_Handler.Init.Period=arr; //自动装载值TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子HAL_TIM_Base_Init(&TIM3_Handler);HAL_TIM_Base_Start_IT(&TIM3_Handler); //使能定时器3和定时器3更新中断:TIM_IT_UPDATE
}
3.PWM的部分初始化函数
1.配置TIM3的基本特性:Prescaler,CounterMode,Period,ClockDivision
2.调用PWM的初始化函数:HAL_TIM_PWM_Init()
2.PWM的模式OCMode为:TIM_OCMODE_PWM1
3.设置比较值 来确定占空比:TIM3_CH2Handler.Pulse=arr/2;
4.选择TIM3的通道2来作为PWM的产生。
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
void TIM3_PWM_Init(u16 arr,u16 psc)
{ TIM3_Handler.Instance=TIM3; //定时器3TIM3_Handler.Init.Prescaler=psc; //定时器分频TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式TIM3_Handler.Init.Period=arr; //自动重装载值TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;HAL_TIM_PWM_Init(&TIM3_Handler); //初始化PWMTIM3_CH2Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1TIM3_CH2Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%TIM3_CH2Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_2);//配置TIM3通道2HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_2);//开启PWM通道2}
4.定时器的底层驱动(时钟使能、引脚配置)
PS:该函数会被HAL_TIM_PWM_Init()调用
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{GPIO_InitTypeDef GPIO_Initure;if(htim->Instance==TIM3){__HAL_RCC_TIM3_CLK_ENABLE(); //使能定时器3__HAL_AFIO_REMAP_TIM3_PARTIAL(); //TIM3通道引脚部分重映射使能__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟GPIO_Initure.Pin=GPIO_PIN_5; //PB5GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出GPIO_Initure.Pull=GPIO_PULLUP; //上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速HAL_GPIO_Init(GPIOB,&GPIO_Initure); }
}
5.设置TIM3通道2的比较值
void TIM_SetTIM3Compare2(u32 pare)
{TIM3->CCR2=pare;
}
6.定时器中断服务函数
void TIM3_IRQHandler(void)
{HAL_TIM_IRQHandler(&TIM3_Handler);
}
7.定时器回调函数,由定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==(&TIM3_Handler)){
// LED1=!LED1; //LED1反转}
}
三、主函数
1.初始化HAL库
2.设置时钟
3.初始化delay函数
4.初始化串口、LED灯
5.TIM3的PWM的初始化
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"int main(void)
{u8 dir=1;u16 led0pwmval=0; HAL_Init(); //初始化HAL库 Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72Mdelay_init(72); //初始化延时函数uart_init(115200); //初始化串口LED_Init(); //初始化LED KEY_Init(); //初始化按键TIM3_PWM_Init(500-1,72-1); //72M/72=1M的计数频率,自动重装载为500,那么PWM频率为1M/500=2kHZwhile(1){delay_ms(10); if(dir)led0pwmval++; //dir==1 led0pwmval递增else led0pwmval--; //dir==0 led0pwmval递减 if(led0pwmval>300)dir=0; //led0pwmval到达300后,方向为递减if(led0pwmval==0)dir=1; //led0pwmval递减到0后,方向改为递增TIM_SetTIM3Compare2(led0pwmval); //修改比较值,修改占空比}
}
四、整体代码分析
1.主函数代码执行流程:
2.GPIO的属性:
3.定时器TIM3和PWM
更多推荐
源码,PWM
发布评论