基于ARM开发板从零开始学习STM32 04-串口通信实例

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/huolu0602/article/details/102632795

    STM32 的串口不仅支持最基本的通用串口同步、异步通讯,还具有 LIN 总线功能、IRDA 功能(红外通讯)、SmartCard 功能。UART是一种通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接收。

异步串口通讯协议:

                       

我们知道要配置串口通讯,至少要设置以下几个参数: 字长(一次传送的数据长度)、波特率(每秒传输的数据位数)、奇偶校验位、还有停止位。串口外设主要由三个部分组成,分别是 波特率的控制部分、收发控制部分及数据存储转移部分。

  1. 波特率控制

波特率,即每秒传输的二进制位数,用 b/s (bps)表示,通过对时钟的控制可以改变波特率。在配置波特率时,我们向波特比率寄存器 USART_BRR 写入参数,修改了串口时钟的 分频值 USARTDIV 。 USART_BRR 寄存器 包括两部分,分别是 DIV_Mantissa (USARTDIV 的整数部分)和 DIVFraction (USARTDIV的小数)部分,最终,计算公式为USARTDIV=DIV_Mantissa+(DIVFraction/16)。

USARTDIV 是对串口外设的时钟源进行分频的,对于 USART1 ,由于它是挂载在 APB2 总线上的,所以它的时钟源为 f PCLK2 ;而 USART2、3 挂载在APB1 上,时钟源则为 f PCLK1 ,串口的时钟源经过 USARTDIV 分频后分别输出作为 发送器时钟 及 接收器时钟 ,控制发送和接收的时序。

    2.收发控制部分

围绕着发送器和接收器控制部分,有好多个寄存器:CR1、CR2、CR3、SR,即 USART 的三个 控制寄存器 (Control Register)及一个 状态寄存器 (StatusRegister)。通过向寄存器写入各种 控制参数 ,来控制发送和接收,如奇偶校验位,停止位等,还包括对 USART 中断的控制;串口的 状态 在任何时候都可以从状态寄存器中查询得到。具体的控制和状态检查,我们都是使用库函数来实现的,在此就不具体分析这些寄存器位了。

     3,.数据存储转移部分

当我们需要发送数据时,内核或 DMA 外设(一种数据传输方式,在下一章介绍)把数据从内存(变量)写入到 发送数据寄存器 TDR 后, 发送控制器 将适时地自动把数据从 TDR 加载到 发送移位寄存器 ,然后通过 串口线 Tx ,把数据 一位一位 地发送出去,在数据从 TDR 转移到 移位寄存器 时,会产生 发送寄存器TDR 已空事件 TXE ,当数据从 移位寄存器 全部发送出去时,会产生数据 发送完成事件 TC ,这些事件可以在 状态寄存器 中查询到。

而 接收数据 则是一个 逆过程 ,数据从 串口线 Rx 一位一位地输入到 接收移位寄存器 ,然后自动地转移到 接收数据寄存器 RDR ,最后用内核指令或 DMA读取到内存(变量)中。

配置串口首先调用函数  USART1_Config() , 函数 USART1_Config() 主要做了如下工作:

1. 使能了串口 1 的时钟

2. 配置好了 usart1 的 I/O

3. 配置好了 usart1 的工作模式,具体为波特率为 115200 、8 个数据位、1个停止位、无硬件流控制。

一.USART初始化配置

    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,DISABLE);
    USART_InitStructure.USART_BaudRate = BaudRate;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure); 

二.GPIO初始化配置

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

若需加入串口中断,则加入第三步,若仅需串口发送数据,则完成前两步配置即可,调用UARTX_send()函数发送数据就行。

三.NVIC配置

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_Cmd(USART1, ENABLE); 

通过以上的步骤,对串口的配置基本完成,加入中断接收数据并转发。

 

串口中断接收数据:

void USART1_IRQHandler(void)
{
 	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)	   
	{	 
	 	RS232_RX_BUF[0] =USART_ReceiveData(USART1); 
		RS232_RX_CNT=1;	
	}										 
}  

通过串口发送缓存区数据:

void RS232_Send_Data(u8 *buf,u8 len)
{
	u8 t;
  	for(t=0;t<len;t++)		
	{		   
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);	 
		USART_SendData(USART1,buf[t]);
	}	 
 
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);		
	RS232_RX_CNT=0;	  
} 

以上仅提供部分代码,完整工程已上传网盘,需要的自行下载。 链接:https://pan.baidu.com/s/1Do1VBDEZ41GHf9HhAX9lMA&shfl=sharepset 
提取码:e6dl 

猜你喜欢

转载自blog.csdn.net/huolu0602/article/details/102632795