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驱动关闭,如下图: