一、环境配置
软件:stm32cubemx 6.4.0
keil 5.30
大虾丁丁串口调试助手
硬件:正点原子stm32f103ZET6开发板
二、配置stm32cubemx项目
选择USART1,Asynchronous(异步通讯),RS232是异步通讯,就是没有同步时钟也没有同步线进行通讯。
设置串口基础配置:
波特率:115200Bit/s;数据长度8位;无校验位;一位停止位。打开接收和发送。
打开串口中断:
设置串口1相关引脚:
设置中断优先级并生成代码:
三、关键代码讲解
#include "usart.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ UART_HandleTypeDef huart1; //定义结构体全局变量,用来初始化各个成员变量。 /* USART1 init function */ void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } //对串口一底层外设进行初始化 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 1, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USART1 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } } /* USER CODE BEGIN 1 */ /* USER CODE END 1 */
mymain.c
1 #include "mymain.h" 2 #include "tim.h" 3 #include "usart.h" 4 #include "gpio.h" 5 extern void SystemClock_Config(); 6 #define KEY HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) 7 8 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 9 { 10 11 if(GPIO_Pin == GPIO_PIN_4) 12 { 13 HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); 14 } 15 } 16 17 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 18 { 19 if(htim->Instance == TIM2) 20 { 21 HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5); 22 } 23 } 24 25 26 uint8_t res;//定义一个全局变量 27 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 28 { 29 if(huart->Instance == USART1)//假如有串口1触发接收中断 30 { 31 res = huart->Instance->DR;//保存接收到的数据 32 if(res == 0x01)//假如接收到的数据是0x01翻转电平 33 HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); 34 } 35 //重新定义一个接收,&res是定义的接收数据的地址,1是指1个数据,多个数据接收暂时 36 //开始新的接收中断 37 HAL_UART_Receive_IT(&huart1,&res,1); 38 //将接收到的数据发送到串口 39 HAL_UART_Transmit(&huart1,&res,sizeof(res),100); 40 } 41 42 43 44 45 int main(void) 46 { 47 48 HAL_Init(); 49 50 51 SystemClock_Config(); 52 53 MX_GPIO_Init(); 54 MX_TIM2_Init(); 55 HAL_TIM_Base_Start_IT(&htim2); 56 57 58 HAL_UART_MspInit(&huart1); 59 MX_USART1_UART_Init(); 60 HAL_UART_MspInit(&huart1); 61 HAL_UART_Init(&huart1); 62 //使能接收中断 63 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); 64 65 66 uint8_t str[]={"helllo"}; 67 //初始化一个接收的地址空间 68 HAL_UART_Receive_IT(&huart1,str,1); 69 70 //发送一个字符串 71 //str:数组起始地址 72 //sizeof(str):发送的个数 73 //100时间间隔,100ms后还未触发跳出函数 74 HAL_UART_Transmit(&huart1,str,sizeof(str),100); 75 76 77 78 79 while (1) 80 { 81 82 83 HAL_Delay(10); 84 85 // static unsigned char keyflag=1; 86 // if(KEY==0) 87 // { 88 // HAL_Delay(100); 89 // if(KEY==0&&keyflag==1) 90 // { 91 // HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); 92 // HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5); 93 // keyflag=0; 94 // } 95 // else if(KEY==1) 96 // {keyflag=1;} 97 // } 98 99 100 101 102 } 103 104 }
利用函数重定向实现printf串口发送:
新建文件。
myprintf.h
#ifndef __MYPRINTF_H #define __MYPRINTF_H #include "main.h" #include "stdio.h" #ifndef _UART_PRINT_C //放置需要被外部调用的uart.c文件中的全局变量\函数 #endif extern UART_HandleTypeDef huart1; void Usart_SendString(uint8_t *str); int fputc(int ch, FILE *f); int fgetc(FILE *f); #endif
myprintf.c
/*************Printf重定向UART**************/ /*用途: *使用printf将打印内容通过串口发送。 *原理: *将C语言库函数中的fputc 和fgetc函数重新定向到UART串口 *使用方法及注意事项: *使用前,需要在main.c中添加头文件 "stdio.h""uart_printf.h" 如果是keil编译器,同时需要在选项卡中勾选“使用微库”usemicrolib. * *默认使用USART1串口, 当需要使用其他串口的时候, 修改huart1 为目标串口, *建议使用CubeMX生成的代码,这样直接修改huart1后面的标号即可直接使用 ******************************************/ #define _UART_PRINTF_C #include "myprintf.h" /***************** 发送字符串(重新定向) **********************/ void Usart_SendString(uint8_t *str) { unsigned int k=0; do { HAL_UART_Transmit(&huart1,(uint8_t *)(str + k) ,1,1000); k++; } while(*(str + k)!='\0'); } ///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数 int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口DEBUG_USART */ HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000); return (ch); } ///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { int ch; HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000); return (ch); }
标签:灯亮,HAL,UART,huart1,LED,Init,串口,GPIO,USART1 From: https://www.cnblogs.com/1998wdq/p/17281095.html