STM32之UART

UART,是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),既然是“器”,显然,它就是个设备而已,要完成一个特定的功能的硬件,它本身并不是协议。那么它要完成什么功能呢?它的最基本功能,是串行数据和并行数据之间的转换。我们知道,计算机中的数据以Byte为基本单位,对一个Byte的存取是并行的,即,同时取得/写入8个bit。而串行通信,需要把这个Byte“打碎”,按照时间顺序来收发以实现串行。

RS232/RS485,是两种不同的电气协议,也就是说,是对电气特性以及物理特性的规定,作用于数据的传输通路上,它并不内含对数据的处理方式。比如,最显著的特征是:RS232使用3-15v有效电平,而UART,因为对电气特性并没有规定,所以直接使用CPU使用的电平,就是所谓的TTL电平(可能在0~3.3V之间)。更具体的,电气的特性也决定了线路的连接方式,比如RS232,规定用电平表示数据,因此线路就是单线路的,用两根线才能达到全双工的目的;而RS485, 使用差分电平表示数据,因此,必须用两根线才能达到传输数据的基本要求,要实现全双工,必需用4根线。但是,无论使用RS232还是RS485,它们与UART是相对独立的,但是由于电气特性的差别,必须要有专用的器件和UART接驳,才能完成数据在线路和UART之间的正常流动。

普通方式的串口

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	 if(HAL_UART_Receive(&huart1, &c, sizeof(c), 1000) == HAL_OK)
	 {
		 if(c == '\r')
		 {
			 HAL_UART_Transmit(&huart1, (uint8_t*)"\n", sizeof("\n"), 1000);
		 }

		 HAL_UART_Transmit(&huart1, &c, sizeof(c), 1000);
	 }
  }
  /* USER CODE END 3 */

串口使用printf()

#include <stdio.h>
#ifdef __GNUC__
int __io_putchar(int ch)
{

	HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);

	if(ch == '\n')
		HAL_UART_Transmit(&huart1, (uint8_t*)"\r", 2, 100);

	return ch;
}
#endif

中断方式UART

先在主函数中初始调用一次中断接收

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, &c, sizeof(c));
  /* USER CODE END 2 */

注册接收完成的回调函数,这个函数是弱函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart == &huart1)
	{
		if(c == '\r')
		{
			HAL_UART_Transmit_IT(huart, (uint8_t*)"\n\r", sizeof("\n\r"));
		}
		else
		{
			HAL_UART_Transmit_IT(huart, &c, sizeof(c));
		}
	}
	HAL_UART_Receive_IT(huart, &c, sizeof(c));
}

HAL_UART_Transmit_IT只发送一次数据,下次发送需要等待下次中断

	//第二行代码不会生效,只会发送"ab",而不会发生"abcde",或者被覆盖成"cde"
	//这与中断的结构有关
	HAL_UART_Transmit_IT(huart, (uint8_t*)"ab", sizeof("ab"));
	HAL_UART_Transmit_IT(huart, (uint8_t*)"abc", sizeof("abc"));

DMA串口

以USART1为例
MX配置完DMA通道的代码

static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
  /* DMA2_Stream7_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);

}
HAL_UART_Transmit_DMA(&huart1, buffer, sizeof(buffer));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我才不要写代码呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值