超梦Nacl 2025-03-22 18:30 采纳率: 100%
浏览 8
已结题

关于数码管超前显示的问题


#include <REGX52.H>
#include"key.h"
#include"seg.h"
//变量
//按键状态
unsigned char down,up,val,old;

//减速
unsigned char key_10;
unsigned int seg_500;
//数码管
unsigned char seg_pos;
unsigned char seg_buff[6]={10,10,10,10,10,10};
unsigned char jie = 1;//1,2,3三个界面
//LED灯
bit rs;//开关
unsigned char p = 0xfe;//中间变量
unsigned int sudu[4] = {400,400,400,400};//间隔
unsigned int s ;//间隔计时器
unsigned char liu = 1;//1,2,3,4流水灯模式
unsigned char deng[4] = {0x7e,0xbd,0xdb,0xe7};
unsigned char de;//流水灯索引0,1,2,3
//按键函数
void key_proc()
{
    if(key_10)
        return;
    key_10 = 1;
    
    val = key_read();
    down = val & (val ^ old);
    up = ~val & (val ^ old);
    old = val;
    
    switch(down)
    {
        case 7:
            rs ^= 1;
        break;
    }
}

//处理函数
void seg_proc()
{
    if(seg_500)
        return ;
    seg_500 = 1;
    
    switch(jie)
    {
        case 1:
            seg_buff[0] = rs?11:5;
            seg_buff[1] = liu;
            seg_buff[2] = (sudu[liu-1]>=1000)?1:10;
            seg_buff[3] = sudu[liu-1]/100%10;
            seg_buff[4] = sudu[liu-1]/10%10;
            seg_buff[5] = sudu[liu-1]%10;
        
            break;
        
        case 2:
            break;
        
        case 3:
            break;
    }
}
//其他显示函数
void led_proc()
{
    P1 = p;
    if(s != sudu[liu-1])
        return;
        s = 0;
    switch(liu)
    {
        case 1:
            if(p == 0x7e)
            {
                p = 0xfe;
            }
            else
            {
                p = (p<<1) | (p>>7);
                if(p == 0x7f) liu = 2;
            }
            break;
        
        case 2:
            p = (p<<7) | (p>>1);
        if(p == 0xfe) liu = 3;
            break;
        
        case 3:
            p = deng[de];
        if(++de == 4) 
        {
            liu = 4;
            de = 3;
        }
            break;
        
        case 4:
            p = deng[de];
        if(--de == 255) 
        {
            liu = 1;    
            de = 0;
        }
            break;
    }
}
//定时器中断
void Timer0_Isr(void) interrupt 1
{
    TL0 = 0x18;                //设置定时初始值
    TH0 = 0xFC;                //设置定时初始值
    
    if(rs) s++;
    if(++key_10 == 10) key_10 = 0;
    if(++seg_500 == 500) seg_500 = 0;
    if(++seg_pos == 6) seg_pos = 0;
    seg_read(seg_pos,seg_buff[seg_pos]);
}
//定时器
void Timer0_Init(void)        //1毫秒@12.000MHz
{
    TMOD &= 0xF0;            //设置定时器模式
    TMOD |= 0x01;            //设置定时器模式
    TL0 = 0x18;                //设置定时初始值
    TH0 = 0xFC;                //设置定时初始值
    TF0 = 0;                //清除TF0标志
    TR0 = 1;                //定时器0开始计时
    ET0 = 1;                //使能定时器0中断
    
    ET0 = 1;
    EA = 1;
}
//main
void main ()
{
     Timer0_Init();
    while(1)
    {
        key_proc();
        seg_proc();
        led_proc();
    }
}

这是我的一道作业题,内容是流水灯的四种运行模式,数码管显示流水灯的运行情况,对此我有疑问,为什么这段代码if(p == 0x7f) liu = 2在检测到组末的状态的时候立即切换了模式,为什么没有导致数码管超前显示,这是我写的,总是超前显示


