本文和设计代码由FPGA爱好者小梅哥编写,未经作者许可,本文仅允许网络论坛复制转载,且转载时请标明原作者。
- #include "sys/alt_stdio.h"
- #include "altera_avalon_uart_regs.h"
- #include "system.h"
- #include "altera_avalon_pio_regs.h"
- #include "alt_types.h"
- #include "sys/alt_irq.h"
- alt_u8 uart_en = 0;
- alt_u8 i=0;
- alt_u8 rx_data[256],tx_data[256];
- alt_u8 tx_len,rx_len;
- alt_isr_func key_isr(void)
- {
- alt_u8 data;
- IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x00); //关闭按键中断
- data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE);
- if(data == 0x30)
- {
- }
- else if(data & 0x10)
- {
- uart_en = 1;
- }
- else if(data & 0x20)
- {
- }
- IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30); //清零所有的捕获位
- IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30); //关闭按键中断
- return 0;
- }
- void key_init()
- {
- char *p;
- alt_ic_isr_register(PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID,
- PIO_LED_IRQ,
- key_isr,
- p,
- 0);
- IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f); //设置低4位为输出,高2位为输入
- IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30); //清零所有的捕获位
- IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30); //打开按键中断
- }
- alt_isr_func uart_0_isr(void)
- {
- alt_u16 status;
- status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE);
- if(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK)
- {
- rx_data[rx_len] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);
- rx_len ++ ;
- }
- if(status & ALTERA_AVALON_UART_STATUS_TRDY_MSK)
- {
- if(tx_len)
- {
- IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE, tx_data[tx_len]);
- tx_len--;
- if(!tx_len)
- {
- IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE,0x80); //关闭发送中断
- }
- }
- }
- return 0;
- }
- void uart_0_init()
- {
- char *p;
- alt_ic_isr_register(UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
- UART_0_IRQ,
- uart_0_isr,
- p,
- 0);
- IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0x0); //清零状态寄存器
- IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); //读空接收寄存器中的无用值
- IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, UART_0_FREQ/9600 - 1);//设置波特率为115200
- IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80); //使能接收中断
- }
- void uart_tx(alt_u8 *data, alt_u8 len)
- {
- tx_len = len;
- while(len)
- {
- tx_data[len] = *data;
- data++;
- len -- ;
- }
- IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80 | 0x40); //使能发送中断
- }
- int main()
- {
- key_init();
- uart_0_init();
- while(1)
- {
- if(uart_en)
- {
- uart_tx(rx_data, rx_len);
- rx_len = 0;
- uart_en = 0;
- }
- }
- return 0;
- }
注意,使用自定义的驱动来完成对UART IP的操作,请将软件自带的UART驱动关闭,如下图:
|