微机原理实验备考文档

硬件平台说明:本备考文档中所有 12 道实验题目及 2026.6.15 期末考试题均基于 General_Platform(即 CPU_INT_TIMER 平台)开发。General_Platform / CPU_INT_TIMER 不含串行通信模块(无 UART、无 SPI),是涉及全部微机原理实验考试题目都通用的硬件平台。其硬件配置为:AXI GPIO×3(开关+LED、数码管位选+段码、按键)+ AXI Timer + AXI INTC,采用普通中断(Normal Interrupt)方式驱动。详细说明见 CPU_INT_TIMER/readme.md

目录


一、13个题目概述

题号 考查内容 涉及外设 核心功能
1 按键编码字符显示(全部显示 开关、LED数码管、按键 LED = 开关值(直通映射)
8个数码管全部显示同一按键字符(C/U/L/D/R)
2 按键编码字符显示(依次显示 开关、LED数码管、按键 LED = 开关值(直通映射)
数码管依次逐个显示按键字符(循环移位
3 进制转换(二进制/十六进制/十进制 开关、数码管、按键 BC二进制显示开关值的低4位
BU十六进制显示开关值的低8位
BL十进制显示开关值的低8位(逐位分解查段码表)
4 程序控制方式(无中断轮询 开关、LED、按键 按键读取两组开关
加法/乘法LED 显示结果(C=加法,R=乘法)
5 十六进制显示+定时器递增 开关、数码管、按键、定时器 C十六进制显示开关值的低8位(右2位数码管)
L每秒+1递增(0→255→0循环),由T1定时器驱动
6 数码管左右移位 开关、数码管、按键 C → 显示开关值的最右4位到最右侧数码管
L循环左移(左端移回右端)
R循环右移(右端移回左端)
7 带符号二进制→十进制原码/反码/补码 开关、数码管、按键 左4位数码管显示二进制
C → 带符号十进制(正数直接=值,负数=16-值)
L → 切换显示取反/补码(符号位不变,低3位处理)
8 数码管滚动显示(无按键控制) 数码管定时器 每秒滚动显示 "3456"(循环左移),由T1定时器驱动
9 综合系统(流水灯变速/移位/反码/符号十进制滚动) 开关、LED数码管、按键、定时器 C流水灯变速(1s→0.5s→0.25s循环切换
ULED 整体左移/右移切换
LLED 循环左移/右移(单灯循环)
R → 开关值二进制/按位取反切换显示
D符号十进制滚动(带负号处理,数码管滚动
10 数码管自动左右滚动 开关、数码管、按键、定时器 C十六进制显示开关值的低8位(右2位数码管)
R切换左移/右移方向(自动滚动,1Hz)
11 LED映射+循环右移 开关、LED、按键 C → 低8位开关映射LED高8位(低8位LED保持)
RLED 循环右移(16位整体旋转)
12 数码管滚动显示+按键控制方向 数码管、按键、定时器 显示 "3456"
C → 开始滚动(由T1定时器驱动)
L左移循环
R右移循环
2026.6.15 LED中断控制+自动循环移位 LED、按键、定时器 BTNCLED低8位显示 1111 0000(其余熄灭)
BTNL三态循环:1Hz自动左移/1Hz自动右移/停止显示当前值
要求:普通中断方式实现

二、头文件与地址宏定义

2.1 必需头文件

#include "xil_io.h"           // Xil_In8/16/32, Xil_Out8/16/32
        #include "stdio.h"            // 标准输入输出
        #include "xintc_l.h"          // 中断控制器(低层)
        #include "xtmrctr_l.h"        // 定时器(低层)
        #include "xtmrctr.h"          // 定时器(高层,含常量定义)
        #include "xgpio_l.h"          // GPIO(低层)
        #include "xgpio.h"            // GPIO(高层,含常量定义)
        #include "xil_printf.h"       // xil_printf
        #include "xparameters.h"      // 参数定义(XPAR_... 地址常量)
        #include "mb_interface.h"     // MicroBlaze接口(中断使能等)
        

2.2 外设基地址(由 xparameters.h 提供)

// GPIO0: 独立开关(16位) CH1 + LED灯(16位) CH2
        #define GPIO0_BASE  XPAR_AXI_GPIO_0_BASEADDR

        // GPIO1: 数码管位选(8位) CH1 + 数码管段码(8位) CH2
        #define GPIO1_BASE  XPAR_AXI_GPIO_1_BASEADDR

        // GPIO2: 独立按键(5位) CH1
        #define GPIO2_BASE  XPAR_AXI_GPIO_2_BASEADDR

        // Timer0: 双通道定时器(T0=通道0, T1=通道1)
        #define TIMER0_BASE XPAR_AXI_TIMER_0_BASEADDR

        // Interrupt Controller
        #define INTC_BASE   XPAR_AXI_INTC_0_BASEADDR
        

2.3 GPIO寄存器偏移

#define XGPIO_TRI_OFFSET   0x00   // 方向寄存器(1=输入, 0=输出)
        #define XGPIO_DATA_OFFSET  0x08   // 数据寄存器(CH1)
        #define XGPIO_TRI2_OFFSET  0x04   // 方向寄存器(CH2)
        #define XGPIO_DATA2_OFFSET 0x0C   // 数据寄存器(CH2)
        #define XGPIO_ISR_OFFSET   0x10   // 中断状态寄存器
        #define XGPIO_IER_OFFSET   0x14   // 中断使能寄存器
        #define XGPIO_GIE_OFFSET   0x18   // 全局中断使能

        #define XGPIO_IR_CH1_MASK         0x01  // 通道1中断屏蔽
        #define XGPIO_GIE_GINTR_ENABLE_MASK 0x80000000  // 全局中断使能位
        

2.4 定时器寄存器偏移

#define XTC_TCSR_OFFSET  0x00   // 控制和状态寄存器
        #define XTC_TLR_OFFSET   0x04   // 装载寄存器
        #define XTC_TCR_OFFSET   0x08   // 计数器寄存器

        // T1(Timer1) = 通道1,地址偏移0x10
        #define XTC_TIMER_COUNTER_OFFSET  0x10

        // TCSR 控制/状态位
        #define XTC_CSR_ENABLE_TMR_MASK    0x00000001  // 使能定时器
        #define XTC_CSR_ENABLE_INT_MASK    0x00000010  // 使能中断
        #define XTC_CSR_AUTO_RELOAD_MASK   0x00000002  // 自动重载
        #define XTC_CSR_DOWN_COUNT_MASK    0x00000008  // 减计数
        #define XTC_CSR_INT_OCCURED_MASK   0x00000020  // 中断发生标志
        #define XTC_CSR_LOAD_MASK          0x00000040  // 加载初值
        

2.5 中断控制器寄存器偏移

#define XIN_IER_OFFSET  0x08   // 中断使能寄存器
        #define XIN_IAR_OFFSET  0x0C   // 中断应答寄存器
        #define XIN_MER_OFFSET  0x1C   // 主使能寄存器
        #define XIN_ISR_OFFSET  0x00   // 中断状态寄存器

        #define XIN_INT_MASTER_ENABLE_MASK   0x00000001  // 主使能
        #define XIN_INT_HARDWARE_ENABLE_MASK 0x00000002  // 硬件使能
        

三、数码管相关表

3.1 十六进制段码表(共阳极)

/* 共阳极数码管段码:dp g f e d c b a,0=亮、1=灭 */
        char segtable_hex[16] = {
            0xc0, // 0
            0xf9, // 1
            0xa4, // 2
            0xb0, // 3
            0x99, // 4
            0x92, // 5
            0x82, // 6
            0xf8, // 7
            0x80, // 8
            0x90, // 9
            0x88, // A
            0x83, // B
            0xc6, // C
            0xa1, // D
            0x86, // E
            0x8e  // F
        };
        

3.2 特殊段码定义

#define SEG_C   0xC6  // 大写C
        #define SEG_U   0xC1  // 大写U
        #define SEG_L   0xC7  // 大写L
        #define SEG_D   0x86  // 小写d
        #define SEG_R   0x86  // 小写r
        #define SEG_MINUS  0xBF  // 负号 "-"(仅g段亮)
        

说明: 段码0xBF的位排列为 1 0 1 1 1 1 1 1,dp=1(灭) g=0(亮) f=1 e=1 d=1 c=1 b=1 a=1 → 仅中间横线(g段)亮起,显示负号。

3.3 段码缓冲区 segcode[8]

/* segcode[0~7]:数码管显示缓冲区,对应最左边~最右边8个数码管的段码。0xff=全灭 */
        char segcode[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
        

3.4 位选码表 poscode[8]

/* poscode[0~7]:数码管位选码,低电平选中对应位 */
        short poscode[8] = {0x7F, 0xBF, 0xDF, 0xEF, 0xf7, 0xfb, 0xfd, 0xfe};
        
poscode[i] 对应位 二进制 说明
poscode[0] 第1位 0111 1111 最左
poscode[1] 第2位 1011 1111
poscode[2] 第3位 1101 1111
poscode[3] 第4位 1110 1111
poscode[4] 第5位 1111 0111
poscode[5] 第6位 1111 1011
poscode[6] 第7位 1111 1101
poscode[7] 第8位 1111 1110 最右

四、按键掩码

/* GPIO2_CH1 低5位对应5个独立按键 */
        #define BTNC_MASK  0x01   // 中间按键 C(bit0)
        #define BTNU_MASK  0x02   // 上键 U(bit1)
        #define BTNL_MASK  0x04   // 左键 L(bit2)
        #define BTNR_MASK  0x08   // 右键 R(bit3)
        #define BTND_MASK  0x10   // 下键 D(bit4)
        

五、中断掩码

/* 中断源编号(对应中断控制器连接顺序) */
        #define GPIO_2_IRQ_MASK  0x2   // GPIO2(按键)中断掩码
        #define TIMER_0_IRQ_MASK 0x4   // Timer0(T0+T1共用同一根中断线)中断掩码
        

注意: GPIO2是中断源1(bit1=0x2),Timer0是中断源2(bit2=0x4)。中断源编号取决于硬件连接,不同工程可能不同。


六、定时器掩码与配置

6.1 定时器重装载值

// T0:数码管动态扫描(~10μs/位)
        #define RESET_VALUE0  1000 - 2           // 100MHz → 100kHz → 10μs

        // T1:基础周期
        #define RESET_VALUE1  100000000 - 2      // 100MHz → 1s
        #define T1_TICK_halfS     50000000 - 2   // 0.5s
        #define T1_TICK_quarterS  25000000 - 2   // 0.25s
        

计算公式: 重装载值 = 时钟频率 × 目标周期 - 2
- 时钟频率 = 100MHz = 100,000,000 Hz
- 目标周期10μs:100M × 10μs - 2 = 1000 - 2
- 目标周期1s:100M × 1s - 2 = 100M - 2
- 目标周期0.5s:100M × 0.5s - 2 = 50M - 2

6.2 两个定时器的分工

定时器 用途 中断频率 功能
T0 数码管动态扫描 ~10μs/位(100kHz) 逐位刷新8个数码管,利用视觉暂留稳定显示
T1 周期控制(滚动/递增/流水灯) 1s/0.5s/0.25s 驱动数码管滚动显示、LED流水灯步进、计数器递增等

6.3 定时器初始化代码模板

// ===== T0初始化 =====
        // 1) 关闭定时器
        Xil_Out32(TIMER0_BASE + XTC_TCSR_OFFSET,
                  Xil_In32(TIMER0_BASE + XTC_TCSR_OFFSET) & ~XTC_CSR_ENABLE_TMR_MASK);
        // 2) 设置重装载值
        Xil_Out32(TIMER0_BASE + XTC_TLR_OFFSET, RESET_VALUE0);
        // 3) 加载初值
        Xil_Out32(TIMER0_BASE + XTC_TCSR_OFFSET,
                  Xil_In32(TIMER0_BASE + XTC_TCSR_OFFSET) | XTC_CSR_LOAD_MASK);
        // 4) 配置并启动:中断使能 | 自动重载 | 减计数 | 清中断标志 | 使能
        Xil_Out32(TIMER0_BASE + XTC_TCSR_OFFSET,
                  (Xil_In32(TIMER0_BASE + XTC_TCSR_OFFSET) & ~XTC_CSR_LOAD_MASK) |
                  XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK |
                  XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK |
                  XTC_CSR_ENABLE_TMR_MASK);

        // ===== T1初始化 =====
        // 注:T1寄存器地址 = T0基址 + XTC_TIMER_COUNTER_OFFSET(0x10)
        // 1) 关闭
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET,
                  Xil_In32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET) & ~XTC_CSR_ENABLE_TMR_MASK);
        // 2) 设置重装载值
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TLR_OFFSET, RESET_VALUE1);
        // 3) 加载
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET,
                  Xil_In32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET) | XTC_CSR_LOAD_MASK);
        // 4) 配置并启动
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET,
                  (Xil_In32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET) & ~XTC_CSR_LOAD_MASK) |
                  XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK |
                  XTC_CSR_DOWN_COUNT_MASK | XTC_CSR_INT_OCCURED_MASK |
                  XTC_CSR_ENABLE_TMR_MASK);
        

七、变量类型说明

类型 常用场景 示例
char 段码值、按键值、低4位开关值、8位计数值 char segcode[8], char button
unsigned char 无符号8位值 unsigned char sw_val
short 位选码(16位) short poscode[8]
unsigned short LED状态、16位开关值 unsigned short led_val
int 模式变量、计数器、循环变量、定时器状态 int mode, int pos, int count

注意: 在MicroBlaze中,char默认是signed char,范围-128~127;当处理0~255范围时建议用unsigned char


八、中断实现框架

8.1 中断服务函数声明

void My_ISR() __attribute__ ((interrupt_handler));
        

8.2 中断初始化步骤

  1. GPIO方向配置:开关→输入,LED→输出,数码管→输出,按键→输入
  2. GPIO中断使能:清除ISR → 使能IER → 使能GIE
  3. 定时器初始化:T0(扫描) + T1(周期控制)
  4. 中断控制器配置:清除IAR → 设置IER → 设置MER
  5. 使能CPU全局中断microblaze_enable_interrupts()

8.3 主中断服务函数框架

void My_ISR()
        {
            int status = Xil_In32(INTC_BASE + XIN_ISR_OFFSET);

            if ((status & GPIO_2_IRQ_MASK) == GPIO_2_IRQ_MASK)
                button_handle();

            if ((status & TIMER_0_IRQ_MASK) == TIMER_0_IRQ_MASK)
                timer_handle();

            Xil_Out32(INTC_BASE + XIN_IAR_OFFSET, status);  // 应答中断
        }
        

8.4 定时器中断分发

void timer_handle(void)
        {
            int timer_status;

            // 检查T0是否触发中断
            timer_status = Xil_In32(TIMER0_BASE + XTC_TCSR_OFFSET);
            if ((timer_status & XTC_CSR_INT_OCCURED_MASK) == XTC_CSR_INT_OCCURED_MASK)
                timer0_handle();

            // 检查T1是否触发中断(用if,不用else if,因为可能同时触发)
            timer_status = Xil_In32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET);
            if ((timer_status & XTC_CSR_INT_OCCURED_MASK) == XTC_CSR_INT_OCCURED_MASK)
                timer1_handle();
        }
        

8.5 T0中断处理(数码管动态扫描)

void timer0_handle(void)
        {
            // 消影
            Xil_Out8(GPIO1_BASE + XGPIO_DATA_OFFSET,  0xff);
            Xil_Out8(GPIO1_BASE + XGPIO_DATA2_OFFSET, 0xff);

            // 输出位码和段码
            Xil_Out8(GPIO1_BASE + XGPIO_DATA_OFFSET,  poscode[pos]);
            Xil_Out8(GPIO1_BASE + XGPIO_DATA2_OFFSET, segcode[pos]);

            // 更新扫描位置
            pos++;
            if (pos == 8) pos = 0;

            // 清除中断标志
            Xil_Out32(TIMER0_BASE + XTC_TCSR_OFFSET,
                      Xil_In32(TIMER0_BASE + XTC_TCSR_OFFSET) | XTC_CSR_INT_OCCURED_MASK);
        }
        

8.6 按键中断处理框架

void button_handle(void)
        {
            char button = Xil_In8(GPIO2_BASE + XGPIO_DATA_OFFSET) & 0x1f;

            // 按键松开:清除中断后返回
            if (button == 0) {
                Xil_Out32(GPIO2_BASE + XGPIO_ISR_OFFSET,
                          Xil_In32(GPIO2_BASE + XGPIO_ISR_OFFSET));
                return;
            }

            // 按优先级判断:C → U → L → R → D
            if (button & BTNC_MASK) {
                // BTNC功能
            }
            else if (button & BTNU_MASK) {
                // BTNU功能
            }
            else if (button & BTNL_MASK) {
                // BTNL功能
            }
            else if (button & BTNR_MASK) {
                // BTNR功能
            }
            else if (button & BTND_MASK) {
                // BTND功能
            }

            // 清除中断标志
            Xil_Out32(GPIO2_BASE + XGPIO_ISR_OFFSET,
                      Xil_In32(GPIO2_BASE + XGPIO_ISR_OFFSET));
        }
        

九、代码逻辑总结

9.1 二进制显示

从开关值中提取指定位,每个位显示"0"(0xc0)或"1"(0xf9)到对应数码管。

// 方法:遍历4位,检查每位是否为1
        char low4 = Xil_In8(GPIO0_BASE + XGPIO_DATA_OFFSET) & 0xf;
        for (int i = 0; i < 4; i++) {
            if (low4 & (0x8 >> i))      // 检查第i位(从高位开始)
                segcode[i] = segtable_hex[1];  // 显示"1"
            else
                segcode[i] = segtable_hex[0];  // 显示"0"
        }
        

9.2 十六进制显示(segtable_hex对应)

将开关值的低8位或低4位直接作为索引查段码表。

// 低4位十六进制显示到最右1位
        char low4 = Xil_In8(GPIO0_BASE + XGPIO_DATA_OFFSET) & 0xf;
        segcode[7] = segtable_hex[low4];

        // 低8位十六进制显示到右2位
        char low8 = Xil_In8(GPIO0_BASE + XGPIO_DATA_OFFSET);
        segcode[6] = segtable_hex[(low8 >> 4) & 0xf];  // 高4位
        segcode[7] = segtable_hex[low8 & 0xf];          // 低4位

        // 16位十六进制显示到高4位
        unsigned short sw = Xil_In16(GPIO0_BASE + XGPIO_DATA_OFFSET);
        for (int i = 0; i < 4; i++) {
            segcode[i] = segtable_hex[(sw >> (12 - 4*i)) & 0xf];
        }
        

