PWM捕获
Cubemx配置
PA15-time2-CH1
对应R40调节的PWM波,通过J10引脚捕获
PB4-Time3-CH1
对应R39调节的PWM波,通过J9引脚捕获
选择好引脚后找到对应TIM和通道选择input Capture direct mode
下面的配置根据截屏所标设置即可,需要注意的是TIM2的counter period是32位的,所以是0xffffffff,但是TIM3的是16位的,填0xffff。
函数编写
首先注意主函数中是否有MX_TIM2_Init()的初始化函数,按说cubemx会自动生成
其次,在初始化后面加上启动函数,启动定时器捕获
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
编写回调函数
此函数中测量了R40的频率和占空比
只测量了R39的频率
两部分代码可以相互借鉴,如果只需要频率,R39的方法更简短
如果既需要测频率,又需要占空比,那么就要用R40的方法了
u32 tim2_cnt1 = 0;
u32 tim2_cnt2 = 0;
u32 f40 = 0;
u8 tim2_state = 0; //0:开始计时 1:获取T1 2:获取T2
u32 tim3_cnt1 = 0;
u32 f39 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim2)
{
if(tim2_state == 0) //第一个上升沿产生,开始计时
{
__HAL_TIM_SetCounter(&htim2,0); //设置CNT为0,重新开始计时
TIM2->CCER |=0x02; //下降沿中断,CC1P置为1
tim2_state=1;
}
else if(tim2_state == 1) //获取T1,改为上升沿中断
{
tim2_cnt1 = __HAL_TIM_GetCounter(&htim2); //获取T1(us)
TIM2->CCER &=~ 0x02; //上升沿中断,CC1P置为0
tim2_state=2;
}
else if(tim2_state == 2) //第二个上升沿中断,获取T2(周期)
{
tim2_cnt2 = __HAL_TIM_GetCounter(&htim2); //获取T2(us)
f40=1000 000/tim2_cnt2;
d40=tim2_cnt1*100.0f/tim2_cnt2;
tim2_state = 0;
}
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1); //开启TIM2_CH1的输入捕获中断
}
if(htim==&tim3)
{
tim3_cnt1=__HAL_TIM_GetCounter(&htim3); //获取cnt,单位us
__HAL_TIM_SetCounter(&htim3,0); //设置cnt为0,重新开始计时
f39=1000 000/tim3_cnt1; //获取到R39控制的555的频率
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1); //开启TIM3_CH1的输入捕获中断
}
}
可以通过下图理解
PWM输出
PA6和PA7都可以进行PWM输出,重点掌握PA7的输出
Cubemx配置
PA7-TIM17-CH1
配置如截屏标红所示。
其中我们设置的PWM输出的频率为1kHz,占空比为20%。
counter period + 1为周期(单位微秒),周期为1000us对应频率为1kHz。
Pulse为高电位时间,pulse/(counter period+1)为占空比
以上提到的两个需要根据需求具体设置
auto-reload preload需要使能,这样可以方便我们在程序中改变输出PWM波的频率和占空比。
代码编写
输出代码编写较简单,主要需要注意的是
初始化(一般cubemx都写了)
启动输出函数
改变输出的频率和占空比
MX_TIM17_Init();
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
TIM17->ARR = 499; // 周期是500us,对应频率2kHz
TIM17->CCR1 = 400; // 80%占空比
这些都放在main()中、while(1)外面。