华中科技大学 模拟电路与数字系统(三)实验6

串行IO接口设计

1 实验目的

  • 理解UART串行通信协议以及接口设计;

  • 掌握UART串行接口设计。

2 实验任务与要求

  • 串行IO要求:所有实验任务要求采用中断方式实现,中断方式时,GPIO输入、延时、UART\SPI接口通信都采用中断方式实现。每位同学仅完成其中的一个任务,且需完成的实验任务编号与座位号模3的取值一致。
  • 实验任务0要求:采用UART IP 核,实现Nexys4 或Nexys4 DDR 实验板UART接口之间的通信。要求当拨动开关时,将开关对应的值通过UART1发送到UART2,同时利用LED 灯指示UART2接收到的当前开关的值;当按下按键时,将按键对应的值通过UART2发送到UART1,同时利用数码管指示UART1接收到的当前按下的按键位置码(C,U,d,L,r)。UART 波特率为9600bps。

3 实验环境

  • Vivado 2019.1
  • Nexys4 DDR™ FPGA Board
  • Xilinx SDK

4 实验内容与步骤

4.1 设计思路

4.1.1 中断源

​ 本次实验的中断源为GPIO_0、GPIO_2和UART;

4.1.2 中断服务程序设计
  • 对于中断源为开关的中断服务程序,函数内读取并更新当前的8位开关状态(搭建平台时之定义了低八位开关与低八位LED灯的引脚);
  • 对于中断源为按键的中断服务程序,函数内读取并更新5个按键的状态值;
  • 对于中断源为uart1的中断服务程序,函数内判断此时是接收中断还是发送中断,接收满中断则将接收到的键值输出到定义的一位数码管上(最右),如果是发送空中断则将当前的开关状态发送到uart2;
  • 对于中断源为uart2的中断服务程序,函数内判断是接收满中断还是发送中断,如果是接收满中断,则将接收到的开关状态输出到8位LED灯上,如果是发送空中断,则将当前的按键状态值发送给uart1。

4.2 硬件电路

4.2.1 Nexys4 DDR开发板的外设

在这里插入图片描述

4.2.2 GPIO与外设的连接

在这里插入图片描述

  • 本实验使用到了GPIO_0的SW70和LED70、GPIO_1的最右边一位数码管、GPIO_2的BTND、U、L、R、C。
4.2.3 UART接口

在这里插入图片描述

  • 本实验使用到了UART1和UART2模块,引脚也自定义到相应外设上。

4.3 硬件平台

  • 根据左东红老师的学习通视频,基于Vivado2019.1版本搭建了串行的IO中断系统。

在这里插入图片描述

4.4 软件流程图

在这里插入图片描述

4.5 设计源代码及注释

  • 快速中断
/*fast interrupt*/
#include "xil_io.h"
#include "stdio.h"
#include "xgpio_l.h"
#include "xintc_l.h"
#include "xuartlite_l.h"

void UART1_RECV()__attribute__((fast_interrupt));
void UART2_RECV()__attribute__((fast_interrupt));
void BtnHandler()__attribute__((fast_interrupt));
void SwtHandler()__attribute__((fast_interrupt));

