[Nios][UART] 使用UART 的一些問題?

來源:互聯網
上載者:User

標籤:for   efi   script   遇到   因此   ase   style   bubuko   png   

我在研究NIOS的UART時有遇到一些問題,做一下分享。

Nios II在讀取周邊設備資訊時,可以用輪詢跟中斷方式兩種方式來讀取資料。

測試前的前置作業:

1.在Qsys中加入一個UART,並在Quartus中將新增的UART裝置的RX、TX對接。

問題一: 使用輪詢方式讀程式

當我用以下程式碼去輪詢時,會發現須等到第62筆資料傳完後,status暫存器的RRDY才會正常判斷。

 1 /* 2  * UART test: polling test, design by Shih-An Li 3  *  4  */ 5  6 #include <stdio.h> 7 #include <system.h> 8 #include "altera_avalon_uart.h" 9 #include "altera_avalon_uart_regs.h"10 #include "alt_types.h"11 #include "sys/alt_irq.h"12 #include <unistd.h>13 #include <io.h>14 15 16 int main(void)17 {18   int rxdata=0,k=0,t=0;19   unsigned int status;20 21   IOWR_ALTERA_AVALON_UART_CONTROL(UART_TX_BASE, 0x1C0);  // clear status22 23   while(1)24   {25       status =IORD_ALTERA_AVALON_UART_STATUS(UART_TX_BASE);  // read status register26       if(status & ALTERA_AVALON_UART_STATUS_TRDY_MSK){  // check trdy flag27           if(status & 0x040){// transmit shift register is empty28               printf("Uart ready (0x%2x) and send %3d ", status, t);29               IOWR(UART_TX_BASE,1, t++);  // send tx data30           }31       }32 33       usleep(100000);34       status =IORD_ALTERA_AVALON_UART_STATUS(UART_TX_BASE);35       printf(" status=0x%x %d\n", status,k++);36       if (status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) // check RRDY flag37       {38           rxdata = IORD(UART_TX_BASE,0);39         printf("Your character rxd is:\t%d  %d\n", rxdata, k);40       }41 42   }43   return 0;44 }

 

執行結果如下:

 1 Uart ready (0x60) and send  59  status=0x60 59 2 Uart ready (0x60) and send  60  status=0x60 60 3 Uart ready (0x60) and send  61  status=0x60 61 4 Uart ready (0x60) and send  62  status=0xe0 62 5 Your character rxd is:    62  63 6 Uart ready (0x60) and send  63  status=0xe0 63 7 Your character rxd is:    63  64 8 Uart ready (0x60) and send  64  status=0xe0 64 9 Your character rxd is:    64  6510 Uart ready (0x60) and send  65 

 

讓我覺得很好奇的是去抓他硬體波形來看,發現只讀一次

status =IORD_ALTERA_AVALON_UART_STATUS(UART_TX_BASE);

 結果硬體居然送出了好幾次的chip_select訊號,而Fig.1最後那次的chip_select居然是讀取addr 0 位置RXDATA暫存器,因此會把rx_char_ready訊號拉下,之後Fig2會在連續讀取幾次address 2位置的status暫存器,此時已經變成0x60了。

一直要到62筆之後才會正常收值。

 

 Fig 1. UART波形

 Fig 2. 接續Fig 1. 波形

 

方法二: 使用中斷方式

程式碼如下,使用Nios II HAL模式來讀寫資料。

此模式會用ISR函數來判斷RRDY旗標使否為1,是則去收值,因此判斷上比較準確。

 1 /* 2  * Nios使用HAL指令,開啟以及讀寫UART設備, design by Shih-An Li 3  */ 4  5 #include <stdio.h> 6 #include <system.h> 7 #include <unistd.h>  // define usleep() 8 #include <stddef.h>  // define NULL 9 #include <fcntl.h>   // define O_NONBLOCK10 #define BUF_SIZE 12811 12 13 int main()14 {15     int iCount, iUart_rxcount;16     int fdterm;           // FILEDESCRIPTOR RETURNED BY OPEN17     FILE *fpterm;         // FILE pointer returned by fdopen18     unsigned char uCUart1_rxbuffer[255], ucTX[128];19     // O_ACCMODE all access mode20     fdterm = open("/dev/uart_tx", O_ACCMODE | O_NONBLOCK);21     fpterm = fdopen(fdterm,"rw+");22     if(fpterm){23         fprintf(fpterm,"uart_tx STARTED\r\n"); // check initial output24           iUart_rxcount = fread(&uCUart1_rxbuffer, 1, sizeof(uCUart1_rxbuffer), fpterm);25           usleep(100000);26         printf("received:%s\r\n",uCUart1_rxbuffer);27     }28     ucTX[0]=0;29     while(1) {30       write(fdterm, &ucTX[0], 1);  // write tx value to uart31       ucTX[0]++;  // tx value + 132       // read uart data to rxbuffer and return receive data number33       iUart_rxcount = read(fdterm, &uCUart1_rxbuffer, sizeof(uCUart1_rxbuffer));34       for(iCount=0; iCount<iUart_rxcount; iCount++) {35 //          fprintf(fpterm,"received:%s\r\n",uart1_rxbuffer);36           printf("%d\n",uCUart1_rxbuffer[iCount]);37       }38       usleep(10000);39   }40   return 0;41 }

執行結果如下

received:uart_tx STARTED012345678

 

 

因此推薦還是以HAL方式來讀取周邊資料比較不會有資料lost問題。

 

[Nios][UART] 使用UART 的一些問題?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: