2301_80280964 2024-06-11 22:15 采纳率: 25%
浏览 7

51单片机的程序设计题

设计一控制系统并仿真:包括主从两个单片机,两个单片机通过串口通信,1号单片机上设计3个按键(A、B、C键),2号单片机上设计6位7段数码管。1号单片机上保存一个数字num,初值为0:按下 A馆,数字加1:按下3键,数字减1:按下C键,数字清零:数字加到60自动从0开始,数字减到0自动从60开始。并发送给2号单片机显示该数

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-11 22:15
    关注

    引自免费微信小程序:皆我百晓生

    为了解决这个问题,我们将分两部分来设计:一部分是1号单片机的程序,另一部分是2号单片机的程序。同时,我们还需要确保两片单片机之间的串行通信正常工作。

    1号单片机(Master)

    在1号单片机上,我们将实现数字的增减功能,并通过串口将数值发送给2号单片机。以下是基本的程序框架:

    #include <reg51.h>
    #include <intrins.h>
    
    #define SBUF (*(volatile unsigned char *)0x99)
    #define SCON (*(volatile unsigned char *)0x98)
    
    sbit P1_0 = P1^0; // A键
    sbit P1_1 = P1^1; // B键
    sbit P1_2 = P1^2; // C键
    
    unsigned char num = 0;
    
    void serial_init() {
        SCON = 0x50; // 设置串口工作模式1
        TMOD &= 0xF0; // 清除低4位
        TMOD |= 0x20; // 设置定时器1为模式2
        TH1 = 0xFD;   // 设定波特率(约9600bps)
        TL1 = 0xFD;
        TR1 = 1;      // 启动定时器1
    }
    
    void send_data(unsigned char data) {
        while(!TI); // 等待发送完成标志
        SBUF = data; // 发送数据
        TI = 0;      // 清除发送完成标志
    }
    
    void main() {
        serial_init();
        while(1) {
            if(P1_0 == 0) { // 按下A键
                _delay_ms(10);
                if(P1_0 == 0) {
                    num++;
                    if(num > 59) num = 0;
                    send_data(num);
                }
            }
            else if(P1_1 == 0) { // 按下B键
                _delay_ms(10);
                if(P1_1 == 0) {
                    num--;
                    if(num > 59) num = 0;
                    send_data(num);
                }
            }
            else if(P1_2 == 0) { // 按下C键
                _delay_ms(10);
                if(P1_2 == 0) {
                    num = 0;
                    send_data(num);
                }
            }
        }
    }
    

    2号单片机(Slave)

    在2号单片机上,我们需要接收来自1号单片机的数据,并在6位7段数码管上显示出来。这里我们假设使用共阴极数码管。以下是基本的程序框架:

    #include <reg51.h>
    #include <intrins.h>
    
    #define SBUF (*(volatile unsigned char *)0x99)
    #define SCON (*(volatile unsigned char *)0x98)
    
    unsigned char display[6]; // 存储要显示的数字
    unsigned char num = 0;
    
    void serial_init() {
        SCON = 0x50; // 设置串口工作模式1
        TMOD &= 0xF0; // 清除低4位
        TMOD |= 0x20; // 设置定时器1为模式2
        TH1 = 0xFD;   // 设定波特率(约9600bps)
        TL1 = 0xFD;
        TR1 = 1;      // 启动定时器1
    }
    
    void display_num(unsigned char num) {
        for(int i = 0; i < 6; i++) {
            display[i] = num % 10 + '0';
            num /= 10;
        }
    }
    
    void disp_digit(unsigned char digit, unsigned char value) {
        switch(digit) {
            case 0:
                P0 = value;
                P2 = 0x01; break;
            case 1:
                P0 = value;
                P2 = 0x02; break;
            case 2:
                P0 = value;
                P2 = 0x04; break;
            case 3:
                P0 = value;
                P2 = 0x08; break;
            case 4:
                P0 = value;
                P2 = 0x10; break;
            case 5:
                P0 = value;
                P2 = 0x20; break;
        }
    }
    
    void main() {
        serial_init();
        while(1) {
            if(RI) {
                num = SBUF;
                RI = 0;
                display_num(num);
            }
            for(int i = 0; i < 6; i++) {
                disp_digit(i, display[i]);
                _delay_ms(2); // 延时切换显示
            }
        }
    }
    

    请注意,上述代码中的_delay_ms()函数需要你自己定义,通常可以通过循环计数来实现延时。此外,数码管的显示逻辑可能需要根据实际硬件进行调整,特别是对于共阳极和共阴极的不同类型。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月11日

悬赏问题

  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)
  • ¥15 关于并联谐振电磁感应加热
  • ¥60 请查询全国几个煤炭大省近十年的煤炭铁路及公路的货物周转量
  • ¥15 请帮我看看我这道c语言题到底漏了哪种情况吧!
  • ¥66 如何制作支付宝扫码跳转到发红包界面
  • ¥15 pnpm 下载element-plus
  • ¥15 解决编写PyDracula时遇到的问题