一:STM32F103VE串口知识:
通用同步异步收发器(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:清除发送,若是高电平,在当前数据传输结束时阻断下一次的数据发送。
二:配置步骤如下:
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软件中配置如下所示:
如上图所示:STM32F103VE芯片的串口1 与DAP的串口相连接,这里我们配置串口1的参数信息。
3.1 配置串口1的基本的串口通讯参数
3.2 使能DMA的收发功能(为下一个章节做准备)
3.3 使能串口1的中断服务函数,并且配置优先级别。
配置完成之后,参考之前的帖子 直接进行生成就可以了。
四:软件编写过程:
4.1 编写串口的基本流程:
首先串口时钟使能,GPIO时钟使能: __HAL_RCC_ART1_CLK_ENABLE();
GPIO端口模式设置: __HAL_RCC_GPIOA_CLK_ENABLE();
串口参数初始化:static void MX_UART1_UART_Init(void)
开启中断并且初始化 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
使能串口: HAL_NVIC_EnableIRQ(USART1_IRQn);
编写串口发送函数:重映射PRINTF 函数进行数据的发送。
4.2 串口初始化
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
定义一个输出字符串,并在定时器6回调函数中,1S的时间中断进行调用。
static unsigned char outputchar[] ={ "nebula pi STM32F103VE usart1 test \r\n" } ;
在回调函数中调用,代码如下所示:
if(Time6point %1000 == 0)
{
Time6point = 0 ;
// HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_4);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_3);
HAL_UART_Transmit(&huart1, outputchar, sizeof(outputchar), 0xffff);
}
打开 RYMCU的串口工具进行查看:
实测,串口1的输出功能正常。
方法二:使用重映射进行串口的输出:
添加几个头文件
#include "stdio.h"
#include "string.h"
#include "stdint.h"
重映射函数如下:
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
需要使能 microlib功能
全部评论