RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。
● 总线在发送或接收前应处于空闲状态 ● 一个起始位
● 一个数据字(8或9位),最低有效位在前
● 0.5,1.5,2个的停止位,由此表明数据帧的结束
● 使用分数波特率发生器 —— 12位整数和4位小数的表示方法。 ● 一个状态寄存器(USART_SR) ● 数据寄存器(USART_DR)
● 一个波特率寄存器(USART_BRR),12位的整数和4位小数 ● 一个智能卡模式下的保护时间寄存器(USART_GTPR)
25.6517/754
关于以上寄存器中每个位的具体定义,请参考寄存器描述第节:USART寄存器描述。
发送配置步骤: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或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。
单字节通信
清零TXE位总是通过对数据寄存器的写操作来完成的。TXE位由硬件来设置,它表明: ● 数据已经从TDR移送到移位寄存器,数据发送已经开始 ● TDR寄存器被清空
● 下一个数据可以被写进USART_DR寄存器而不会覆盖先前的数据 如果TXEIE位被设置,此标志将产生一个中断。
如果此时USART正在发送数据,对USART_DR寄存器的写操作把数据存进TDR寄存器,并在当前传输结束时把该数据复制进移位寄存器。
如果此时USART没有在发送数据,处于空闲状态,对USART_DR寄存器的写操作直接把数据放进移位寄存器,数据传输开始,TXE位立即被置起。
当一帧发送完成时(停止位发送后)并且设置了TXE位,TC位被置起,如果USART_CR1寄存器中的TCIE位被置起时,则会产生中断。
字符接收
在USART接收期间,数据的最低有效位首先从RX脚移进。在此模式里,USART_DR寄存器包含的缓冲器位于内部总线和接收移位寄存器之间。 配置步骤: 1. 将USART_CR1寄存器的UE置1来激活USART。 2. 编程USART_CR1的M位定义字长 3. 在USART_CR2中编写停止位的个数
4. 如果需多缓冲器通信,选择USART_CR3中的DMA使能位(DMAR)。按多缓冲器通信所要求的配置DMA寄存器。
5. 利用波特率寄存器USART_BRR选择希望的波特率。
6.
设置USART_CR1的RE位。激活接收器,使它开始寻找起始位。
当一字符被接收到时,
● RXNE位被置位。它表明移位寄存器的内容被转移到RDR。换句话说,数据已经被接收并且
可以被读出(包括与之有关的错误标志)。 ● 如果RXNEIE位被设置,产生中断。
● 在接收期间如果检测到帧错误,噪音或溢出错误,错误标志将被置起,
● 在多缓冲器通信时,RXNE在每个字节接收后被置起,并由DMA对数据寄存器的读操作而
清零。 ● 在单缓冲器模式里,由软件读USART_DR寄存器完成对RXNE位清除。RXNE标志也可以通
过对它写0来清除。RXNE位必须在下一字符接收结束前被清零,以避免溢出错误。
注意: 在接收数据时,RE位不应该被复位。如果RE位在接收时被清零,当前字节的接收被丢失。
多处理器通信
通过USART可以实现多处理器通信(将几个USART连在一个网络里)。例如某个USART设备可以是主,它的TX输出和其他USART从设备的RX输入相连接;USART从设备各自的TX输出逻辑地与在一起,并且和主设备的RX输入相连接。
在多处理器配置中,我们通常希望只有被寻址的接收者才被激活,来接收随后的数据,这样就可以减少由未被寻址的接收器的参与带来的多余的USART服务开销。
单线半双工通信
单线半双方模式通过设置USART_CR3寄存器的HDSEL位选择。在这个模式里,下面的位必须保持清零状态:
● USART_CR2寄存器的LINEN和CLKEN位 ● USART_CR3寄存器的SCEN和IREN位
USART可以配置成遵循单线半双工协议。在单线半双工模式下,TX和RX引脚在芯片内部互连。使用控制位”HALF DUPLEX SEL”(USART_CR3中的HDSEL位)选择半双工和全双工通信。 当HDSEL为’1’时 ● RX不再被使用
● 当没有数据传输时,TX总是被释放。因此,它在空闲状态的或接收状态时表现为一个标准
I/O口。这就意味该I/O在不被USART驱动时,必须配置成悬空输入(或开漏的输出高)。 除此以外,通信与正常USART模式类似。由软件来管理线上的冲突(例如通过使用一个中央仲裁器)。特别的是,发送从不会被硬件所阻碍。当TE位被设置时,只要数据一写到数据寄存器上,发送就继续。
/**
* @brief USART1 GPIO ÅäÖÃ,¹¤×÷ģʽÅäÖá£115200 8-N-1
* @param ÎÞ
* @retval ÎÞ
*/
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* config USART1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = 115200;
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);
USART_Cmd(USART1, ENABLE);
}
/// Öض¨Ïòc¿âº¯Êýprintfµ½USART1
int fputc(int ch, FILE *f)
{
/* ·¢ËÍÒ»¸ö×Ö½ÚÊý¾Ýµ½USART1 */
USART_SendData(USART1, (uint8_t) ch);
/* µÈ´ý·¢ËÍÍê±Ï */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return (ch);
}
/// Öض¨Ïòc¿âº¯Êýscanfµ½USART1
int fgetc(FILE *f)
{
/* µÈ´ý´®¿Ú1ÊäÈëÊý¾Ý */
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(USART1);
}
/**************
int main(void)
{
/* USART1 config 115200 8-N-1 */
USART1_Config();
USART1_DMA_Config();
LED_GPIO_Config();
printf("\r\n usart1 DMA TX ²âÊÔ \r\n");
{
uint16_t i;
/*Ìî³ä½«Òª·¢Ë͵ÄÊý¾Ý*/
for(i=0;i<SENDBUFF_SIZE;i++)
{
SendBuff[i]
= 'A';
}
}
/* USART1 Ïò DMA·¢³öTXÇëÇó */
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
/* ´ËʱCPUÊÇ¿ÕÏеģ¬¿ÉÒÔ¸ÉÆäËûµÄÊÂÇé */
//ÀýÈçͬʱ¿ØÖÆLED
for(;;)
{
LED1(ON);
Delay(0xFFFFF);
LED1(OFF);
Delay(0xFFFFF);
}
}
来源:CSDN
作者:zhengyad
链接:https://blog.csdn.net/u012306024/article/details/44773867