完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
一、UART和USART简介
UART串口通信协议全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输,它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外部设备进行全双工数据交换。 USART串口通信协议全称叫做通用同步异步收发传输器(universal synchronous asynchronous receiver and transmitter),USART相比较UART支持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。 USART框图如下: 二、UART通信协议 1)起始位 当未有数据发送时,数据线处于逻辑“1”状态;先发出一个逻辑“0”信号,表示开始传输字符。 2)数据位 紧接着起始位之后。资料位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟定位。 3)奇偶校验位 资料为加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。 4)停止位 它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。 5)空闲位或起始位 处于逻辑“1”状态,表示当前线路上没有资料传送,进入空闲状态。 处于逻辑“0”状态,表示开始传送下一数据段。 6)波特率 表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。 常用的波特率有:9600、115200…… 时间间隔计算:1秒除以波特率得出的时间,例如,波特率为9600的时间间隔为1s / 9600(波特率) = 104us。 三、UART功能说明 接口通过三个引脚从外部连接到其它设备。任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX): RX:接收数据输入引脚就是串行数据输入引脚。过采样威廉希尔官方网站 可区分有效输入数据和噪声,从而用于恢复数据。 TX:发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O 用于发送和接收数据(USART 电平下,随后在 SW_RX 上接收数据)。 1)正常 USART 模式下,通过这些引脚以帧的形式发送和接收串行数据:
1)发送接收 发送逻辑对从发送FIFO 读取的数据执行“并→串”转换。控制逻辑输出起始位在先的串行位流,并且根据控制寄存器中已编程的配置,后面紧跟着数据位(注意:最低位 LSB 先输出)、奇偶校验位和停止位。 在检测到一个有效的起始脉冲后,接收逻辑对接收到的位流执行“串→并”转换。此外还会对溢出错误、奇偶校验错误、帧错误和线中止(line-break)错误进行检测,并将检测到的状态附加到被写入接收FIFO 的数据中。 2)波特率产生 波特率除数(baud-rate divisor)是一个22 位数,它由16 位整数和6 位小数组成。波特率发生器使用这两个值组成的数字来决定位周期。通过带有小数波特率的除法器,在足够高的系统时钟速率下,UART 可以产生所有标准的波特率,而误差很小。 3)数据收发 发送时,数据被写入发送FIFO。如果UART 被使能,则会按照预先设置好的参数(波特率、数据位、停止位、校验位等)开始发送数据,一直到发送FIFO 中没有数据。一旦向发送FIFO 写数据(如果FIFO 未空),UART 的忙标志位BUSY 就有效,并且在发送数据期间一直保持有效。BUSY 位仅在发送FIFO 为空,且已从移位寄存器发送最后一个字符,包括停止位时才变无效。即 UART 不再使能,它也可以指示忙状态。 在UART 接收器空闲时,如果数据输入变成“低电平”,即接收到了起始位,则接收计数器开始运行,并且数据在Baud16 的第8 个周期被采样。如果Rx 在Baud16 的第8 周期仍然为低电平,则起始位有效,否则会被认为是错误的起始位并将其忽略。 如果起始位有效,则根据数据字符被编程的长度,在 Baud16 的每第 16 个周期(即一个位周期之后)对连续的数据位进行采样。如果奇偶校验模式使能,则还会检测奇偶校验位。 最后,如果Rx 为高电平,则有效的停止位被确认,否则发生帧错误。当接收到一个完整的字符时,将数据存放在接收FIFO 中。 4)中断控制 出现以下情况时,可使UART 产生中断: 由于所有中断事件在发送到中断控制器之前会一起进行“或运算”操作,所以任意时刻 UART 只能向中断产生一个中断请求。通过查询中断状态函数,软件可以在同一个中断服务函数里处理多个中断事件(多个并列的if 语句)。 5)FIFO 操作 FIFO 是“First-In First-Out”的缩写,意为“先进先出”,是一种常见的队列操作。 Stellaris 系列ARM 的UART 模块包含有2 个16 字节的FIFO:一个用于发送,另一个用于接收。可以将两个FIFO 分别配置为以不同深度触发中断。可供选择的配置包括:1/8、 1/4、1/2、3/4 和7/8 深度。例如,如果接收FIFO 选择1/4,则在UART 接收到4 个数据时产生接收中断。 发送FIFO的基本工作过程: 只要有数据填充到发送FIFO 里,就会立即启动发送过程。由于发送本身是个相对缓慢的过程,因此在发送的同时其它需要发送的数据还可以继续填充到发送 FIFO 里。当发送 FIFO 被填满时就不能再继续填充了,否则会造成数据丢失,此时只能等待。这个等待并不会很久,以9600 的波特率为例,等待出现一个空位的时间在1ms 上下。发送 FIFO 会按照填入数据的先后顺序把数据一个个发送出去,直到发送 FIFO 全空时为止。已发送完毕的数据会被自动清除,在发送FIFO 里同时会多出一个空位。 接收FIFO的基本工作过程: 当硬件逻辑接收到数据时,就会往接收FIFO 里填充接收到的数据。程序应当及时取走这些数据,数据被取走也是在接收FIFO 里被自动删除的过程,因此在接收 FIFO 里同时会多出一个空位。如果在接收 FIFO 里的数据未被及时取走而造成接收FIFO 已满,则以后再接收到数据时因无空位可以填充而造成数据丢失。 收发FIFO 主要是为了解决UART 收发中断过于频繁而导致CPU 效率不高的问题而引入的。在进行 UART 通信时,中断方式比轮询方式要简便且效率高。但是,如果没有收发 FIFO,则每收发一个数据都要中断处理一次,效率仍然不够高。如果有了收发FIFO,则可以在连续收发若干个数据(可多至14 个)后才产生一次中断然后一并处理,这就大大提高了收发效率。 完全不必要担心FIFO 机制可能带来的数据丢失或得不到及时处理的问题,因为它已经帮你想到了收发过程中存在的任何问题,只要在初始化配置UART 后,就可以放心收发了, FIFO 和中断例程会自动搞定一切。 五、程序配置 /***************************** UART_Config USART2 GPIO���ã�����ģʽ���� ********************************/ void UART2_Config(void) { GPIO_InitTypeDef GPIO_IS; USART_InitTypeDef USART_IS; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /*���ô���ʱ��*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); /*USART1 GPIO Config*/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1); /*Configure USART1 TX RX as alternate function*/ GPIO_IS.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3; GPIO_IS.GPIO_Mode = GPIO_Mode_AF; GPIO_IS.GPIO_Speed = GPIO_Speed_50MHz; GPIO_IS.GPIO_OType = GPIO_OType_PP; GPIO_IS.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_IS); /*USART1 MODE CONFIG*/ USART_IS.USART_BaudRate = 115200; USART_IS.USART_WordLength = USART_WordLength_8b; USART_IS.USART_StopBits = USART_StopBits_1; USART_IS.USART_Parity = USART_Parity_No; USART_IS.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_IS.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_Init(USART2,&USART_IS); USART_Cmd(USART2,ENABLE); USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); //USART_ITConfig(USART2,USART_IT_ORE,DISABLE); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 六、碰到的问题 1)引脚复用导致的问题 串口引脚复用功能没有打开造成串口运行不正常 /*串口复用功能打开*/ GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1); 2)串口频繁进入中断导致的问题 串口只打开接收中断会发现有时串口会一直进入ore中断,这个标志位不清除掉,就会一直进入这个中断,按照下面的流程去处理串口中断就可以避免这个问题了。 void USART1_IRQHandler(void) { if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) { USART_ReceiveData(USART1); USART_ClearFlag(USART1, USART_FLAG_ORE); } if( USART_GetITStatus(USART1,USART_IT_RXNE) != RESET ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); USART_ClearFlag(USART1,USART_IT_RXNE); Uart1_Val.Real_Data = USART_ReceiveData( USART1 ); Uart1_IT_Reci_Fuc(); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1932 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1705 浏览 1 评论
1185 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
785 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1750 浏览 2 评论
1992浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
827浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
279浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
637浏览 3评论
644浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-2-2 18:04 , Processed in 0.673116 second(s), Total 43, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号