一、前言

1、简介

  在上一篇UART详解中,已经有了关于UART的详细介绍了,也有关于如何使用STM32CubeMX来配置UART的操作了,而在该篇博客,主要会讲解一下如何实现UART串口的发送功能。

2、UART简介

  嵌入式开发中,UART串口通信协议是我们常用的通信协议之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)。

3、准备工作

  在UART详解中已经有了详细的说明,在这里就不说明了。

注:

  建议每次编写好一个相关功能且测试功能成功使用后,保存并压缩成一份Demo例程,方便日后有需要的时候可以直接使用。

  例如:

二、CubeMx配置及函数说明

说明:

  这篇用到的配置跟UART详解里的配置都相同,可以按照UART详解来配置好时钟、UART即可。

  所以在进行下一步之前,先确保已经按照UART详解的配置步骤配置好了,然后再进行后面的操作。

1、CubeMx配置

  按照上一篇UART详解来配置

2、函数说明

1)CubeMX生成的UART初始化(在usart.c中)

  

 1 UART_HandleTypeDef huart1;
2
3 /* USART1 init function */
4
5 void MX_USART1_UART_Init(void)
6 {
7
8 huart1.Instance = USART1;
9 huart1.Init.BaudRate = 115200;
10 huart1.Init.WordLength = UART_WORDLENGTH_8B;
11 huart1.Init.StopBits = UART_STOPBITS_1;
12 huart1.Init.Parity = UART_PARITY_NONE;
13 huart1.Init.Mode = UART_MODE_TX_RX;
14 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
15 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
16 if (HAL_UART_Init(&huart1) != HAL_OK)
17 {
18 Error_Handler();
19 }
20
21 }
22
23 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
24 {
25
26 GPIO_InitTypeDef GPIO_InitStruct = {0};
27 if(uartHandle->Instance==USART1)
28 {
29 /* USER CODE BEGIN USART1_MspInit 0 */
30
31 /* USER CODE END USART1_MspInit 0 */
32 /* USART1 clock enable */
33 __HAL_RCC_USART1_CLK_ENABLE();
34
35 __HAL_RCC_GPIOA_CLK_ENABLE();
36 /**USART1 GPIO Configuration
37 PA9 ------> USART1_TX
38 PA10 ------> USART1_RX
39 */
40 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
41 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
42 GPIO_InitStruct.Pull = GPIO_PULLUP;
43 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
44 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
45 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
46
47 /* USER CODE BEGIN USART1_MspInit 1 */
48
49 /* USER CODE END USART1_MspInit 1 */
50 }
51 }
52
53 void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
54 {
55
56 if(uartHandle->Instance==USART1)
57 {
58 /* USER CODE BEGIN USART1_MspDeInit 0 */
59
60 /* USER CODE END USART1_MspDeInit 0 */
61 /* Peripheral clock disable */
62 __HAL_RCC_USART1_CLK_DISABLE();
63
64 /**USART1 GPIO Configuration
65 PA9 ------> USART1_TX
66 PA10 ------> USART1_RX
67 */
68 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
69
70 /* USER CODE BEGIN USART1_MspDeInit 1 */
71
72 /* USER CODE END USART1_MspDeInit 1 */
73 }
74 }

USART init

2)HAL库函数HAL_UART_Transmit(在stm32f4xx_hal_uart.c中)

说明:

  该函数能够通过huart串口发送Size位pData数据。

参数说明:

  • huart    :选择用来发送的UART串口

  • pData   :指向将要发送的数据的指针

  • Size      :发送数据的大小

  • Timeout:超时时间

  

 1 /**
2 * @brief Sends an amount of data in blocking mode.
3 * @param huart Pointer to a UART_HandleTypeDef structure that contains
4 * the configuration information for the specified UART module.
5 * @param pData Pointer to data buffer
6 * @param Size Amount of data to be sent
7 * @param Timeout Timeout duration
8 * @retval HAL status
9 */
10 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
11 {
12 uint16_t *tmp;
13 uint32_t tickstart = 0U;
14
15 /* Check that a Tx process is not already ongoing */
16 if (huart->gState == HAL_UART_STATE_READY)
17 {
18 if ((pData == NULL) || (Size == 0U))
19 {
20 return HAL_ERROR;
21 }
22
23 /* Process Locked */
24 __HAL_LOCK(huart);
25
26 huart->ErrorCode = HAL_UART_ERROR_NONE;
27 huart->gState = HAL_UART_STATE_BUSY_TX;
28
29 /* Init tickstart for timeout managment */
30 tickstart = HAL_GetTick();
31
32 huart->TxXferSize = Size;
33 huart->TxXferCount = Size;
34 while (huart->TxXferCount > 0U)
35 {
36 huart->TxXferCount--;
37 if (huart->Init.WordLength == UART_WORDLENGTH_9B)
38 {
39 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
40 {
41 return HAL_TIMEOUT;
42 }
43 tmp = (uint16_t *) pData;
44 huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
45 if (huart->Init.Parity == UART_PARITY_NONE)
46 {
47 pData += 2U;
48 }
49 else
50 {
51 pData += 1U;
52 }
53 }
54 else
55 {
56 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
57 {
58 return HAL_TIMEOUT;
59 }
60 huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
61 }
62 }
63
64 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
65 {
66 return HAL_TIMEOUT;
67 }
68
69 /* At end of Tx process, restore huart->gState to Ready */
70 huart->gState = HAL_UART_STATE_READY;
71
72 /* Process Unlocked */
73 __HAL_UNLOCK(huart);
74
75 return HAL_OK;
76 }
77 else
78 {
79 return HAL_BUSY;
80 }
81 }