//中断服务程序
char scancode[5][2]={{0x1,0xc6},{0x2,0xc1},{0x4,0xc7},{0x8,0x88},{0x10,0xa1}};
int main()
{
    /*GPIO*/
    /*GPIO_0*/
    Xil_Out16(XPAR_AXI_GPIO_0_BASEADDR + XGPIO_TRI_OFFSET, 0xffff);//switch
    Xil_Out16(XPAR_AXI_GPIO_0_BASEADDR + XGPIO_TRI2_OFFSET, 0x0);//LED
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_IER_OFFSET,XGPIO_IR_CH1_MASK);//通道1允许中断
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_GIE_OFFSET,XGPIO_GIE_GINTR_ENABLE_MASK);//允许GPIO_0中断输出
    
    /*GPIO_1*/
    Xil_Out8(XPAR_AXI_GPIO_1_BASEADDR + XGPIO_TRI_OFFSET, 0x0);//设定位码为输出
    Xil_Out8(XPAR_AXI_GPIO_1_BASEADDR + XGPIO_TRI2_OFFSET, 0x0);//设定段码为输出
    Xil_Out8(XPAR_AXI_GPIO_1_BASEADDR + XGPIO_DATA_OFFSET, 0xfe);//segment初值,DATA位选
    
    /*GPIO_2*/
    Xil_Out8(XPAR_AXI_GPIO_2_BASEADDR + XGPIO_TRI_OFFSET, 0x1f);//设定5个按键为输入
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_IER_OFFSET,XGPIO_IR_CH1_MASK); CH1允许 中断,CH1对应的是按键
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_GIE_OFFSET,XGPIO_GIE_GINTR_ENABLE_MASK);//允许 按键和LD所对应的GPIO IP核 GPIO_2 中断输出
    
    /*UART*/
    Xil_Out32(XPAR_AXI_UARTLITE_1_BASEADDR+XUL_CONTROL_REG_OFFSET,
            XUL_CR_ENABLE_INTR|XUL_CR_FIFO_RX_RESET|XUL_CR_FIFO_TX_RESET);
    Xil_Out32(XPAR_AXI_UARTLITE_2_BASEADDR+XUL_CONTROL_REG_OFFSET,
            XUL_CR_ENABLE_INTR|XUL_CR_FIFO_RX_RESET|XUL_CR_FIFO_TX_RESET);
    
    /*INTC*/
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IAR_OFFSET,
            Xil_In32(XPAR_INTC_0_BASEADDR+XIN_ISR_OFFSET));
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IER_OFFSET,XPAR_AXI_GPIO_0_IP2INTC_IRPT_MASK|XPAR_AXI_GPIO_2_IP2INTC_IRPT_MASK|
            XPAR_AXI_UARTLITE_1_INTERRUPT_MASK|XPAR_AXI_UARTLITE_2_INTERRUPT_MASK);//使能
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IMR_OFFSET,XPAR_AXI_GPIO_2_IP2INTC_IRPT_MASK|XPAR_AXI_GPIO_0_IP2INTC_IRPT_MASK|
            XPAR_AXI_UARTLITE_1_INTERRUPT_MASK|XPAR_AXI_UARTLITE_2_INTERRUPT_MASK);//工作模式
    Xil_Out32(XPAR_AXI_INTC_0_BASEADDR+XIN_MER_OFFSET,XIN_INT_MASTER_ENABLE_MASK|XIN_INT_HARDWARE_ENABLE_MASK);//允许中断输出
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IVAR_OFFSET+4*XPAR_INTC_0_GPIO_2_VEC_ID,(u32)BtnHandler);
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IVAR_OFFSET+4*XPAR_INTC_0_GPIO_0_VEC_ID,(u32)SwtHandler);
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IVAR_OFFSET+4*XPAR_INTC_0_UARTLITE_1_VEC_ID,(u32)UART1_RECV);
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_IVAR_OFFSET+4*XPAR_INTC_0_UARTLITE_2_VEC_ID,(u32)UART2_RECV);
    Xil_Out32(XPAR_INTC_0_BASEADDR+XIN_MER_OFFSET,XIN_INT_MASTER_ENABLE_MASK|XIN_INT_HARDWARE_ENABLE_MASK);
    //填写中断控制器维护的中断向量表 写IVAR寄存器
    
    /*MicroBlaze*/
    microblaze_enable_interrupts();
    //microblaze中断开放
    return 0;
}

void BtnHandler()
{
    u8 btncode=Xil_In8(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_DATA_OFFSET);
    if(btncode)
    {
    //将按键值写入UART2的发送FIFO到UART1
    Xil_Out32(XPAR_AXI_UARTLITE_2_BASEADDR+XUL_TX_FIFO_OFFSET,btncode);
    }
    Xil_Out32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_ISR_OFFSET,
            Xil_In32(XPAR_AXI_GPIO_2_BASEADDR+XGPIO_ISR_OFFSET));//清除中断
}

void SwtHandler(){
    //将开关写入UART1的发送FIFO到UART2
    Xil_Out32(XPAR_AXI_UARTLITE_1_BASEADDR+XUL_TX_FIFO_OFFSET,Xil_In32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_DATA_OFFSET));
    Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_ISR_OFFSET,Xil_In32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_ISR_OFFSET));   //清除中断
}

void UART2_RECV()
{
    if((Xil_In32(XPAR_AXI_UARTLITE_2_BASEADDR+XUL_STATUS_REG_OFFSET)
            &XUL_SR_RX_FIFO_VALID_DATA)==XUL_SR_RX_FIFO_VALID_DATA)
        Xil_Out32(XPAR_AXI_GPIO_0_BASEADDR+XGPIO_DATA2_OFFSET,
                Xil_In32(XPAR_AXI_UARTLITE_2_BASEADDR+XUL_RX_FIFO_OFFSET));
}

void UART1_RECV()
{
    if((Xil_In32(XPAR_AXI_UARTLITE_1_BASEADDR+XUL_STATUS_REG_OFFSET)
            &XUL_SR_RX_FIFO_VALID_DATA)==XUL_SR_RX_FIFO_VALID_DATA)
    {
        u8 btncode = Xil_In8(XPAR_AXI_UARTLITE_1_BASEADDR+XUL_RX_FIFO_OFFSET);
        for(int i=0;i<5;i++)
        {
            if(btncode==scancode[i][0])
            {
                btncode=scancode[i][1];
                Xil_Out32(XPAR_AXI_GPIO_1_BASEADDR+XGPIO_DATA2_OFFSET,btncode);
                break;
            }
        }
    }

4.5 下载及功能验证

​ 在经过调试和修改代码后,下载到实验FPGA上,能够实现要求的功能,验收,功能验证图片如下:

  • 在连接时,LED和一位数码管能够正常相应中断
    在这里插入图片描述在这里插入图片描述

  • 在断开时,LED和一位数码管不能正常相应中断
    在这里插入图片描述

  • 再次连接上,LED和一位数码管又能正常相应中断

在这里插入图片描述

5 实验心得、体会

​ 深入学习了硬件平台的搭建,中断的原理,在SDK上以c语言实现各种中断的功能以及GPIO,TIMER等的具体功能,除此之外还学习到了串行接口的原理,UART的使用方法等。

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值