摘要:使用中斷方式通過接收數(shù)據(jù)實(shí)驗(yàn)?zāi)康谋竟?jié)實(shí)驗(yàn)?zāi)康臑閷?shí)現(xiàn)串口發(fā)送和接收。如果兩臺(tái)設(shè)備之間需要通過串口進(jìn)行通信,上面提到的波特率數(shù)據(jù)位停止位和奇偶校驗(yàn)位等這些必要參數(shù),必須設(shè)置一致,才能進(jìn)行串口通信。
使用中斷方式通過UART接收數(shù)據(jù)
????????本節(jié)實(shí)驗(yàn)?zāi)康臑閷?shí)現(xiàn)串口發(fā)送和接收。這一節(jié)計(jì)劃采取中斷的方式來實(shí)現(xiàn)串口接收,K210串口接收到0x00,則熄滅前節(jié)提到的紅色LED燈,并通過串口打印Red Led Off,否則,則點(diǎn)亮前節(jié)提到的紅色LED燈,并通過串口打印Red Led On。
????????1)、帶UART和發(fā)光二極管(LED)的K210開發(fā)板一塊,用于實(shí)踐并查看實(shí)驗(yàn)現(xiàn)象;
????????2)、官方裸機(jī)編程指導(dǎo)手冊(cè):kendryte_standalone_programming_guide,用于查閱SDK中接口說明。
????????串口通信是指外設(shè)和計(jì)算機(jī)間,通過數(shù)據(jù)線、地線和控制線等,按位進(jìn)行數(shù)據(jù)傳輸?shù)囊环N通信方式,傳輸方式為一個(gè)字符一個(gè)字符的傳輸,每個(gè)字符一位一位的傳輸,先傳輸?shù)臀?,再傳輸高位,并且傳輸每個(gè)字符時(shí),總是以起始位開始,以停止位結(jié)束,位于位之間可根據(jù)自己需求,設(shè)置時(shí)間間隔,這個(gè)時(shí)間間隔對(duì)應(yīng)波特率;而對(duì)于有些場(chǎng)景,為了保證數(shù)據(jù)的可靠性,還需加上校驗(yàn)位,稱之為奇偶校驗(yàn)位,以此來校驗(yàn)傳輸數(shù)據(jù)的正確性。如果兩臺(tái)設(shè)備之間需要通過串口進(jìn)行通信,上面提到的波特率、數(shù)據(jù)位、停止位和奇偶校驗(yàn)位等這些必要參數(shù),必須設(shè)置一致,才能進(jìn)行串口通信。另外,串口通信支持全雙工通信,即:使用一根數(shù)據(jù)線發(fā)送數(shù)據(jù)的同時(shí),可以用另一個(gè)數(shù)據(jù)線進(jìn)行數(shù)據(jù)接收。
????????硬件電路圖如下:
????????軟件流程圖如下:
????????根據(jù)硬件設(shè)計(jì)和軟件設(shè)計(jì)可知,本節(jié)應(yīng)用實(shí)現(xiàn)步驟如下:
????????1)、設(shè)置引腳復(fù)用功能:由硬件原理圖可知:我們需要將IO12設(shè)置為GPIOHS功能,IO4和IO5設(shè)置為UART的RX和TX功能,如下圖:
????????2)、LED初始化,如下圖:
????????3)、UART初始化,如下圖:
????????4)、實(shí)現(xiàn)uart3接收中斷回調(diào)函數(shù),在接收中斷回調(diào)函數(shù)中,實(shí)現(xiàn)串口接收和記錄接收數(shù)據(jù)長度,如下圖:
????????5)、通過UART發(fā)送提示信息,如下圖:
????????6)、判斷是否接收到數(shù)據(jù),如果接收到數(shù)據(jù),判斷接收到的控制命令類型,根據(jù)接收到的控制命令,進(jìn)行相應(yīng)的操作,如下圖:
????????根據(jù)上述實(shí)現(xiàn)步驟,最終代碼如下:
#include #include #include #include #include #include #include #define LED_R_PIN (12)#define LED_R_GPIOHSNUM (0)#define LED_R_FUNC (FUNC_GPIOHS0+LED_R_GPIOHSNUM)#define UART3_RX_PIN (4)#define UART3_TX_PIN (5)#define UART3_NUM (UART_DEVICE_3)#define UART3_RX_FUNC (FUNC_UART1_RX+UART3_NUM*2)#define UART3_TX_FUNC (FUNC_UART1_TX+UART3_NUM*2)/********************************* * 管腳功能初始化 ********************************/void init_hardware(void){ // 將紅色LED管腳設(shè)置復(fù)用為GPIOHS fpioa_set_function(LED_R_PIN, LED_R_FUNC); // 將UART管腳設(shè)置復(fù)用為UART fpioa_set_function(UART3_RX_PIN, UART3_RX_FUNC); fpioa_set_function(UART3_TX_PIN, UART3_TX_FUNC);}/********************************* * LED初始化 ********************************/void init_led(gpio_pin_value_t value){ // 設(shè)置輸出 gpiohs_set_drive_mode(LED_R_GPIOHSNUM, GPIO_DM_OUTPUT); // 設(shè)置初始電平狀態(tài) gpiohs_set_pin(LED_R_GPIOHSNUM, value);}/********************************* * 控制LED亮滅 ********************************/void ctl_led(gpio_pin_value_t value){ gpiohs_set_pin(LED_R_GPIOHSNUM, value);}struct RCVBUF { char buf[128]; unsigned char len;};/********************************* * UART接收中斷回調(diào)函數(shù) ********************************/int irq_uart3_rcv(void *ctx){ struct RCVBUF *rcv_buf = (struct RCVBUF *)ctx; rcv_buf->len = uart_receive_data(UART3_NUM, rcv_buf->buf, 1); return 0;}/********************************* * UART初始化 ********************************/void init_uart(struct RCVBUF *rcv_buf){ // 初始化 uart uart_init(UART3_NUM); // 設(shè)置 uart 工作模式 uart_set_work_mode (UART3_NUM , UART_NORMAL); // 設(shè)置 UART 相關(guān)參數(shù) uart_config (UART3_NUM , 115200 , UART_BITWIDTH_8BIT , UART_STOP_1 , UART_PARITY_NONE); // 初始化外部中斷 plic_init(); // 注冊(cè) UART 中斷函數(shù) uart_irq_register (UART3_NUM, UART_RECEIVE, irq_uart3_rcv, rcv_buf , 1); // 設(shè)置接收中斷 觸發(fā) FIFO 深度 uart_set_receive_trigger(UART3_NUM, UART_RECEIVE_FIFO_1); // 使能系統(tǒng)中斷,如果使用中斷,一定要開啟系統(tǒng)中斷 sysctl_enable_irq();}int main(int argc, char **argv){ init_hardware(); init_led(GPIO_PV_HIGH); struct RCVBUF rcv_buf = { .len = 0, }; init_uart(&rcv_buf); uart_send_data(UART3_NUM, "CTL LED:[0:OFF/1:ON] /r/n", sizeof("CTL LED:[0:OFF/1:ON] /r/n")); while (1) { if(rcv_buf.len != 0) { uart_send_data(UART3_NUM, "rcv_buf.len:", sizeof("rcv_buf.len:")); uart_send_data(UART3_NUM, (char *)&rcv_buf.len, sizeof(rcv_buf.len)); if(rcv_buf.buf[0] == 0) { uart_send_data(UART3_NUM, "LER_R OFF! /r/n", sizeof("LER_R OFF! /r/n")); ctl_led(GPIO_PV_HIGH); } else { uart_send_data(UART3_NUM, "LER_R ON! /r/n", sizeof("LER_R ON! /r/n")); ctl_led(GPIO_PV_LOW); } uart_send_data(UART3_NUM, "CTL LED:[0:OFF/1:ON] /r/n", sizeof("CTL LED:[0:OFF/1:ON] /r/n")); rcv_buf.len = 0; } usleep(20000); } return 0;}
????????1)、同上一節(jié)類似,在SDK中創(chuàng)建uart_irq文件夾,在新建的文件夾中創(chuàng)建一個(gè)main.c文件,然后將本節(jié)代碼輸入到main.c文件中,如下圖:
????????2)、同上一節(jié)的編譯方式類似,打開vscode終端,在終端中進(jìn)入上一節(jié)創(chuàng)建的build文件夾,然后輸入:cmake ../ -DPROJ=uart_irq -G "MinGW Makefiles" ,生成makefile文件,如下圖:
????????3)、生成makefile文件后,輸入:make ,開始編譯,如下圖:
????????4)、編譯完成后,會(huì)在build目錄下生成燒錄文件:uart_irq.bin,如下圖:
????????同上一節(jié)的燒錄方式類似,注意:Firmware那一項(xiàng)選擇我們剛編譯出的uart_irq.bin文件。
????????通過串口助手,發(fā)送0x00,紅色LED燈熄滅,發(fā)送其他非零數(shù),紅色LED亮起。如下圖:
????????1)、開啟LED
????????2)、關(guān)閉LED
????????1)、K210串口中斷有接收中斷和發(fā)送中斷,用戶可根據(jù)需求設(shè)置想要的中斷方式;
????????2)、K210串口的中斷可設(shè)置觸發(fā)FIFO深度,用戶可根據(jù)需求設(shè)置想要的FIFO深度。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/123277.html
摘要:緊接著上一篇博文。。。編寫串口中斷函數(shù)當(dāng)中斷發(fā)生的時(shí)候,程序就會(huì)執(zhí)行中斷服務(wù)函數(shù),我們?cè)谥袛喾?wù)函數(shù)中編寫相應(yīng)的邏輯代碼就可以了。將以下代碼編寫在中串口輸出重定義到注意頭文件需要包含標(biāo)準(zhǔn)庫,也就是。 ...
摘要:目前,所有型號(hào)串口的輸入是輸出是。串口全雙工通信是沒有時(shí)鐘脈沖的,只能依靠晶振脈沖定時(shí)器的溢出脈沖。中斷中讀取,清標(biāo)志,然后返回給計(jì)算機(jī),等待發(fā)送完畢防重疊最少時(shí)間次位定時(shí)器時(shí)間。實(shí)現(xiàn)燒錄程序的目的。 ...
摘要:異步通信與同步通信異步通信異步通信是指通信的發(fā)送與接收設(shè)備使用各自的時(shí)鐘控制數(shù)據(jù)的發(fā)送和接收過程。同步通信同步通信時(shí)要建立發(fā)送方時(shí)鐘對(duì)接收方時(shí)鐘的直接控制,使雙方達(dá)到完全同步。配置串口設(shè)置為異步通信基礎(chǔ)參數(shù)波特率為。 ...
摘要:接收緩沖區(qū)和發(fā)送緩沖區(qū)的請(qǐng)求是獨(dú)立的。此時(shí)串口實(shí)際上還有個(gè)字節(jié)并未發(fā)送完成,數(shù)據(jù)寄存器和移位寄存器中的個(gè)字節(jié)還需要發(fā)送,并不能關(guān)閉串口發(fā)送。 文章目錄 串口通訊串...
閱讀 2547·2021-11-24 09:39
閱讀 3445·2021-11-15 11:37
閱讀 2313·2021-10-08 10:04
閱讀 4013·2021-09-09 11:54
閱讀 1914·2021-08-18 10:24
閱讀 1119·2019-08-30 11:02
閱讀 1832·2019-08-29 18:45
閱讀 1694·2019-08-29 16:33