9.3 十进制显示

将数值按位分解,每位查段码表显示。

// 方法:从高位到低位逐位提取
        unsigned short val = ...;  // 待显示数值
        for (int i = 0; i < 5; i++) {
            int digit = val % 10;
            segcode[7 - i] = segtable_hex[digit];  // 从最右开始
            val /= 10;
        }
        

9.4 数码管循环左移

char temp = segcode[0];              // 保存最左端
        for (int i = 0; i < 7; i++) {
            segcode[i] = segcode[i + 1];     // 后一位覆盖前一位
        }
        segcode[7] = temp;                   // 原最左端到最右端
        

9.5 数码管循环右移

char temp = segcode[7];              // 保存最右端
        for (int i = 0; i < 7; i++) {
            segcode[7 - i] = segcode[6 - i]; // 前一位覆盖后一位(从右向左遍历)
        }
        segcode[0] = temp;                   // 原最右端到最左端
        

9.6 变速实现(定时器重装载值切换)

// 方法:切换T1的重装载值
        // 1s模式
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TLR_OFFSET, T1_BASE_TICK);
        // 0.5s模式
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TLR_OFFSET, T1_TICK_halfS);
        // 0.25s模式
        Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TLR_OFFSET, T1_TICK_quarterS);
        

使用计数器实现循环切换:

static int speed_count = 0;
        if (speed_count == 0) {
            Xil_Out32(..., T1_BASE_TICK);     // 1s
            speed_count = 1;
        }
        else if (speed_count == 1) {
            Xil_Out32(..., T1_TICK_halfS);    // 0.5s
            speed_count = 2;
        }
        else {
            Xil_Out32(..., T1_TICK_quarterS); // 0.25s
            speed_count = 0;
        }
        

9.7 取反(带符号位处理)

// 题目7:符号位(bit3)不取反,低3位取反
        char low4 = ...;                   // 读取低4位
        char sign = low4 & 0x8;           // 提取符号位
        char number = low4 & 0x7;         // 提取数值部分(低3位)
        char inverted = sign | (~number & 0x7);  // 符号位不变,低3位取反
        

9.8 补码计算

// 补码 = 取反 + 1(统一处理低3位)
        char twos_comp = sign | ((~number + 1) & 0x7);
        

9.9 流水灯变速

T1中断中驱动LED流水灯步进,通过按键切换T1速度。

void timer1_handle(void) {
            if (mode == MODE_C) {
                ledbits++;
                if (ledbits == 16) ledbits = 0;
                Xil_Out16(GPIO0_BASE + XGPIO_DATA2_OFFSET, 1 << ledbits);
            }
        }
        

