串口实现USART的接受与发送:
(一),开启串口1,开启RX 与 TX 的DMA通道,默认即可;
(二),开启串口中断,并且保证 两个DMA通道 与 串口 的中断等级一致,如1;
例如:
USART空闲中断:优先级0 DMA接收中断(半满/满传输):优先级0
DMA发送中断:优先级2(更低)
最佳实践:将串口接收中断与RX DMA中断设为相同最高优先级(如0),且均高于发送中断
(三),添加代码:
注意:DMA 编号小的通道优先级高!!
在 stm32f1xx_it.c 中添加如下代码:
#define BUFFERSIZE 255 //可接收的最大数据量
extern uint8_t Rx_len ;
extern uint8_t ReceiveBuff[BUFFERSIZE]; //接收缓冲区
extern uint32_t rx_time ;
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
uint32_t temp;
if(USART1 == huart1.Instance)//判断是否为串口1中断
{
if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))//如果为串口1空闲
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除中断标志
HAL_UART_DMAStop(&huart1); //停止DMA接收
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //获取DMA当前还有多少未填充
Rx_len = BUFFERSIZE - temp; //计算串口接收到的数据个数
// HAL_UART_Transmit_DMA(&huart1,ReceiveBuff,Rx_len); //发送数据,引起发送回调函数(将数据回传)
rx_time = uwTick;
// Rx_len=0;//接收数据长度清零
HAL_UART_Receive_DMA(&huart1,ReceiveBuff,BUFFERSIZE); //开启下一次接收
}
}
/* USER CODE END USART1_IRQn 1 */
}
在 main.c 中添加代码:
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能串口1 IDLE中断
HAL_UART_Receive_DMA(&huart1,ReceiveBuff,BUFFERSIZE);//使能接收
#define BUFFERSIZE 255//可以接收的最大字符个数
uint8_t ReceiveBuff[BUFFERSIZE]; //接收缓冲区
uint8_t Rx_len;//接收完成中断标志,接收到的字符长度
extern DMA_HandleTypeDef hdma_usart1_rx;
//void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) //发送回调函数
//{
// if(huart==&huart1)//判断是否是串口1中断
// {
// Rx_len=0;
// memset(ReceiveBuff,'\0',sizeof(ReceiveBuff));
// }
//}
void Rx_proc()
{
if(uwTick - rx_time<80)
rx_time = uwTick;
if(Rx_len > 0 )
{
//接收判断区
if(ReceiveBuff[0]=='1' && ReceiveBuff[1]=='2'&& ReceiveBuff[2]=='3' && ReceiveBuff[5]=='2')
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);//引脚C13电平反转
HAL_UART_Transmit_DMA(&huart1,ReceiveBuff,Rx_len);
}
Rx_len=0;
memset(ReceiveBuff,'\0',sizeof(ReceiveBuff));
}
}
可以只开启接收中断,发送用printf :
void Rx_proc()
{
if(uwTick - rx_time<80)
rx_time = uwTick;
if(Rx_len > 0 )
{
//接收判断区
if(ReceiveBuff[0]=='1' && ReceiveBuff[1]=='2'&& ReceiveBuff[2]=='3' && ReceiveBuff[5]=='2')
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);//引脚C13电平反转
printf("%s\r\n",ReceiveBuff);
}
Rx_len=0;
memset(ReceiveBuff,'\0',sizeof(ReceiveBuff));
}
}