STM32 HAL库指令学习

记录一下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%

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你解答关于使用stm32HAL库发送AT指令的问题。以下是一个基本的示例代码: ```c #include "stm32f4xx_hal.h" #include <string.h> UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); char at_cmd[] = "AT\r\n"; // AT指令 HAL_UART_Transmit(&huart2, (uint8_t*)at_cmd, strlen(at_cmd), HAL_MAX_DELAY); // 发送AT指令 while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 50; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { Error_Handler(); } } static void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void Error_Handler(void) { __disable_irq(); while (1) { } } ``` 这段代码使用了UART2串口和PA5引脚。首先在`MX_USART2_UART_Init()`函数中初始化UART2串口,然后使用`HAL_UART_Transmit()`函数发送AT指令。你需要将AT指令存储在`at_cmd`数组中,并使用`strlen()`函数获取AT指令的长度。在这个示例中,我们只发送了一次AT指令,然后进入了一个无限循环。你可以根据你自己的需求更改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值