STM32F103RB板载资源串口知识:
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
串口的功能概述:
接口通过三个引脚与其他设备连接在一起(见图248)。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。
RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的IO端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。在单线和智能卡模式里,此10口被同时用于数据的发送和接收。
总线在发送或接收前应处于空闲状态
一个组数据的起始位一个数据字(8或9位),最低有效位在前0.5,1.5,2个的停止位,由此表明数据的结束使用分数波特率发生器-- 12位整数和4位小数的表示方法。一个状态寄存器(USART SR)
数据寄存器(USART DR)一个波特率寄存器(USART BRR),12位的整数和4位小数一个智能卡模式下的保护时间寄存器(USART GTPR)关于以上寄存器中每个位的具体定义,请参考寄存器描述第25.6节:USART寄存器描述。
在同步模式中需要下列引脚:CK:发送器时钟输出。此引脚输出用于同步传输的 时钟,(在Start位和Stop位上没有时钟脉冲,软件可选地,可以在最后一个数据位送出一个时钟脉冲)。数据可以在RX上同步被接收。这可以用来控制带有移位寄存器的外部设备(例如LCD驱动器)。时钟相位和极性都是软件可编程的。在智能卡模式里,CK可以为智能卡提供时钟。在IrDA模式里需要下列引脚:
IrDA RDI: IrDA模式下的数据输入。
OIrDA TDO: IrDA模式下的数据输出。
下列引脚在硬件流控模式中需要:
nCTS:清除发送,若是高电平,在当前数据传输结束时阻断下一次的数据发送。
STM32 内部框图如下所示:
字长可以通过编程USART CR1寄存器中的M位,选择成8或9位(见图249)。在起始位期间,TX脚处于低电平,在停止位期间处于高电平。空闲符号被视为完全由’1’组成的一个完整的数据帧,后面跟着包含了数据的下一帧的开始位(“1的位数也包括了停止位的位数)。
断开符号 被视为在一个帧周期内全部收到?0’(包括停止位期间,也是’0”)。在断开帧结束时,发送器再插入1或2个停止位('1’)来应答起始位。发送和接收由一共用的波特率发生器驱动,当发送器和接收器的使能位分别置位时,分别为其产生时钟。
配置步骤如下:
通过在USART CR1寄存器上置位UE位来激活USART
2编程USART CR1的M位来定义字长。
3.在USART CR2中编程停止位的位数。
4:如果采用多缓冲器通信,配置USART CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。
5.利用USART BRR寄存器选择要求的波特率。
6.设置USART CR1中的TE位,发送一个空闲帧作为第一次数据发送。
7.把要发送的数据写进USART DR寄存器(此动作清除TXE位)。在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。
8在USART DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束。当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。
二:STM32 cube Mx软件配置:
2.1 先查看原理图,确定一下板载资源的IO口配置
在上图中可能看不到引脚的使用情况,这里我简单说明一下,调试串口使用的串口2,连接到板载调试器的串口上面,这样我们在调试的过程中,只需要将调试信息输出到板载的调试口就可以,通过PC端的串口接收工具,可以将调试信息输出到串口监测引脚。
2.2 cubeMX 软件中串口2的配置过程
这里我们要记得使能串口2的发送与接收中断
配置一下,串口引脚的GPIO口的配置:如下所示:
配置好已上参数,然后直接生成代码即可。
三:程序代码的编写
3.1 编写串口的基本流程:
首先串口时钟使能,GPIO时钟使能: __HAL_RCC_ART2_CLK_ENABLE();
GPIO端口模式设置: __HAL_RCC_GPIOA_CLK_ENABLE();
串口参数初始化:static void MX_UART2_UART_Init(void)
开启中断并且初始化 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
使能串口: HAL_NVIC_EnableIRQ(USART2_IRQn);
编写串口发送函数:重映射PRINTF 函数进行数据的发送。
3.2 串口代码初始化如下:
/** * @brief USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ }
需要在生成代码中,添加下面三个文件
#include "stdio.h" #include "string.h" #include "stdint.h"
定义两个输出的数组
const uint8_t hello_str[] = "Hello !EEPW?& DigiKey! Hello STM32F103RB!\r\n"; const uint8_t Output_str[] = "Hello !Let us do it ! autor by clever !\r\n";
在定时器的回调函数中,增加数据输出的程序代码如下所示:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { /* USER CODE BEGIN Callback 0 */ /* USER CODE END Callback 0 */ /* USER CODE BEGIN Callback 1 */ if (htim->Instance == TIM1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); temp ++ ; if(temp >=2) temp = 0 ; if(temp ==1) HAL_UART_Transmit(&huart2, (uint8_t *)&Output_str, sizeof(Output_str), 0xFFFF); else HAL_UART_Transmit(&huart2, (uint8_t *)&hello_str, sizeof(hello_str), 0xFFFF); } /* USER CODE END Callback 1 */ }
试验效果如下所示:
实验截图如下:
打开串口调试工具:配置串口的波特率115200,选择端口号,配置:校验位 :无校验 停止位:1位
方法2:使用printf将数据导出,首先我们需要将串口2重映射一下
/* USER CODE BEGIN PFP */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); return ch; } /* USER CODE END PFP */
需要注意的是:将代码写在用户区,否则再次生成的时候,代码就会被覆盖;
需要配置一下代码使用lib功能,否则printf功能不能正常实现
修改定时器内的回调函数如下
if(temp ==1) printf(" Hello !EEPW?& DigiKey! Hello STM32F103RB!\r\n"); else printf(" Hello !Let us do it ! autor by clever !\r\n");
试验效果正常;至此使用串口输出数据任务完成
测试代码如下:
03usart.zip(未增加输出函数代码,大家可以尝试移植一下)
完整代码如下所示: