RVMCU課堂「13」: 手把手教你玩轉(zhuǎn)RVSTAR—UART通信篇
系統(tǒng)環(huán)境
軟件平臺
硬件需求
通用同步異步收發(fā)器(USART)提供了一個靈活方便的串行數(shù)據(jù)交換接口,數(shù)據(jù)幀可以通過全雙工或半雙工,同步或異步的方式進行傳輸。USART提供了可編程的波特率發(fā)生器及奇偶校驗位、數(shù)據(jù)位和停止位等可編程的串口特性。它還支持多處理器通信、多種狀態(tài)標志和硬件流控操作(CTS/RTS)。另外,USART還支持DMA功能,以實現(xiàn)高速率的數(shù)據(jù)通信(除了UART4)。
RV-STAR的USB UART電路
在之前的文章中介紹過,RV-STAR的開發(fā)板上使用了一個雙端口的FT2232 USB設(shè)備芯片,一個端口用于JTAG調(diào)試,另一個端口可建立開發(fā)板到電腦的串口連接,其電路原理圖如下:
實驗1是讓RV-STAR開發(fā)板接收從PC主機發(fā)送的字符,再回發(fā)給PC主機。在進行UART編程的時候,首先需要對UART外設(shè)進行初始化,代碼片段如下:
void uart_init()
{
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_UART4);
// UART4_TX - PC12
gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
// UART4_RX - PD2
gpio_init(GPIOD, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
usart_deinit(UART4);
usart_baudrate_set(UART4, 115200U);
usart_word_length_set(UART4, USART_WL_8BIT);
usart_stop_bit_set(UART4, USART_STB_1BIT);
usart_parity_config(UART4, USART_PM_NONE);
usart_hardware_flow_rts_config(UART4, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(UART4, USART_CTS_DISABLE);
usart_receive_config(UART4, USART_RECEIVE_ENABLE);
usart_transmit_config(UART4, USART_TRANSMIT_ENABLE);
usart_enable(UART4);
}
首先需要初始化外設(shè)時鐘,然后將發(fā)送引腳初始化為推挽輸出模式、接收引腳初始化為浮空輸入模式,然后依次設(shè)置UART4的波特率(115200)、數(shù)據(jù)位(8位)、停止位(1位)、奇偶校驗位(無)、硬件流控以及使能收發(fā)器。UART發(fā)送器和接收器支持若干個中斷事件,為了保證接收數(shù)據(jù)的完整和及時,我們通常使用中斷的方式處理數(shù)據(jù)的接收,因此需要在主程序開始時進行中斷使能,這里使用非向量模式中斷,當(dāng)接收器接受到數(shù)據(jù)幀,其狀態(tài)寄存器的RBNE產(chǎn)生置位時觸發(fā)中斷,其代碼片段如下:
int main()
{
uart_init();
ECLIC_Register_IRQ(UART4_IRQn, ECLIC_NON_VECTOR_INTERRUPT, ECLIC_LEVEL_TRIGGER, 1, 0, NULL);
__enable_irq();
usart_interrupt_enable(UART4, USART_INT_RBNE);
while (1);
}
主程序中只進行外設(shè)初始化和中斷使能,接收字符和回傳因為時間極短,可以都在中斷服務(wù)程序中處理:使用字符型變量c保存使用usart_data_receive()接收到的數(shù)據(jù),然后再使用usart_data_transmit()發(fā)送出去(每次發(fā)送數(shù)據(jù)幀,需要等待USART_FLAG_TBE置位后再發(fā)送下一幀)。
{
if (RESET != usart_interrupt_flag_get(UART4, USART_INT_FLAG_RBNE))
{
uint8_t c = usart_data_receive(UART4);
usart_data_transmit(UART4, c);
while (SET != usart_flag_get(UART4, USART_FLAG_TBE));
}
}
完成代碼編寫后,連接開發(fā)板,編譯并上傳代碼。為了屏蔽不同IDE的串口終端的差異,我們使用通用的PC串口軟件CoolTerm來觀察串口實驗的現(xiàn)象,它是一個免費而功能強大的串口調(diào)試軟件。
在發(fā)送窗口中,輸入字符,然后點擊“Send”發(fā)送,會發(fā)現(xiàn)RV-STAR將字符進行了回傳,并打印顯示在了終端窗口中。
實驗2:控制板載RGB LED
實驗2是通過PC主機向RV-STAR的串口發(fā)送'r','g','b'三種不同的字符,用以控制RV-STAR的板載RGB LED產(chǎn)生不同的亮光。和實驗1的回傳字符程序不同的地方是,實驗2的代碼里使用了一個char類型的全局變量led_color作為主程序和中斷服務(wù)程序的橋梁,用于存儲在中斷服務(wù)程序中接收到的字符,然后在主程序的循環(huán)體中調(diào)用函數(shù),據(jù)此變量改變led的狀態(tài)。完整代碼請參考:
實驗3:返回接收的字符串
實驗3是實驗1和實驗2的升級版,可以讓RV-STAR開發(fā)板接收從PC主機發(fā)送的一串字符串并進行回傳。其實現(xiàn)思路是:在全局變量中定義了一個數(shù)組用作接收數(shù)據(jù)的環(huán)形緩沖區(qū),每次在接收中斷里將收到的字符存入環(huán)形緩沖區(qū),在主循環(huán)中檢測接收緩沖區(qū)是否收到了一段完整的字符串(通過判斷頭尾指針和'\n'結(jié)束符),然后再將緩沖區(qū)中的字符依次傳出。在CoolTerm中的實驗現(xiàn)象參照下圖(需要鍵入一個回車光標作為結(jié)束符):