NIOS II下基于中断的UART接收和发送设计示例代码

  1 #include "sys/alt_stdio.h"
  2 #include "altera_avalon_uart_regs.h"
  3 #include "system.h"
  4 #include "altera_avalon_pio_regs.h"
  5 #include "alt_types.h"
  6 #include "sys/alt_irq.h"
  7 
  8 alt_u8 uart_en = 0;
  9 alt_u8 i=0;
 10 alt_u8 rx_data[256],tx_data[256];
 11 alt_u8 tx_len,rx_len;
 12 
 13 alt_isr_func key_isr(void)
 14 {
 15     alt_u8 data;
 16     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x00);    //关闭按键中断
 17     data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE);
 18     if(data == 0x30)
 19     {
 20 
 21     }
 22     else if(data & 0x10)
 23     {
 24         uart_en = 1;
 25     }
 26     else if(data & 0x20)
 27     {
 28 
 29     }
 30     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);    //清零所有的捕获位
 31     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30);    //关闭按键中断
 32     return 0;
 33 }
 34 
 35 void key_init()
 36 {
 37     char *p;
 38     alt_ic_isr_register(PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID,
 39                         PIO_LED_IRQ,
 40                         key_isr,
 41                         p,
 42                         0);
 43 
 44     IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f);    //设置低4位为输出,高2位为输入
 45     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);    //清零所有的捕获位
 46     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30);    //打开按键中断
 47 }
 48 
 49 alt_isr_func uart_0_isr(void)
 50 {
 51     alt_u16 status;
 52 
 53     status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE);
 54     if(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK)
 55     {
 56         rx_data[rx_len] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);
 57         rx_len ++ ;
 58     }
 59 
 60     if(status & ALTERA_AVALON_UART_STATUS_TRDY_MSK)
 61     {
 62         if(tx_len)
 63         {
 64             IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE, tx_data[tx_len]);
 65             tx_len--;
 66             if(!tx_len)
 67             {
 68                 IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE,0x80);    //关闭发送中断
 69 
 70             }
 71         }
 72     }
 73     return 0;
 74 }
 75 
 76 void uart_0_init()
 77 {
 78     char *p;
 79     alt_ic_isr_register(UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
 80                         UART_0_IRQ,
 81                         uart_0_isr,
 82                         p,
 83                         0);
 84 
 85     IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0x0);    //清零状态寄存器
 86     IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);    //读空接收寄存器中的无用值
 87     IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, UART_0_FREQ/9600 - 1);//设置波特率为115200
 88     IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80);    //使能接收中断
 89 }
 90 
 91 void uart_tx(alt_u8 *data, alt_u8 len)
 92 {
 93     tx_len = len;
 94     while(len)
 95     {
 96         tx_data[len] = *data;
 97         data++;
 98         len -- ;
 99     }
100     IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80 | 0x40);    //使能发送中断
101 }
102 
103 int main()
104 {
105     key_init();
106     uart_0_init();
107 
108     while(1)
109     {
110         if(uart_en)
111         {
112             uart_tx(rx_data, rx_len);
113             rx_len = 0;
114             uart_en = 0;
115         }
116     }
117 
118   return 0;
119 }

注意,使用自定义的驱动来完成对UART IP的操作,请将软件自带的UART驱动关闭,如下图:

posted @ 2017-09-19 10:47  小梅哥  阅读(2967)  评论(0编辑  收藏  举报