[FPGA] 【工程源码】NIOS II下基于中断的UART接收和发送设计示例代码

[复制链接]
719|0
 楼主| zgmxs 发表于 2020-2-25 18:59 | 显示全部楼层 |阅读模式
本文和设计代码由FPGA爱好者小梅哥编写,未经作者许可,本文仅允许网络论坛复制转载,且转载时请标明原作者。


  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. alt_u8 uart_en = 0;
  8. alt_u8 i=0;
  9. alt_u8 rx_data[256],tx_data[256];
  10. alt_u8 tx_len,rx_len;

  11. alt_isr_func key_isr(void)
  12. {
  13.     alt_u8 data;
  14.     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x00);    //关闭按键中断
  15.     data = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE);
  16.     if(data == 0x30)
  17.     {

  18.     }
  19.     else if(data & 0x10)
  20.     {
  21.         uart_en = 1;
  22.     }
  23.     else if(data & 0x20)
  24.     {

  25.     }
  26.     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);    //清零所有的捕获位
  27.     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30);    //关闭按键中断
  28.     return 0;
  29. }

  30. void key_init()
  31. {
  32.     char *p;
  33.     alt_ic_isr_register(PIO_LED_IRQ_INTERRUPT_CONTROLLER_ID,
  34.                         PIO_LED_IRQ,
  35.                         key_isr,
  36.                         p,
  37.                         0);

  38.     IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_LED_BASE, 0x0f);    //设置低4位为输出,高2位为输入
  39.     IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_LED_BASE, 0x30);    //清零所有的捕获位
  40.     IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_LED_BASE, 0x30);    //打开按键中断
  41. }

  42. alt_isr_func uart_0_isr(void)
  43. {
  44.     alt_u16 status;

  45.     status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE);
  46.     if(status & ALTERA_AVALON_UART_STATUS_RRDY_MSK)
  47.     {
  48.         rx_data[rx_len] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);
  49.         rx_len ++ ;
  50.     }

  51.     if(status & ALTERA_AVALON_UART_STATUS_TRDY_MSK)
  52.     {
  53.         if(tx_len)
  54.         {
  55.             IOWR_ALTERA_AVALON_UART_TXDATA(UART_0_BASE, tx_data[tx_len]);
  56.             tx_len--;
  57.             if(!tx_len)
  58.             {
  59.                 IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE,0x80);    //关闭发送中断

  60.             }
  61.         }
  62.     }
  63.     return 0;
  64. }

  65. void uart_0_init()
  66. {
  67.     char *p;
  68.     alt_ic_isr_register(UART_0_IRQ_INTERRUPT_CONTROLLER_ID,
  69.                         UART_0_IRQ,
  70.                         uart_0_isr,
  71.                         p,
  72.                         0);

  73.     IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0x0);    //清零状态寄存器
  74.     IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE);    //读空接收寄存器中的无用值
  75.     IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, UART_0_FREQ/9600 - 1);//设置波特率为115200
  76.     IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80);    //使能接收中断
  77. }

  78. void uart_tx(alt_u8 *data, alt_u8 len)
  79. {
  80.     tx_len = len;
  81.     while(len)
  82.     {
  83.         tx_data[len] = *data;
  84.         data++;
  85.         len -- ;
  86.     }
  87.     IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, 0x80 | 0x40);    //使能发送中断
  88. }

  89. int main()
  90. {
  91.     key_init();
  92.     uart_0_init();

  93.     while(1)
  94.     {
  95.         if(uart_en)
  96.         {
  97.             uart_tx(rx_data, rx_len);
  98.             rx_len = 0;
  99.             uart_en = 0;
  100.         }
  101.     }

  102.   return 0;
  103. }

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



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

104

主题

104

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部