这个最好还是用中断,因为有长延时容易造成程序时间阻塞!!! 思路:就两个方向解决 1:控制数据线,扫描线不变。这个楼上有人已经说过就是没点通而已,需要写两个函数,一个正常的扫描函数;另一个根据设置位的标志将相应位写全1或全0关闭(取决于共阴还是共阳),两个函数交叉调用即可。调用时间就是频率,自己决定。如果要退出设置状态,就只调用正常扫描的函数。 2:数据线不变,控制扫描线。同样设置位标志决定哪一位闪烁,相应位位选线的开启用闪烁周期决定, 比如前500MS开启,后500MS关闭。其它的和正常扫描一样。多申明一组变量来赋给位选,不要直接控制,这样就很方便了。 |
Rei 发表于 2019-12-29 12:43 除了加分的那个思路,其他的很麻烦,贴程序的没听懂你的意思基本在忽悠。 |
定时器中断 |
Rei 发表于 2019-12-29 12:43 勘误: if(Twinkle==1 && key==i)//闪烁标志与键值条件符合 P0=0x00; //保持消隐状态 else P0=dis_buf; //送段码,dis_buf[ ]显示缓存数组 |
Rei 发表于 2019-12-29 12:43 这是一个动态显示的数码管驱动程序 void display() { static uchar i=0;//静态变量 P0=0x00; //消隐 switch(i) //送位码 { case 0: led138a=0;led138b=0;led138c=0; break; case 1: led138a=1;led138b=0;led138c=0; break; case 2: led138a=0;led138b=1;led138c=0; break; case 3: led138a=1;led138b=1;led138c=0; break; case 4: led138a=0;led138b=0;led138c=1; break; case 5: led138a=1;led138b=0;led138c=1; break; case 6: led138a=0;led138b=1;led138c=1; break; case 7: led138a=1;led138b=1;led138c=1; break; } P0=dis_buf; //送段码 i++; i%=8; } 在上述程序基础改为键控逐位闪烁的数码管驱动程序 void display() { static uchar i=0;//静态变量 P0=0x00; //消隐 switch(i) //送位码 { case 0: led138a=0;led138b=0;led138c=0; break; case 1: led138a=1;led138b=0;led138c=0; break; case 2: led138a=0;led138b=1;led138c=0; break; case 3: led138a=1;led138b=1;led138c=0; break; case 4: led138a=0;led138b=0;led138c=1; break; case 5: led138a=1;led138b=0;led138c=1; break; case 6: led138a=0;led138b=1;led138c=1; break; case 7: led138a=1;led138b=1;led138c=1; break; } if(Twinkle==1 && key==i)//闪烁标志与键值条件符合 P0=0xff; //保持消隐状态 else P0=dis_buf; //送段码,dis_buf[ ]显示缓存数组 i++; i%=8; } |
说明:以上两种方法都是要先在中断中设置闪烁标志的,闪烁标志是否有效 由是否进入设置状态的标志决定。所以其实写一个函数更方便,但是你必须先理解逻辑是什么样的。 |
首先确定数码管共阴还是共阳,然后确定位选和段选IO口,再考虑动态数码管的消影,最后结合定时器完事 |
wulin 发表于 2019-12-29 07:09 大佬能说的再详细一点吗,看的有点懵= = |
楼主只要搞清楚数码管在什么条件下可以点亮,什么条件下不亮,再按0.5秒间隔交替提供这两个条件不就成了?如果对闪动周期要求精确当然使用定时器中断为佳。 |
写两个显示函数,把它们分开来显示 |