```c

#include <REGX52.H>
#include"key.h"
#include"seg.h"
//按键沿
unsigned char down,up,val,old;
bit rs;//开关
//减速
unsigned char key_10;//按键减速
unsigned int seg_500;//数码管减速
//LED灯
unsigned char de = 1;//led模式1,2,3,4
unsigned char p = 0xfe;//LED值
unsigned char led[4] = {0x7e,0xbd,0xdb,0xe7};//L18,L27,L36,L45
unsigned char le = 255;//数组索引0,1,2,3
unsigned int led_v[4] = {400,400,400,400};//流转间隔
unsigned int led_t = 0;//流转计时
//数码管
unsigned char jie = 1;//界面123
unsigned char t = 1;
unsigned char seg_pos;//数码管索引
unsigned char seg_buff[] = {10,10,10,10,10,10};//数码管数组
//key
void key_proc()
{
    if(key_10) return ;
    key_10 = 1;
    
    val = key_read();
    down = val & (val ^ old);
    up = ~val & (val ^ old);
    old = val;
    
    switch(down)
    {
        case 7:
            rs ^= 1;
        break;
        
        case 6:
            if(++jie == 4) jie = 1;
            break;
    }
}
//led
void led_proc()
{        
    if(rs == 0)
        return;
    if(led_t)
        return;
    led_t = 1;
    
        P1 = p;
    switch(de)
    {
        case 1:
            if(le == 255)
            {
                p = 0xfe;
                le = 0;
            }
            else
            p = (p<<1) | (p>>7);
            if(p == 0x7f) de = 2;
            break;
        case 2:
            p = (p<<7) | (p>>1);
            if(p == 0xfe) {de = 3; le = 0;}
            break;
        case 3:
            p = led[le];
            if(++le == 4) {le = 3; de = 4;}
            break;
        case 4:
            p = led[le];
            if(--le == 255) {de = 1;}
            break;
    }
}
//数码管
void seg_proc()
{
    if(seg_500) return;
    seg_500 = 1;
    switch(jie)
    {
        case 1:
            if(rs == 0)
                seg_buff[0] = 11;
            else
                seg_buff[0] = 5;
            seg_buff[1] = de;
            if(led_v[de-1] >= 1000)
                seg_buff[2] = 1;
            else
                seg_buff[2] = 10;
            seg_buff[3] = led_v[de-1] /100%10;
            seg_buff[4] = led_v[de-1] /10%10;
            seg_buff[5] = led_v[de-1] %10;
            
            break;
            
        case 2:
            seg_buff[0] = 12;
            seg_buff[1] = de;
            if(led_v[de-1] >= 1000)
                seg_buff[2] = 1;
            else
                seg_buff[2] = 10;
            seg_buff[3] = led_v[de-1] /100%10;
            seg_buff[4] = led_v[de-1] /10%10;
            seg_buff[5] = led_v[de-1] %10;
            
                break;
            
        case 3:
            seg_buff[0] = 13;
            seg_buff[1] = 14;
            seg_buff[2] = 12;
            seg_buff[3] = de;
            if(de<2)
            {
                seg_buff[4] = 0;
                t = 0;
                while(~p>>t)
                {
                    t++;
                }
                seg_buff[5] = t + 1;
            }
            else
            {
                t = 0;
                while((~p & 0xf)>>t)
                {
                    t++;
                }
                seg_buff[4] = t+1;
                seg_buff[5] = 8-t;
            }
    }
}
//定时器
void Timer0_Init(void)        //1毫秒@12.000MHz
{
    TMOD &= 0xF0;            //设置定时器模式
    TMOD |= 0x01;            //设置定时器模式
    TL0 = 0x18;                //设置定时初始值
    TH0 = 0xFC;                //设置定时初始值
    TF0 = 0;                //清除TF0标志
    TR0 = 1;                //定时器0开始计时
    
    ET0 = 1;
    EA = 1;
}

//中断
void Timer0_Isr(void) interrupt 1
{
    TL0 = 0x18;                //设置定时初始值
    TH0 = 0xFC;                //设置定时初始值

    if(++led_t == led_v[de-1]) led_t = 0;
    if(++key_10 == 10) key_10 = 0;
    if(++seg_500 == 500) seg_500 = 0;
    if(++seg_pos == 6) seg_pos = 0;
    seg_read(seg_pos,seg_buff[seg_pos]);
}

//main
void main()
{
    Timer0_Init();
    while(1)
    {
        key_proc();
        seg_proc();
        led_proc();
    }
}

```

  • 写回答

