stm32 USART
2022-01-28 22:16 jym蒟蒻 阅读(322) 评论(0) 编辑 收藏 举报介绍的定义
串行通信、并行通信、全双工、半双工、单工、同步、异步、比特率、码元、波特率、TTL、RS232、DB9接口、DTE、DCE、协议层、USART、UART、CH340G芯片、USB。
根据数据传送的方式,通讯可分为串行通讯与并行通讯。
串行通信:同一时刻只能传输一个数据位的数据。串行通讯可以节省数据线的硬件成本。
并行通信:可以同时传输多个数据位的数据。因为一次可传输多个数据位的数据 ,在数据传输速率相同的情况下,并行通讯传输的数据量要大得多。使用很多数据线进行传输。
根据数据通讯的方向,通讯又分为全双工、半双工及单工通讯,它们主要以信道的方向来区分。
全双工:在同一时刻,两个设备之间可以同时收发数据。
半双工:两个设备之间可以收发数据,但不能在同一时刻进行。
单工:在任何时刻都只能进行一个方向的通讯,即一个固定为发送设备,另一个固定为接收设备。
根据通讯的数据同步方式,又分为同步和异步两种,可以根据通讯过程中是否有使用时钟信号进行简单的区分。
同步通讯:收发设备双方会使用一根信号线表示时钟信号,在时钟信号的驱动下双方进行协调,同步数据。通常双方会统一规定在时钟信号的上升沿或下降沿对数据线进行采样。在同步通讯中,数据信号所传输的内容绝大部分就是有效数据,同步通讯的效率更高。同步通讯双方的时钟允许误差较小。
异步通讯:不使用时钟信号进行数据同步,它们直接在数据信号中穿插一些同步用的信号位,或者把主体数据进行打包,以数据帧的格式传输数据,有时还需要双方约定数据的传输速率,以便更好地同步。异步通讯中会包含帧的各种标识符,异步通讯双方的时钟允许误差较大。
通讯速率:衡量通讯性能,常以比特率(Bitrate)来表示,即每秒钟传输的二进制位数,单位为比特每秒(bit/s)。
“波特率” (Baudrate):表示每秒钟传输了多少个码元。
码元:一个码元就是一个脉冲信号,一个脉冲信号有可能携带1bit数据,也有可能携带2bit数据、4bit数据。把振幅分成四种,低(00)、中(01)、高(10)、很高(11),发一个脉冲信号,携带2bit的数据。一个码元能携带1bit数据,那么比特率 = 波特率;一个码元能携带2bit数据,那么比特率 = 2倍的波特率。
根据通讯使用的电平标准不同,串口通讯可分为 TTL 标准及 RS-232 标准。
RS232标准:规定了信号的用途、通讯接口以及信号的电平标准。
两个通讯设备的“DB9 接口”之间通过串口信号线建立起连接, 串口信号线中使用“RS-232 标准”传输数据信号。由于 RS-232 电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的 “TTL 标准”的电平信号。
DB9接口如下图;DTE:数据终端设备(计算机、路由);DCE:数据通讯设备(调制解调器、猫)。通常DTE引出公头,DCE引出母头。DB9接口里面连的有TXD、RXD信号线,串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口
TTL标准:控制器一般使用 TTL 电平标准,所以常常会使用 MA3232 芯片对 TTL 及 RS-232 电平的信号进行互相转换。
协议层:规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。
USART:通用同步异步收发器,串行通信设备,可与外部设备进行全双工数据交换。串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。
UART:去掉了同步通信功能,只有异步通信。平时用的串口通信基本都是 UART。
CH340G 芯片:USB 总线的转接芯片,实现 USB 转 USART、USB 转 lrDA 红外或者 USB 转打印机接口,这里使用其 USB 转 USART 功能,原理图如下。其中的USB-MINI就是我们的USB。
用下面这个线就能把stm32和电脑连起来了。
实现开发板与电脑通信,在开发板上电时通过 USART 发送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开发板就会产生中断,中断服务函数接收数据,并马上把数据返回发送给电脑。
main里面调用 USART_Config 函数完成 USART 初始化配置,包括 GPIO 配置, USART 配置,接收中断使能,然后什么都不做,等待 USART 接收中断的产生,并在中断服务函数把数据回传。
#include "stm32f10x.h"
#include "bsp_usart.h"
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
/*初始化USART 配置模式为 115200 8-N-1,中断接收*/
USART_Config();
/* 发送一个字符串 */
Usart_SendString( DEBUG_USARTx,"这是一个串口中断接收回显实验\n");
while(1)
{
}
}
下面的NVIC_Configuration函数进行中断控制器 NVIC 的配置,配置 USART 作为中断源。
static void NVIC_Configuration(void)
下面的USART_Config函数进行USART 初始化配置,主要是设置GPIO_InitStructure和USART_InitStructure这两个结构体变量。
void USART_Config(void)
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
下面这两个函数进行字符的发送。
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
USART_Config函数整个流程大致是:
使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟; 初始化 GPIO,并将 GPIO 复用到 USART 上; 配置 USART 参数; 配置中断控制器并使能 USART 接收中断; 使能 USART;
最后在 USART 接收中断服务函数实现数据接收和发送。
#include "bsp_usart.h"
/**
* @brief 配置嵌套向量中断控制器NVIC
* @param 无
* @retval 无
*/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief USART GPIO 配置,工作参数配置
* @param 无
* @retval 无
*/
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
// 配置串口的工作参数
// 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_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(DEBUG_USARTx, &USART_InitStructure);
// 串口中断优先级配置
NVIC_Configuration();
// 使能串口接收中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
// 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
}
/***************** 发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 发送一个字节数据到USART */
USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{
uint8_t i;
for(i=0; i<num; i++)
{
/* 发送一个字节数据到USART */
Usart_SendByte(pUSARTx,array[i]);
}
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}
/***************** 发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do
{
Usart_SendByte( pUSARTx, *(str + k) );
k++;
} while