本文主要是介绍嵌入式开发--STM32G431RBTx-产生PWM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
嵌入式开发–STM32G431RBTx-产生pwm
定时器工作原理
如图有反映stm32g431的定时器资源。
共10个定时器
定时器 | 定时器类型 | 个数 |
---|---|---|
TIM6,7 | 基本定时器 | 2 |
TIM2,3,4 | 全功能通用定时器 | 3 |
TIM15,16,17 | 通用定时器(只有1或2个通道) | 3 |
TIM1,8 | 高级控制定时器 | 2 |
- 当APB1/2分频系数为1时,给定时器的时钟为X1
- 当APB1/2分频系数不为1时,给定时器时钟需X2
基本定时功能,当累加的时钟脉冲数超过预定值时,能触发中断或者触发DMA请求。
是专门用于驱动数模转换器(DAC)
基本定时器TIM16/17内部结构图
配置定时器
设定TIM16定时器
设定系数
第一个是分频系数
(Prescaler)
第二个是周期计数值,按照分频后的时间进行计数(Counter Period)
80M的晶振除以8000,得到的工作频率为80 000 000/8 000=10 000
计算到ARR,就让ARR设置为100-1
此时可以得到一个频率为100hz的PWM波
此处为占空比的设置,后续可以继续更改。
使用中断
TIM17设置同上。
关于按键中断的实现
struct keys key[4]={0,0,0}; if(htim->Instance==TIM3){key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);}
这段代码是一个中断回调函数,用于处理定时器 TIM3 的中断事件。代码中包含一个名为 key
的结构体数组,用于记录按键的状态。
在函数体中,首先通过读取 GPIO 引脚的状态,将按键的状态存储到 key
数组中的相应位置。其中,key[i].key_sta
表示第 i 个按键的状态。
接下来,使用一个循环遍历 key
数组的每个元素,对每个按键的状态进行判断和处理。
for(int i=0;i<4;i++){switch (key[i].judge_sta){case 0: //{if(key[i].key_sta==0) key[i].judge_sta=1;}break;case 1:{if(key[i].key_sta==0){key[i].judge_sta=2;key[i].single_flag=1;}else key[i].judge_sta=0;}break;case 2:{if(key[i].key_sta==1){key[i].judge_sta=0; }}break; } }
在 switch
语句中,根据 key[i].judge_sta
的值来确定需要执行的操作。key[i].judge_sta
表示按键的判断状态。
当key[i].judge_sta
的值为 0 时,表示按键处于初始状态。
- 如果按键的状态为按下(
key[i].key_sta
等于 0),则将key[i].judge_sta
的值设为 1,表示按键已按下。
当 key[i].judge_sta
的值为 1 时,表示按键已按下。
- 如果按键的状态仍然为按下,维持
key[i].judge_sta
的值为 1。 - 如果按键的状态变为松开(
key[i].key_sta
等于 1),则将key[i].judge_sta
的值设为 2,表示按键已松开,并将key[i].single_flag
的值设为 1,表示按键被单击。
当key[i].judge_sta
的值为 2 时,表示按键已松开。
- 如果按键的状态变为按下,将
key[i].judge_sta
的值设为 0,表示按键已按下。
功能实现
一共有四个按键,按键0,按键1,按键2,按键3
按键 | 功能 |
---|---|
按键0 | LCD显示PA6,PA7的占空比 |
按键1 | LCD显示PA6,PA7的占空比;PA6占空比加10 |
按键2 | LCD显示PA6,PA7的占空比;PA7占空比加10 |
按键3 | LCD显示PA6,PA7的占空比 |
添加如下配置
extern uint frq1,frq2;
extern float duty1,duty2;
uchar view=0;uchar pa6_duty=10;
uchar pa7_duty=10;HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);//pwm输出开启HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//频率测量捕获定时器开启HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);//频率测量捕获定时器开启 间接通道HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pa6_duty);//设置初始pwm频率__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pa7_duty);
按键功能
void key_proc(void)
{if(key[1].single_flag==1){pa6_duty+=10;if(pa6_duty>=100) pa6_duty=10;__HAL_TIM_SetCompare(&htim16,TIM_CHANNEL_1,pa6_duty);key[1].single_flag=0;}if(key[2].single_flag==1){pa7_duty+=10;if(pa7_duty>=100) pa7_duty=10;__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,pa7_duty);key[2].single_flag=0;}
} void disp_proc(void)
{char text[30]; sprintf(text," Para ");LCD_DisplayStringLine(Line1, (uint8_t *)text);sprintf(text," PA6:%d ",pa6_duty);LCD_DisplayStringLine(Line2, (uint8_t *)text);sprintf(text," PA7:%d ",pa7_duty);LCD_DisplayStringLine(Line4, (uint8_t *)text);//清理界面残留sprintf(text," ");LCD_DisplayStringLine(Line3, (uint8_t *)text);LCD_DisplayStringLine(Line5, (uint8_t *)text);}
这篇关于嵌入式开发--STM32G431RBTx-产生PWM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!