记录一下stm32hal的学习过程,防止自己遗忘指令。
大一小白,以下全是基于自己的理解,如有不对,欢迎指正!!!
一.GPIO
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//设置pc15为高电平
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//设置pc15为低电平
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);//设置pc15为高电平
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);//设置pc15为低电平
GPIO_PinState类型变量可以赋值为GPIO_PIN_SET或GPIO_PIN_RESET
二.串口收发
轮询模式:
HAL_UART_Transmit(&huart1,(uint8_t*)message,strlen(message),100);//发送
HAL_UART_Transmit(&huart1,(uint8_t*)message,strlen(message),100);//发送,此时message被转换为uint8_t指针以符合入参,也可以定义uint8_t message[]这样的数组,最后的100代表等待时间,也可以设置为HAL_MAX_DELAY(发送不完就一直等待)
HAL_UART_Receive(&huart1,(uint8_t*)message,strlen(message),100);//接受,此时message被转换为uint8_t指针以符合入参,也可以定义uint8_t message[]这样的数组,最后的100代表等待时间,也可以设置为HAL_MAX_DELAY(发送不完就一直等待)
中断模式:推荐使用,无需堵塞
使用中断前记得在CubeMX里打开uart的中断
发送时直接加_IT,去掉等待时间
HAL_UART_Transmit_IT(&huart2,receive,1);//此时receive数组为uint8_t数组,因此无需强制类型转换,由于中断也无需添加等待时间
接收时HAL_UART_Receive_IT(&huart2,receive,1);
由于要判断接收完全,因此要引入回调函数
先在主函数执行之前开启中断接收(可以在begin2和end2中添加)
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,receive,1);
/* USER CODE END 2 */
之后在pfp对中重新定义HAL_UART_RxCpltCallback接收中断回调函数
例如:
/* USER CODE BEGIN PFP */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{/*写在中断中执行的代码
*/
HAL_UART_Receive_IT(&huart1,receive,1);//注意执行之后要再次开启接收中断,要不然只能接收一次!
}
/* USER CODE END PFP */
三.产生PWM
理论知识:
公式:f(频率)=clk_freq/(arr+1)*(psc*1)
clk_freq为单片机主频
duty(占空比)=ccr/(arr+1)
psc为分频系数
arr为自动重装载寄存器(TIMx_ARR)的值
ccr为捕获/比较寄存器(TIMx_CRx)的值
一般来看,都是让psc固定,通过改变arr来改变频率,通过改变ccr来改变占空比
注意1mhz=1000000hz
程序实现:
使用之前一定要打开定时器:
例如:HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
想让在while循环之前运行,请放在begin2和end2对中(我放在begin1和end1中不行哈)
//配置PSC预分频值
__HAL_TIM_SET_PRESCALER(&htim,prescaler);
//配置PWM频率 ARR
__HAL_TIM_SetAutoreload(&htim, (uint16_t)pwm_freq_arr);
//配置PWM占空比
__HAL_TIM_SetCompare(&htim, Channel, (uint16_t)pwm_duty_pulse);
从网上大神找到的封装好的函数:
//通用接口,主频72MHz,预分频值为72-1,设置PWM的脉冲频率freq(0.16-10kHz)、占空比参数 pulse (0-100)
void set_pwm_param(TIM_HandleTypeDef htim, uint32_t Channel, uint32_t freq, uint16_t duty)
{
uint16_t prescaler = 72-1;
uint64_t tim_clk_freq = 72000000;//填写自己的单片机主频,单位为hz
//计算PWM频率,所对应的自动重装载值 ---> ARR = 主频 / (预分频+1) / 预期PWM频率(Hz) - 1
float pwm_freq_arr = (tim_clk_freq * 1.0) / (prescaler+1) / freq * 1.0 - 1;
//计算PWM占空比,所对应比较寄存器的值 ---> CCR = 预期占空比 * (自动重装载值+1)
//占空比则由捕获/比较寄存器(TIMx_CRx)寄存器决定。占空比:duty = Pluse / (ARR+1)
float pwm_duty_pulse = duty * 1.0 / 100 * (pwm_freq_arr + 1);
//配置PSC预分频值
__HAL_TIM_SET_PRESCALER(&htim, prescaler);
//配置PWM频率 ARR
__HAL_TIM_SetAutoreload(&htim, (uint16_t)pwm_freq_arr);
//配置PWM占空比
__HAL_TIM_SetCompare(&htim, Channel, (uint16_t)pwm_duty_pulse);
}
使用示范:set_pwm_param(htim1,TIM_CHANNEL_1,1500,56);//频率1.5khz,占空比56%