9.10 LED整体左移/右移

// 循环左移(16位)
        unsigned short val = led_val;
        val = ((val << 1) & 0xFFFF) | ((val >> 15) & 0x0001);

        // 循环右移(16位)
        unsigned short lsb = led_val & 0x0001;
        led_val = (led_val >> 1) | (lsb << 15);
        

9.11 LED整体循环移位(2026.6.15 期末题)

题目要求: 使用普通中断方式,BTNC按下后LED低8位显示1111 0000(其余熄灭);BTNL三态循环切换:1Hz自动左移→1Hz自动右移→停止显示当前值。移位时整体8位循环,最左边移出回到最低位,最右边移出回到最高位。

核心变量: Led_current(8位变量,保存LED低8位当前值)

// 全局变量
        unsigned char Led_current;   // LED低8位当前值(LED显示用)
        unsigned char shift_mode;    // 移位模式:0=停止, 1=左移, 2=右移

        // BTNC中断处理:设置固定值 1111 0000 = 0xF0
        Led_current = 0xF0;
        shift_mode = 0;              // 停止自动移位
        Xil_Out16(GPIO0_BASE + XGPIO_DATA2_OFFSET, (unsigned short)Led_current);

        // BTNL中断处理:三态循环
        // count%3 决定模式
        // 0 → 左移模式
        // 1 → 右移模式
        // 2 → 停止模式(显示当前值)
        static int btnl_count = 0;
        btnl_count = (btnl_count + 1) % 3;

        if (btnl_count == 0) {
            shift_mode = 1;  // 左移
        } else if (btnl_count == 1) {
            shift_mode = 2;  // 右移
        } else {
            shift_mode = 0;  // 停止
        }

        // T1定时器中断(1Hz):根据shift_mode自动移位
        void timer1_handle(void)
        {
            if (shift_mode == 1) {
                // 循环左移:左移1位,最高位移到最低位
                Led_current = (Led_current << 1) | ((Led_current & 0x80) >> 7);
                Xil_Out16(GPIO0_BASE + XGPIO_DATA2_OFFSET, (unsigned short)Led_current);
            }
            else if (shift_mode == 2) {
                // 循环右移:右移1位,最低位移到最高位
                Led_current = (Led_current >> 1) | ((Led_current & 0x01) << 7);
                Xil_Out16(GPIO0_BASE + XGPIO_DATA2_OFFSET, (unsigned short)Led_current);
            }
            // shift_mode == 0 时不操作(停止,保持当前值)

            // 清除T1中断标志
            Xil_Out32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET,
                      Xil_In32(TIMER0_BASE + XTC_TIMER_COUNTER_OFFSET + XTC_TCSR_OFFSET) | XTC_CSR_INT_OCCURED_MASK);
        }
        

关键点:


十、常见GPIO配置速查

外设 基地址 CH1方向 CH2方向 CH1用途 CH2用途
GPIO0 XPAR_AXI_GPIO_0_BASEADDR 输入(0xffff) 输出(0x0) 16位开关 16位LED
GPIO1 XPAR_AXI_GPIO_1_BASEADDR 输出(0x0) 输出(0x0) 8位位选 8位段码
GPIO2 XPAR_AXI_GPIO_2_BASEADDR 输入(0x1f) 5位按键
// 初始化配置
        Xil_Out16(GPIO0_BASE + XGPIO_TRI_OFFSET,  0xffff);   // GPIO0_CH1: 开关→输入
        Xil_Out16(GPIO0_BASE + XGPIO_TRI2_OFFSET, 0x0);       // GPIO0_CH2: LED→输出
        Xil_Out8( GPIO1_BASE + XGPIO_TRI_OFFSET,  0x0);       // GPIO1_CH1: 位选→输出
        Xil_Out8( GPIO1_BASE + XGPIO_TRI2_OFFSET, 0x0);       // GPIO1_CH2: 段码→输出
        Xil_Out8( GPIO2_BASE + XGPIO_TRI_OFFSET,  0x1f);      // GPIO2_CH1: 按键→输入