USARTx是用的GPIOx的引脚,所以在使用USARTx时除了要打开USARTx模块时还需要打开使用对应TX,RX引脚所对应的GPIOx时钟。
USART(Universal Synchronous AsynchronousReceiver Transmitter,通用同步异步收发器)。具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备,USART通道可以非常方便的实现串行通信。
STM32F10XXX芯片至少用两个引脚让其内的USART通道跟其它设备相连。STM32F10XXX芯片提供发送数据引脚(TX)与接收数据引脚(RX)两个引脚与RS-232规格设备(如Max232)相连。外加一个控制引脚(CX)与RS-485规格的设备(如Max485)相连。
USART通道在STM32F10XX芯片内,使用USART收/发数据需要依靠其通信原理。
USART发送器发送的数据的走向为“USART_DR寄存器”à“发送移位寄存器”à“TX引脚”。数据流经TX后就标志着将STM32F10XX芯片内的数据发送到芯片外部了,可由其它模块(如MAX485)来接收STM32F10XX发送出来的数据。USART_DR寄存器中的数据是用户直接写入的。
STM32F10XX USART发送数据的具体过程可用下图表述:
Figure1:USART_发送单字节原理
用这个图描述USART发送器显得有些抽象,还得配点文字说明。
A. 此模式下USART_DR寄存器的数据缓冲器(TDR)位于内部总线与发送移位寄存器之间。
B. 如果此时USART正在发送数据,对USART_DR寄存器的写操作把数据存进TDR寄存器,并在当前传输结束时(发送移位寄存器内的数据传输结束时)把该数据复制进移位寄存器。即数据传输路线为1号线。
如果此时USART没有在发送数据,处于空闲状态,对USART_DR寄存器的写操作直接把数据放进移位寄存器后,数据开始被传输。即数据走的是2号线。
Figure2:USART接收单字符
RS232是一种标准。前缀“RS”表示“标准”的含义(EIA 提出的建议)。根据RS232标准,制造出了满足此标准的芯片,如Max232芯片,用此芯片接收数据的引脚就可以接收来自STMF10XXX发送数据引脚(TX)的数据,用此芯片发送数据的引脚就可以向STMF10XX接收数据引脚(RX)发送数据。由此而形成STM32F10XX芯片与MAX232芯片之间的通信。
Figure3:串口线公头
在这里,PC 与STM3210XX 就是用串口线相连。STMF10XXX芯片USART通道的数据通过TX引脚传输给MAX232,MAX232通过接收数据引脚T1IN将接收到的数据通过T1OUT发送到串口线的RXD引脚上,然后串口线就通过RXD引脚对应的线将数据发送到电脑中对应通信模块上。反过来,当电脑向STM3210XX发送数据时,电脑通过串口线的TXD引脚将数据发送到MAX232的R1IN引脚上,MAX232再将R1IN之上的数据通过R1OUT发给STM32F10XX的RX引脚,再到USART通道。
USART初始化包含三个方面:
//初始化USART1 void USART1_Init( void ) { //开启USART1时钟,#define USART1_RCC_EN ( 1 << 14 ) RCC->APB2ENR |= USART1_RCC_EN; //使能USART(UE),8位数据位(M),一位停止位 // USART_EN: (0x2000), USART_DATA_8:(0x0000), USART_STOP_BIT_1: (0x0000) USART1->CR1 |= USART_EN | USART_DATA_8 ; USART1->CR2 |= USART_STOP_BIT_1; //设置USART1传送数据时的波特率,此值对应的波特率为9600 USART1->BRR= 0x1d4c; } //USART1 TX引脚配置 void USART1_GPIO_Init( void ) { //开启GPIOA时钟,GPIOA_RCC_EN:( 1 << 2 ) RCC->APB2ENR |= GPIOA_RCC_EN; //将TX引脚写0 GPIOA->CRH &= 0xffffff0f; //将TX引脚配置复用功能推挽输出模式 GPIOA->CRH |= GPIOA_PIN_9_TX; } |
//发送字符串函数 void USART_Sent(unsigned char *data, int len) { int i; for(i = 0; i < len; ++i) USART_SendByte( data[i] ); } //USART1发送字符函数 void USART_SendByte( uint16_t byte ) { //等TDR缓冲区的数据被复制到发送移位寄存器中 // USART_TXE_FLAG:(0x0080) while( !(USART_TXE_FLAG & USART1->SR) ); //TDR数据已被复制,可写入新数据 USART1->DR= ( byte & (uint16_t)0x01FF); } |
int main( void ) { USART1_Init( ); USART1_GPIO_Init( ); //使能USART1发送器功能,USART_TE_EN:(0x0008) USART1->CR1 |= USART_TE_EN ; while( 1 ){ USART_Sent( (unsigned char *)("Hello, Mxl, Another Nice Day\n"), sizeof( "Hello, Mxl, Another Nice Day\n" ) ) } } |