一.stm32使用hal库串口接收发送测试

一.hal库串口接收发送测试

1、串口的模式有3种,一是查询模式,二是中断模式,三是DMA模式

HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制 HAL_UART_Receive();串口轮询模式接收,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收

2、阻塞传输是调用这个函数并在等待时间内一直等待操作完成。 HAL_UART_Transmit HAL_UART_Receive 查询的方式一般少用,这里不做过多介绍。 3、串口中断 串口中断函数 HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用 HAL_UART_TxCpltCallback();数据完全发送完成后调用 HAL_UART_RxHalfCpltCallback();一半数据接收完成时调用 HAL_UART_RxCpltCallback();数据完全接受完成后调用 HAL_UART_ErrorCallback();传输出现错误时调用

一.在串口中定义相关变量

uint8_t RxBuffer;//接收中断缓存
uint8_t Uart_RxBuffer[256];//接收中断
uint8_t Uart_RX_Cnt = 0;//接收中断计数
uint8_t AlmStr[]="Uart1数据溢出(大于256)!rn";//UART1 错误信息输出

在main的主循环外开启中断
HAL_UART_Receive_IT(&huart1,(uint8_t*)&RxBuffer,1);//开启接收中断

串口接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
          
   
  UNUSED(huart);
  if(Uart_RX_Cnt >= 255)  //溢出判断
  {
          
   
     Uart_RX_Cnt = 0;
	memset(Uart_RxBuffer,0x00,sizeof(Uart_RxBuffer));//清空缓存,记得#include "string.h"
	HAL_UART_Transmit(&huart1, (uint8_t *)&AlmStr, sizeof(AlmStr),0xFFFF);

  }
 else
 {
          
   
	Uart_RxBuffer[Uart_RX_Cnt++] = RxBuffer;   //接收数据转存
	if((Uart_RxBuffer[Uart_RX_Cnt-1] == 0x0A)&&	(Uart_RxBuffer[Uart_RX_Cnt-2] == 0x0D)) //判断结束位
    {
          
   

		HAL_UART_Transmit(&huart1, (uint8_t *)&Uart_RxBuffer,Uart_RX_Cnt,0xFFFF); //将收到的信息发送出去

		Uart_RX_Cnt = 0;
	memset(Uart_RxBuffer,0x00,sizeof(Uart_RxBuffer)); //清空数组
    }
}
     HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1);   //再开启接收中断
}

到这里中断方式的串口接收(并发送)完成。


二.重定向问题
函数版:
/*
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
*/

int fputc(int ch, FILE *f)
{
          
   
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
/*
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx 
  * 在串口上输入时,最后需要加空格,才能被存储
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无 
 */
int fgetc(FILE *f)
{
          
   
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

寄存器版:
/*重定向Printf函数*/  
int fputc(int ch,FILE *f)  
{
          
     
    return (SendChar(ch));  
}  
/*重定向Scanf函数*/  
int fgetc(FILE *f)  
{
          
     
   return (SendChar(GetKey()));  
    /*调用scanf()在串口中输入数据时,必须以空格结束,否则无法完成发送*/  
}
int SendChar(int ch)  
{
          
     
    while(!(USART1->SR & USART_FLAG_TXE));  
    USART1->DR = (ch & 0x1FF);  
    return ch;  
}  
int GetKey(void)  
{
          
     
    while(!(USART1->SR & USART_FLAG_RXNE));  
    return ((int)(USART1->DR & 0X1FF));  
}

主函数的循环体演示: 实测代码:https://download..net/download/weixin_44386927/13772536

经验分享 程序员 微信小程序 职场和发展