串口的初始化:
1.软件方面,如波特率等,void UART1_Init(uint32_t bandrate)
使用hal库官方做的结构体初始化串口比较简单,我们只需要赋值对应成员即可
2.硬件方面,如gpio等 void HAL_UART_MspInit(UART_HandleTypeDef *huart)。
#include "stm32f1xx_hal.h"
#include "uart.h"
UART_HandleTypeDef UART1;
uint8_t TX_DATA[64],RX_DATA[64];
uint8_t RX_STATE;
void UART1_Init(uint32_t bandrate){ //串口中断收发数据
UART1.Instance = USART1;
UART1.Init.BaudRate =bandrate;
UART1.Init.HwFlowCtl =UART_HWCONTROL_NONE ;
UART1.Init.Mode = UART_MODE_TX_RX;
UART1.Init.Parity =UART_PARITY_NONE ;
UART1.Init.StopBits =USART_STOPBITS_1;
UART1.Init.WordLength =UART_WORDLENGTH_8B;
HAL_UART_Init(&UART1);
HAL_UART_Receive_IT(&UART1,RX_DATA,5); //使能接收
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart){
if(huart->Instance == USART1){
__HAL_RCC_GPIOA_CLK_ENABLE();//打开gpioa的时钟
__HAL_RCC_USART1_CLK_ENABLE();//打开串口1的时钟
GPIO_InitTypeDef GPIO_Init;
GPIO_Init.Mode = GPIO_MODE_AF_PP ;
GPIO_Init.Pin = GPIO_PIN_9;//串口1的TX
GPIO_Init.Speed =GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA,&GPIO_Init);
GPIO_Init.Mode = GPIO_MODE_AF_INPUT ;
GPIO_Init.Pin = GPIO_PIN_10;//串口1的RX
GPIO_Init.Pull = GPIO_NOPULL; //上下拉只有输入模式有效,输出模式上下拉电阻被禁止
HAL_GPIO_Init(GPIOA,&GPIO_Init);
HAL_NVIC_SetPriority(USART1_IRQn ,3,0);//配置 中断优先级
HAL_NVIC_EnableIRQ(USART1_IRQn);//使能中断
}
}
void USART1_IRQHandler(void){
HAL_UART_IRQHandler(&UART1); //这个函数处理UART中断请求。
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart->Instance == USART1){ //接收完成中断回调函数
memcpy(TX_DATA,RX_DATA,5);
RX_STATE=1;
HAL_UART_Receive_IT(&UART1,RX_DATA,5);
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
if(huart->Instance == USART1){ //发送完成中断回调函数
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){
if(huart->Instance == USART1){ //错误中断回调函数
}
}
主函数大循环中代码如下,实现把收到的数据返还电脑。串口以中断方式收发数据,必须要收到预期接收值才能触发接收完成中断。如HAL_UART_Receive_IT(&UART1,RX_DATA,5)必须收到5个字节数据才能触发HAL_UART_RxCpltCallback()。
while(1){
// if(RX_DATA[0]==0x31) HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);
if(RX_STATE==1){
RX_STATE=0;
HAL_UART_Transmit_IT(&UART1,TX_DATA,5);
}