HAL_UART_Transmit

三、代码部分:实现UART发送

1、直接发送

1)在main主函数中定义一个数组

   /* USER CODE BEGIN 1 */
unsigned char uTx_Data[] = {0x41, 0x42, 0x43, 0x44, 0x45}; //数组内十六进制代表“ABCDE”
/* USER CODE END 1 */

2)在main主函数中的while循环中调用HAL库UART发送函数

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
/* UART发送 */
HAL_UART_Transmit(&huart1, uTx_Data, sizeof(uTx_Data), 0xffff);
/* 延迟1s */
HAL_Delay();
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */

整个main函数如下:

 int main(void)
{
/* USER CODE BEGIN 1 */
unsigned char uTx_Data[] = {0x41, 0x42, 0x43, 0x44, 0x45}; //数组内十六进制代表“ABCDE”
/* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */
SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
/* UART发送 */
HAL_UART_Transmit(&huart1, uTx_Data, sizeof(uTx_Data), 0xffff);
/* 延迟1s */
HAL_Delay();
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

3)编译、下载烧写

4)实现效果(在PC端串口助手中显示发送成功)

2、字符串发送

说明:

  前面的发送方式,不仅要传入句柄参数,还有数组、长度、超时时间参数。

  为了简便发送,我们可以专门写一个字符串发送函数,可以直接传入一个数组即可发送,可以更简便地实现字符串发送。

  优点是,发送数据更简便,能够一次性发送很长的数据数组。

  但缺点就是不能控制发送的长度,会将整个数据数组发出。

1)在Uart.c中添加vUser_UART_SendString函数

 /* USER CODE BEGIN 1 */
void vUser_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char * uData)
{
/* -1- 判断数据是否发送完毕 */
while(*uData) //若为空即发送完毕,若不为空则还有数据
{
/* -2- 发送1Byte */
HAL_UART_Transmit(uartHandle, uData, , 0xffff);
/* -3- 移至下1Byte */
uData++;
}
}
/* USER CODE END 1 */

2)在Uart.h中声明一下vUser_UART_SendString函数(声明后就可以在别的地方调用该函数)

 /* USER CODE BEGIN Prototypes */
extern void vUser_UART_SendString(UART_HandleTypeDef* uartHandle, unsigned char * uData);
/* USER CODE END Prototypes */

3)在main主函数中定义一个数组

   /* USER CODE BEGIN 1 */
unsigned char uTx_Data[] = "\r\n Hallo World! 你好,世界!";
/* USER CODE END 1 */

4)在main主函数的while循环中调用字符串发送函数

   /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
/* 字符串发送 */
vUser_UART_SendString(&huart1, uTx_Data);
/* 延迟1s */
HAL_Delay();
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */

整个main函数如下:

 int main(void)
{
/* USER CODE BEGIN 1 */
unsigned char uTx_Data[] = "\r\n Hallo World! 你好,世界!";
/* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */
SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
/* UART发送 */
vUser_UART_SendString(&huart1, uTx_Data);
/* 延迟1s */
HAL_Delay();
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

5)编译、下载烧写

6)实现效果(在PC端串口助手显示发送成功)

3、printf发送

说明:

  这种发送方式就是相当于编写c语言的时候,在小黑框中打印自己想要打印的东西,我们也可以在串口助手上实现一样的功能。

  由于篇幅长度有限,可能需要后续有空再补上这一发送方式,在这里先不讲解了。

四、结尾

1、总结

  这篇博客主要是以上一篇UART详解为基础,来实现使用UART来实现发送功能,在这里简单讲解了两种发送方式,而在后续如果有机会还会补上第三种printf发送方式的。

  如果大家还不清楚UART串口通信协议的,可以阅读一下上一篇UART详解。若还有对于此篇博客不懂之处,可在下方留言评论,我会尽快回复。

