485-串口硬件相关问题分析
uart整体框图见下表:
USART 寄存器:
usart初始化过程
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
{
uint32_t tmpreg = 0x00, apbclock = 0x00;
uint32_t integerdivider = 0x00;
uint32_t fractionaldivider = 0x00;
RCC_ClocksTypeDef RCC_ClocksStatus;
/*---------------------------- USART CR2 Configuration -----------------------*/
tmpreg = USARTx->CR2;
/*
cr2 的12,13bit是控制停止位
00 1 个停止位
01 0.5个停止位
10 2个停止位
11 1.5个停止位
*/
/* Clear STOP[13:12] bits */
tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
/* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit :
Set STOP[13:12] bits according to USART_StopBits value */
tmpreg |= (uint32_t)USART_InitStruct->USART_StopBits;
/* Write to USART CR2 */
USARTx->CR2 = (uint16_t)tmpreg;
/*---------------------------- USART CR1 Configuration -----------------------*/
tmpreg = USARTx->CR1;
/*
#define CR1_CLEAR_MASK ((uint16_t)(USART_CR1_M | USART_CR1_PCE | \
USART_CR1_PS | USART_CR1_TE | \
USART_CR1_RE))
*/
/* Clear M, PCE, PS, TE and RE bits */
tmpreg &= (uint32_t)~((uint32_t)CR1_CLEAR_MASK);
/* Configure the USART Word Length, Parity and mode:
Set the M bits according to USART_WordLength value
Set PCE and PS bits according to USART_Parity value
Set TE and RE bits according to USART_Mode value */
tmpreg |= (uint32_t)USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
USART_InitStruct->USART_Mode;
/* Write to USART CR1 */
USARTx->CR1 = (uint16_t)tmpreg;
/*---------------------------- USART CR3 Configuration -----------------------*/
tmpreg = USARTx->CR3;
/* Clear CTSE and RTSE bits */
tmpreg &= (uint32_t)~((uint32_t)CR3_CLEAR_MASK);
/* Configure the USART HFC :
Set CTSE and RTSE bits according to USART_HardwareFlowControl value */
tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
/* Write to USART CR3 */
USARTx->CR3 = (uint16_t)tmpreg;
/*---------------------------- USART BRR Configuration -----------------------*/
/* Configure the USART Baud Rate */
RCC_GetClocksFreq(&RCC_ClocksStatus);
if ((USARTx == USART1) || (USARTx == USART6))
{
apbclock = RCC_ClocksStatus.PCLK2_Frequency;
}
else
{
apbclock = RCC_ClocksStatus.PCLK1_Frequency;
}
/* Determine the integer part */
if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
{
/* Integer part computing in case Oversampling mode is 8 Samples */
integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));
}
else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
{
/* Integer part computing in case Oversampling mode is 16 Samples */
integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
}
tmpreg = (integerdivider / 100) << 4;
/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
{
tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
}
else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
{
tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
}
/* Write to USART BRR register */
USARTx->BRR = (uint16_t)tmpreg;
}
寄存器说明
位 12 M:字长 (Word length) 该位决定了字长。该位由软件置 1 或清零。 0: 1 起始位, 8 数据位, n 停止位
1: 1 起始位, 9 数据位, n 停止位 注意: 在数据传输(发送和接收)期间不得更改 M 位
位 10 PCE:奇偶校验控制使能 (Parity control enable)
该位选择硬件奇偶校验控制(生成和检测)。使能奇偶校验控制时,计算出的奇偶校验位被
插入到 MSB 位置(如果 M=1,则为第 9 位;如果 M=0,则为第 8 位),并对接收到的数据
检查奇偶校验位。此位由软件置 1 和清零。一旦该位置 1, PCE 在当前字节的后面处于活动
状态(在接收和发送时)。
0:禁止奇偶校验控制
1:使能奇偶校验控制
位 9 PS:奇偶校验选择 (Parity selection) 该位用于在使能奇偶校验生成/检测(PCE 位置
1)时选择奇校验或偶校验。该位由软件置 1 和 清零。将在当前字节的后面选择奇偶校验。 0:偶校验 1:奇校验
位 3 TE:发送器使能 (Transmitter enable) 该位使能发送器。该位由软件置 1 和清零。 0:禁止发送器
1:使能发送器 注意: 1:除了在智能卡模式下以外,传送期间 TE 位上的“0”脉冲(“0”后紧跟的是“1”)
会在当前字的后面发送一个报头(空闲线路)。 2:当 TE 置 1 时,在发送开始前存在 1 位的时间延迟
位 2 RE:接收器使能 (Receiver enable) 该位使能接收器。该位由软件置 1 和清零。 0:禁止接收器
1:使能接收器并开始搜索起始位
位 6 TC:发送完成 (Transmission complete) 如果已完成对包含数据的帧的发送并且 TXE 置 1,则该位由硬件置
1。如果 USART_CR1 寄存 器中 TCIE = 1,则会生成中断。该位由软件序列清零(读取 USART_SR 寄存器,然后写入
USART_DR 寄存器)。 TC 位也可以通过向该位写入‘0’来清零。建议仅在多缓冲区通信 时使用此清零序列。 0:传送未完成
1:传送已完成
uart 使能
USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE);
USART_ClearFlag(USART6, USART_FLAG_TC);--->USARTx->SR = (uint16_t)~USART_FLAG;
USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); //中断使能 见uart中断部分
//#define USART_CR1_UE ((uint16_t)0x2000)
//#define USART_FLAG_TC ((uint16_t)0x0040)
* @param USART_IT: specifies the USART interrupt sources to be enabled or disabled.
* This parameter can be one of the following values:
* @arg USART_IT_CTS: CTS change interrupt
* @arg USART_IT_LBD: LIN Break detection interrupt
* @arg USART_IT_TXE: Transmit Data Register empty interrupt
* @arg USART_IT_TC: Transmission complete interrupt
* @arg USART_IT_RXNE: Receive Data register not empty interrupt
* @arg USART_IT_IDLE: Idle line detection interrupt
* @arg USART_IT_PE: Parity Error interrupt
* @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
位 13 UE: USART 使能 (USART enable) 该位清零后, USART
预分频器和输出将停止,并会结束当前字节传输以降低功耗。此位由软 件置 1 和清零。 0:禁止 USART 预分频器和输出 1:使能
USART
uart 的读写流程
发送器:
步骤:
- 通过向 USART_CR1 寄存器中的 UE 位写入 1 使能 USART。
- 对 USART_CR1 中的 M 位进行编程以定义字长。
- 对 USART_CR2 中的停止位数量进行编程。
- 如果将进行多缓冲区通信,请选择 USART_CR3 中的 DMA 使能 (DMAT)。按照多缓冲区
通信中的解释说明配置 DMA 寄存器。 - 使用 USART_BRR 寄存器选择所需波特率。
- 将 USART_CR1 中的 TE 位置 1 以便在首次发送时发送一个空闲帧。
- 在 USART_DR 寄存器中写入要发送的数据(该操作将清零 TXE 位)。为每个要在单缓
冲区模式下发送的数据重复这一步骤。 - 向 USART_DR 寄存器写入最后一个数据后,等待至 TC=1。这表明最后一个帧的传送已
完成。禁止 USART 或进入暂停模式时需要此步骤,以避免损坏最后一次发送。
接收器:
字符接收
USART 接收期间,首先通过 RX 引脚移入数据的最低有效位。该模式下, USART_DR 寄存
器的缓冲区 (RDR) 位于内部总线和接收移位寄存器之间。
步骤:
- 通过向 USART_CR1 寄存器中的 UE 位写入 1 使能 USART。
- 对 USART_CR1 中的 M 位进行编程以定义字长。
- 对 USART_CR2 中的停止位数量进行编程。
- 如果将进行多缓冲区通信,请选择 USART_CR3 中的 DMA 使能 (DMAR)。按照多缓冲
区通信中的解释说明配置 DMA 寄存器。步骤 3 - 使用波特率寄存器 USART_BRR 选择所需波特率
- 将 RE 位 USART_CR1 置 1。这一操作将使能接收器开始搜索起始位。
接收到字符时
● RXNE 位置 1。这表明移位寄存器的内容已传送到 RDR。也就是说,已接收到并可读取
数据(以及其相应的错误标志)。
● 如果 RXNEIE 位置 1,则会生成中断。
● 如果接收期间已检测到帧错误、噪声错误或上溢错误,错误标志位可置 1。
● 在多缓冲区模式下,每接收到一个字节后 RXNE 均置 1,然后通过 DMA 对数据寄存器执
行读操作清零。
● 在单缓冲区模式下,通过软件对 USART_DR 寄存器执行读操作将 RXNE 位清零。 RXNE
标志也可以通过向该位写入零来清零。 RXNE 位必须在结束接收下一个字符前清零,以
避免发生上溢错误。
本文地址:https://blog.csdn.net/weixin_43836778/article/details/108577445
下一篇: VPN帮你*?还是先顾着自己的隐私再说吧
推荐阅读
-
C#启动windows服务方法的相关问题分析
-
Python基于多线程操作数据库相关问题分析
-
Flask和Django框架中自定义模型类的表名、父类相关问题分析
-
oracle数据库之相关数据字典进行性能问题分析
-
Qt5下串口编程中“QIODevice::write (QSerialPort): device not open”问题的分析处理总结
-
数据分析小白入门篇,MathorCup 无车承运人平台线路定价问题,特征间的相关性分析
-
百度黑帽SEO相关问题分析
-
485-串口硬件相关问题分析
-
Python基于多线程操作数据库相关问题分析
-
Flask和Django框架中自定义模型类的表名、父类相关问题分析