本文主要是介绍【蓝桥杯嵌入式】定时器的PWM输出与输入捕获(测量频率与占空比),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【蓝桥杯嵌入式】定时器的PWM输出与脉冲输 入捕获(测量频率与占空比)
- PWM输出
- cubemx配置
- 程序设计
- 输入捕获
- cubemx配置
- 程序设计
- 真题典例分析
PWM输出
cubemx配置
PWM输出引脚配置,这里使用PA6和PA7引脚输出两路PWM信号,分别对应的是由TIM16和TIM17的通道1产生的PWM信号,同时配置定时器的预分频系数PSC和自动重装载值CCR,PWM信号频率即为:
frq = 80000000 / (PSC+1)/ (ARR+1)
这里预分频系数为800-1,自动重装载值为100,则频率 frq = 80000000 / 800 / 100 = 1K Hz,占空比预设置为20%
同理 对TIM17通道1进行相关配置,使得输出频率为2KHz,占空比初始化为20%的PWM信号
程序设计
通过cubemx配置后,初始化信号的参数如下所示
//PA6 1KHz 20%
TIM16->PSC = 800-1;
TIM16->ARR = 100-1;
TIM16->CCR1 = 20;//PA7 2KHz 20%
TIM17->PSC = 400-1;
TIM17->ARR = 100-1;
TIM17->CCR1 = 20;
启动PWM输出: 启动TIM16与TIM17的通道1输出PWM信号
HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
修改PWM信号占空比: 通过改变TIM16与TIM17通道1的自动重装载值来改变PWM信号的占空比
TIM16->CCR1 = 50;
TIM17->CCR1 = 25;
修改PWM信号的频率:,可以通过改变预分频系数PSC,或者改变自动重装值,但通过修改自动重装载值修改频率的同时会修改占空比。
TIM16->PSC = 400-1; //将PA6引脚的频率改为2000 Hz 占空比保持不变
TIM17->ARR = 50-1; //将PA7的频率改为4000 Hz 但占空比变为原来的2倍
输入捕获
- 输入捕获可以用来测量PWM波的频率与占空比
- 输入捕获模式下,当通道输入引脚出现指定高电平跳变时,当前CNT的值将被锁存到CCR中
cubemx配置
通过查看原理图发现,开发板自带2路555信号发生器,分别通过接口J9和J10接到开发板的PB4和PA15端口,这里取下跳线帽,通过杜邦线将PA6、PA7的PWM信号接入到PA15、PB4引脚,用于检测PWM信号的频率与占空比。
通过配置PB4引脚为TIM3_CH1,开启定时器3,设置预分频系数,配置从模式、触发源及其时钟源,分别设置通道1和通道2为直接模式与间接模式,同时设置为上升沿触发和下降沿触发。
同理对TIM2进行同样的配置
程序设计
初始化开启定时器的通道捕获
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_IC_Start(&htim3,TIM_CHANNEL_2);
频率和占空比的测量
void pwm_process(void)
{//测量频率frq1 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);frq2 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);//测量占空比duty1 = (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);duty2 = (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
}
真题典例分析
- PA6输出信号占空比通过电位器R37进行调节如图调节
- 通过B2按键切换高低频模式,并通过LCD进行实时显示
adc数据采集功能函数:
double getAdcVal(ADC_HandleTypeDef *pin)
{double dat;HAL_ADC_Start(pin);dat = HAL_ADC_GetValue(pin);return dat * 3.3 / 4096;
}
adc业务逻辑程序进程函数: 首先确定adc数据采集周期为200ms采集一次,并进行数字滤波,最后通过电压与占空比的关系,来确定PA6引脚的占空比。
u32 adc_tick = 0;
double adc_sum = 0;
void adc_process(void)
{//adc采集周期 200msif(uwTick - adc_tick < 200)return;adc_tick = uwTick;//adc数字滤波for(uchar i = 0; i < 10; i++)adc_sum += getAdcVal(&hadc2);vr37 = adc_sum / 10.0f;adc_sum = 0;//通过电压改变PWM占空比if(vr37 <= 1.0f)TIM16->CCR1 = 10;else if(vr37 >= 3.0f)TIM16->CCR1 = 85;elseTIM16->CCR1 = (uchar)(37.5 * (vr37 - 1.0f) + 10);
}
按键二: 启动5秒定时,并确定是从高频到低频,还是从低频到高频
if(key[1].single_flag == 1)
{//按键2短按业务逻辑程序//shake_flag = !shake_flag;up_flag = !up_flag; //从低频到高频标志sec5_flag = !sec5_flag; //5秒定时标志HAL_TIM_Base_Start_IT(&htim7); //启动定时器 改变分频系数key[1].single_flag = 0;
}
定时器中断服务函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{ if(htim->Instance == TIM7) //50ms{if(up_flag)psc--;elsepsc++;}
}
PWM进程函数: 频率、占空比的修改与测量
void pwm_process(void)
{//通过修改预分频系数修改频率TIM16->PSC = psc;//检测PWM信号频率frq1 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);frq2 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);//检测PWM信号占空比duty1 = (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);duty2 = (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
}
最后将实时的频率与占空比显示在LCD屏幕
void lcd_process(void)
{if(ui == 0) //第一个界面显示的内容{sprintf(text," Title1 ");LCD_DisplayStringLine(Line1, (unsigned char *)text); //LCD显示函数sprintf(text," frq1:%dHz ",frq1);LCD_DisplayStringLine(Line3, (unsigned char *)text); //LCD显示函数sprintf(text," duty1:%d%% ",duty1);LCD_DisplayStringLine(Line4, (unsigned char *)text); //LCD显示函数sprintf(text," frq2:%dHz ",frq2);LCD_DisplayStringLine(Line5, (unsigned char *)text); //LCD显示函数sprintf(text," duty2:%d%% ",duty2);LCD_DisplayStringLine(Line6, (unsigned char *)text); //LCD显示函数}
}
这篇关于【蓝桥杯嵌入式】定时器的PWM输出与输入捕获(测量频率与占空比)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!