孤殇兮 2023-03-24 21:21 采纳率: 93.3%
浏览 185
已结题

51单片机外部中断控制数码管

1.实验任务
编写控制程序,要求:
(1)两个按键L/R,分别连接外部中断0和外部中断1;
(2)数码管初始显示:01234567;
(3)当用户按下L按键时,数码管显示的数据向左移动;
(4)当用户按下R按键时,数码管显示的数据向右移动。
注意事项:按键不松开数据不更新,仍然显示原数据。
2.实验原理
2.1硬件原理与连线图
1.外部中断与独立按键连线图,如图1所示。

图1 独立按键电路原理图
2.数码管连线图,如图2所示。

图2 数码管动态显示电路原理图
【注意】一定要按本图所示的连线编写控制程序。

img

  • 写回答

5条回答 默认 最新

  • OKX安生 2023-03-25 01:38
    关注
    该回答引用于gpt与OKX安生共同编写:
    
    • 该回答引用于gpt与OKX安生共同编写:

    好的,以下是8051单片机控制7段数码管外部中断的具体步骤:

    1.定义和初始化变量
    首先需要定义和初始化一些变量来存储当前显示的值以及左右移位的状态。还需要定义一个查找表来将数字映射到其对应的段模式。

    2.配置外部中断引脚和使能中断
    将L和R按键连接到外部中断0和外部中断1引脚,然后使用P3寄存器将这些引脚配置为输入。设置IE寄存器的相应位以启用中断。

    3.初始化7段数码管
    将每个段的引脚连接到单片机的IO口,并将这些IO口配置为输出。然后可以通过设置每个IO口的状态来显示初始值“01234567”。

    4.实现中断服务程序
    当外部中断触发时,执行中断服务程序。在中断服务程序中,需要首先检测哪个按键被按下。如果是左键,则将当前显示的值向左移动一个数字,并更新显示。如果是右键,则将当前显示的值向右移动一个数字,并更新显示。需要注意去抖动逻辑,避免单次按键触发多次中断。

    5.主程序
    在主程序中,需要无限循环等待中断的发生。同时,在中断服务程序中更新了显示后,需要将更新后的值存储到缓冲区中,以便下一次更新时使用。

    希望这些步骤能够帮助您实现在8051单片机上使用外部中断控制7段数码管的功能。

    • 以下是一个示例代码,可以实现在8051单片机上使用外部中断控制7段数码管左右移位的功能:

    您可以参考一下:

    #include <reg52.h>
    
    #define uchar unsigned char
    #define uint unsigned int
    
    // 数字到段模式的查找表
    uchar code segTable[] = {
        0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
        0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
    };
    
    // 存储当前显示的值、缓冲区和左右移位状态的变量
    uchar curValue = 0, buffer[8] = {0}, leftShift = 0, rightShift = 0;
    
    // 初始化IO口和中断
    void init() {
        P3 = 0xFF; // 将P3设为输入
        IE = 0x85; // 启用INT0和INT1中断
        IT0 = 1; // 设定INT0中断触发方式为下降沿
        IT1 = 1; // 设定INT1中断触发方式为下降沿
    }
    
    // 显示数字
    void display(uchar digit) {
        P1 = segTable[digit]; // 设置IO口状态
        delay(); // 延时一段时间,以便眼睛观察到数码管的变化
    }
    
    // 更新并显示数码管
    void updateDisplay() {
        // 将当前值存储到缓冲区中
        buffer[curValue] = curValue;
        // 如果需要左移,则将缓冲区向左移动一位
        if (leftShift) {
            for (uint i = 1; i < 8; i++) {
                buffer[i - 1] = buffer[i];
            }
            leftShift = 0; // 清除左移标志位
        }
        // 如果需要右移,则将缓冲区向右移动一位
        if (rightShift) {
            for (uint i = 7; i > 0; i--) {
                buffer[i] = buffer[i - 1];
            }
            rightShift = 0; // 清除右移标志位
        }
        // 显示缓冲区中的值
        for (uint i = 0; i < 8; i++) {
            display(buffer[i]);
        }
    }
    
    // 左移函数
    void leftShiftHandler() interrupt 0 {
        leftShift = 1;
    }
    
    // 右移函数
    void rightShiftHandler() interrupt 2 {
        rightShift = 1;
    }
    
    // 延时函数
    void delay() {
        uchar i, j;
        for (i = 255; i > 0; i--)
            for (j = 110; j > 0; j--);
    }
    
    // 主函数
    void main() {
        init(); // 初始化
        while (1) { // 无限循环
            updateDisplay(); // 更新并显示数码管
        }
    }
    

    需要根据您的实际硬件配置和需求进行调整和修改。希望能对您有所帮助!

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 4月1日
  • 创建了问题 3月24日