4条回答 默认 最新

  • 码农阿豪@新空间 新星创作者: 前端开发技术领域 2025-03-22 19:31
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    找到代码段内定义了按键函数`void key_proc()`,流水灯处理函数`void seg_proc()`和LED灯处理函数`void led_proc()`,以及定时器中断函数`void Timer0_Isr()`和定时器初始化函数`void Timer0_Init()`。代码段中主要实现了按键、数码管、LED灯和定时器的操作。 案例:假设设备上有4个LED灯可以流水显示,按下按键7时可以切换LED灯的显示模式,每个LED灯间隔显示时间为400ms,按下按键7后LED灯会切换为以字节`0x7e`、`0xbd`、`0xdb`、`0xe7`循环显示。每秒钟会有500次定时中断,且每个LED灯的流水间隔为500ms。
    #include <REGX52.H>
    #include "key.h"
    #include "seg.h"
    unsigned char down, up, val, old;
    unsigned char key_10;
    unsigned int seg_500;
    unsigned char seg_pos;
    unsigned char seg_buff[6] = {10, 10, 10, 10, 10, 10};
    unsigned char jie = 1;
    unsigned char p = 0xfe;
    unsigned int sudu[4] = {400, 400, 400, 400};
    unsigned int s ;
    unsigned char liu = 1;
    unsigned char deng[4] = {0x7e, 0xbd, 0xdb, 0xe7};
    unsigned char de;
    void key_proc(){
        if(key_10)
            return;
        key_10 = 1;
        val = key_read();
        down = val & (val ^ old);
        up = ~val & (val ^ old);
        old = val;
        
        switch(down){
            case 7:
                liu = (liu % 4) + 1; // 切换LED灯显示模式
            break;
        }
    }
    void seg_proc(){
        if(seg_500)
            return;
        seg_500 = 1;
        
        switch(jie){
            case 1:
                seg_buff[0] = liu;
                seg_buff[1] = (sudu[liu - 1] >= 1000) ? 1 : 10;
                seg_buff[2] = sudu[liu - 1] / 100 % 10;
                seg_buff[3] = sudu[liu - 1] / 10 % 10;
                seg_buff[4] = sudu[liu - 1] % 10;
                break;
            case 2:
                break;
            case 3:
                break;
        }
    }
    void led_proc(){
        P1 = p;
        if(s != sudu[liu - 1])
            return;
        
        s = 0;
        
        switch(liu){
            case 1:
                if(p == 0x7e){
                    p = 0xfe;
                }else{
                    p = (p << 1) | (p >> 7);
                    if(p == 0x7f) liu = 2;
                }
                break;
            case 2:
                p = (p << 7) | (p >> 1);
                if(p == 0xfe) liu = 3;
                break;
            case 3:
                p = deng[de];
                if(++de == 4){
                    liu = 4;
                    de = 3;
                }
                break;
            case 4:
                p = deng[de];
                if(--de == 255){
                    liu = 1;
                    de = 0;
                }
                break;
        }
    }
    void Timer0_Isr() interrupt 1{
        TL0 = 0x18;
        TH0 = 0xFC;
        
        if(rs) s++;
        if(++key_10 == 10) key_10 = 0;
        if(++seg_500 == 500) seg_500 = 0;
        if(++seg_pos == 6) seg_pos = 0;
        seg_read(seg_pos, seg_buff[seg_pos]);
    }
    void Timer0_Init(){
        TMOD &= 0xF0; 
        TMOD |= 0x01;
        TL0 = 0x18;
        TH0 = 0xFC;
        TF0 = 0;
        TR0 = 1;
    }
    

    需要注意的是,代码段中使用了一些未定义的函数和变量,例如key_read()seg_read()等,如果这些函数和变量并未在其他代码段中定义,需要进行进一步的检查和补充。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月3日
  • 已采纳回答 3月26日
  • 创建了问题 3月22日