2、回顾

1)UART详解

3、后续

1)UART接收

2)待补充

~

~

~

~

感谢阅读~

欢迎大家关注我的博客,一起分享嵌入式知识~

基于STM32之UART串口通信协议(二)发送的更多相关文章

  1. 基于STM32之UART串口通信协议(四)Printf发送

    一.前言 1.简介 前面在UART发送中已经讲解过如何调用HAL库的HAL_UART_Transmit函数来实现串口发送,而在调用这个函数来实现串口发送的话,但是在发送数据或者字符的时候,需要将数据或 ...

  2. 基于STM32之UART串口通信协议(一)详解

    一.前言 1.简介 写的这篇博客,是为了简单讲解一下UART通信协议,以及UART能够实现的一些功能,还有有关使用STM32CubeMX来配置芯片的一些操作,在后面我会以我使用的STM32F429开发 ...

  3. 基于STM32之UART串口通信协议(三)接收

    一.前言 1.简介 回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作. 2.UART简介 嵌入式开发中,UART串口通信协议是我们 ...

  4. 基于STM8的UART发送和中断接收---STM8-第二章

    1. 综述 UART的基础知识,通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器. 做软件开发的人都 ...

  5. STM32 HAL库 UART 串口读写功能笔记

    https://www.cnblogs.com/Mysterious/p/4804188.html STM32L0 HAL库 UART 串口读写功能 串口发送功能: uint8_t TxData[10 ...

  6. STM32 Bootloader基于ymodem传输协议串口IAP升级详解

    硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...

  7. 基于ZYNQ 的UART中断实验之串口写数据到DDR3中

    1.参考 UG585 网络笔记 2.理论知识 参见上一次实验:基于ZYNQ 的UART中断实验 3.实验目的 练习使用UART的中断实验,并将接收到的数据写入到DDR3中. 4.实验过程 建立工程,设 ...

  8. stm32中的串口通信你了解多少

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

  9. 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)

    本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...

随机推荐

  1. ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 视图 花了几章节,终于把 ASP.NET Core MVC 中的 C 控 ...

  2. UWP 应用中的Back button(TitleBar) 的处理

    后退按钮是一项系统提供的 UI 提示,可以在后退堆栈或用户导航历史记录中支持向后导航. 用起来其实也是很简单的,只需要在App.xaml.cs 中修改(添加)如下红色代码,便可实现.. sealed ...

  3. libuv windows 下编译及使用出现的问题(异步IO)

    1. 下载源码:http://dist.libuv.org/dist/ 我下载的是 v1.8.0 版本,打开可看见四个文件,如下: 说明:.tar.gz 版本的是可以在Linux和Windows下编译 ...

  4. .Net Core中使用NodeJs加解密DES,MD5,AES,REA

    鉴于使用.net core我们的加解密也同时迁移到了跨平台上,我使用的是NodeJs加解密的.废话不多说了,还是来干活吧. 1.创建Node项目 2.添加package.json {  "n ...

  5. 自定义View实现图片热区效果

    我司主要从事工业物联网领域软件的开发,现有个需求,在外废品处理时需要对产品的不良位置进行标记,点选图片实现图片网格的着色功能. 需求是通过自定义view来实现,实现思路如下: 首先将点击的小方格对象实 ...

  6. Winform 点击TreeView控件节点的CheckBox不触发NodeMouseClick事件的做法

    private void Tv_areainfo_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (!e.Node. ...

  7. SqlServer 无法为可更新的订阅设置发布服务器登录名 sp_link_publication

    原文:SqlServer 无法为可更新的订阅设置发布服务器登录名 sp_link_publication 没有截图: 创建可更新订阅,正常创建了发布,在订阅端创建订阅,最后一步提示完成,却出现了警告: ...

  8. Linux文件系统操作与磁盘管理

    简单文件操作 df---->report file system disk space usage du---->estimate file space usage 2.简单的磁盘管理 d ...

  9. Delphi 屏幕抓图技术的实现

    摘 要:本文以Delphi7.0作为开发平台,给出了网络监控软件中的两种屏幕抓图技术的设计方法和步骤.介绍了教师在计算机机房内教学时,如何监控学生计算机显示器上的画面,以保证教学的质量和效果. 引言 ...

  10. 一顶博士帽能带来什么——访GOOGLE公司中国区总裁李开复

      在读了博士生远潇给本报的来信后,GOOGLE公司中国区总裁李开复说,有这些困惑和担心,实际上是很多博士生们在读博士之前并没有认真地想过,自己是不是能耐得住寂寞做学问,是不是能抵御来自物质世界的诱惑 ...