注意是UART4,不是USART4
在stm32中UART和USART是不相同的
USART是通用同步/異步串行接收/發(fā)送器
UART是通用異步收發(fā)傳輸器
簡單區(qū)分同步和異步就是看通信時需不需要對外提供時鐘輸出,我們平時用的串口通信基本都是 UART。
USART支持同步模式,因此USART 需要同步時鐘信號USART_CK(如STM32 單片機(jī)),通常情況同步信號很少使用,因此一般的單片機(jī)UART和USART使用方式是一樣的,都使用異步模式。
UART需要固定的波特率,就是說兩位數(shù)據(jù)的間隔要相等。 UART總線是異步串口,一般由波特率產(chǎn)生器(產(chǎn)生的波特率等于傳輸波特率的16倍)、UART接收器、UART發(fā)送器組成,硬件上有兩根線,一根用于發(fā)送,一根用于接收。 顯然,如果用通用IO口模擬UART總線,則需一個輸入口,一個輸出口。
UART是一個并行輸入成為串行輸出的芯片,通常集成在主板上,多數(shù)是16550AFN芯片。因為計算機(jī)內(nèi)部采用并行數(shù)據(jù),不能直接把數(shù)據(jù)發(fā)到Modem,必須經(jīng)過UART整理才能進(jìn)行異步傳輸,其過程為:CPU先把準(zhǔn)備寫入串行設(shè)備的數(shù)據(jù)放到UART的寄存器(臨時內(nèi)存塊)中,再通過FIFO(First Input First Output,先入先出隊列)傳送到串行設(shè)備,若是沒有FIFO,信息將變得雜亂無章,不可能傳送到Modem。
作為接口的一部分,UART還提供以下功能:將由計算機(jī)內(nèi)部傳送過來的并行數(shù)據(jù)轉(zhuǎn)換為輸出的串行數(shù)據(jù)流。將計算機(jī)外部來的串行數(shù)據(jù)轉(zhuǎn)換為字節(jié),供計算機(jī)內(nèi)部使用并行數(shù)據(jù)的器件使用。在輸出的串行數(shù)據(jù)流中加入奇偶校驗位,并對從外部接收的數(shù)據(jù)流進(jìn)行奇偶校驗。在輸出數(shù)據(jù)流中加入啟停標(biāo)記,并從接收數(shù)據(jù)流中刪除啟停標(biāo)記。處理由鍵盤或鼠標(biāo)發(fā)出的中斷信號(鍵盤和鼠標(biāo)也是串行設(shè)備)??梢蕴幚碛嬎銠C(jī)與外部串行設(shè)備的同步管理問題。
USART收發(fā)模塊一般分為三大部分:時鐘發(fā)生器、數(shù)據(jù)發(fā)送器和接收器??刂萍拇嫫鳛樗械哪K共享。時鐘發(fā)生器由同步邏輯電路(在同步從模式下由外部時鐘輸入驅(qū)動)和波特率發(fā)生器組成。發(fā)送時鐘引腳XCK僅用于同步發(fā)送模式下,發(fā)送器部分由一個單獨的寫入緩沖器(發(fā)送UDR)、一個串行移位寄存器、校驗位發(fā)生器和用于處理不同湞結(jié)構(gòu)的控制邏輯電路構(gòu)成。使用寫入緩沖器,實現(xiàn)了連續(xù)發(fā)送多湞數(shù)據(jù)無延時的通信。接收器是USART模塊最復(fù)雜的部分,最主要的是時鐘和數(shù)據(jù)接收單元。數(shù)據(jù)接收單元用作異步數(shù)據(jù)的接收。除了接收單元,接收器還包括校驗位校驗器、控制邏輯、移位寄存器和兩級接收緩沖器(接收UDR)。接收器支持與發(fā)送器相同的幀結(jié)構(gòu),同時支持楨錯誤、數(shù)據(jù)溢出和校驗錯誤的檢測。USART是一個全雙工通用同步/異步串行收發(fā)模塊,該接口是一個高度靈活的串行通信設(shè)備。
綜上可以看出,USART相對UART來說是在異步通信的基礎(chǔ)上還有同步的功能,USART能夠提供主動時鐘。
UAST4的配置
注意:在使用UART4之前,首先要確保你的單片機(jī)是支持UART4的(我用到的單片機(jī)是STM32F103vet6),具體是否支持UART4,可以參考數(shù)據(jù)手冊。同時要注意,UART4是掛載到APB1總線上的!
初始化程序:
為了方便調(diào)試輸出,我將USART1也進(jìn)行了初始化,對比一下不難發(fā)現(xiàn)UASRT1的初始化和UART4的初始化幾乎相同
GPIO_InitTypeDefGPIO_InitStructure;
USART_InitTypeDefUSART_InitStructure;
/*configUSART1clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);//注意UART4是掛載在APB1總線上的,用RCC_APB1PeriphClockCmd()函數(shù)初始化!
/*USART1GPIOconfig*/
/*ConfigureUSART1Tx(PA.09)asalternatefunctionpush-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);
/*ConfigureUSART1Rx(PA.10)asinputfloating*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/*USART1modeconfig*/
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);
//3?ê??ˉUART4-TX-PC10
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
//UART-RX-PC11
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
USART_InitStructure.USART_BaudRate=9600;
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(UART4,&USART_InitStructure);
USART_Cmd(UART4,ENABLE);
USART_ClearFlag(UART4,USART_FLAG_TC);