碰到动态扫描数码管和键盘的问题
本帖最后由 xts 于 2012-9-28 11:19 编辑单个数码管的扫描,首先会出现高亮的一位(不一样的一位),这个就是是最后一个被扫的数码管。它的延时包含了,整个程序的延时所以和其他数码管有所不同。
另外用定时器,定时扫描的缺陷,由于它必然会在一定时间内中断去扫描数码管,因此有时主程序中一些代码会执行不了。
(我在编写键盘和数码管的时候,就发现了数码管显示正常,但是键盘的判断语句总是执行不了)
请看11楼代码
{:biggrin:} 问题已经解决
另外要注意的是中断中最开始要加入数据清0代码如(P0=0xFF这个应该是共阳的吧)
共阴的写成P0=0就行了。{:cry:} 刚浪费了点时间在这个上面
请程序中不要用到任一个delayms()之类的 时间片处理! 黑猫白猫,能抓老鼠就是好猫。
有delay的程序,没delay的程序。能完成任务的就是好程序。 楼主的问题明显是程序写的有问题。。还说是定时扫描的缺陷。。 1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。如下:
数码管1亮;
延时;
数码管2亮;
延时;
……
最后位数码管亮;
延时
灭最后位数码管;
2、定时器扫描的话从来没遇到过LZ所述问题 难道是LZ在中断中处理数据太多?或者是中断中耗时太长? Mr_Mo 发表于 2012-9-27 20:38 static/image/common/back.gif
1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。如下:
数码管1亮;
延时; ...
来学习经验,谢谢ls Mr_Mo 发表于 2012-9-27 20:38 static/image/common/back.gif
1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。如下:
数码管1亮;
延时; ...
可能是原理图不一样造成的吧。我的数码管是74LS138驱动的。每个数码管要一个个扫描很耗时间。
void Display()
{
DataPort=0; //清空数据,防止有交替重影
P20=0;
P21=1;
P22=0;
P23=1;
DataPort=TempData;
delayms(2);
P20=1;
P21=1;
P22=0;
P23=1;
DataPort=TempData;
delayms(2);
P20=0;
P21=0;
P22=1;
P23=1;
DataPort=TempData;
delayms(2);
P20=1;
P21=0;
P22=1;
P23=1;
DataPort=TempData;
delayms(2);
P20=0;
P21=0;
P22=0;
P23=1;
DataPort=TempData;
delayms(2);
P20=1;
P21=0;
P22=0;
P23=1;
DataPort=TempData;
delayms(2);
} hameyou 发表于 2012-9-27 17:33 static/image/common/back.gif
还是任务没处理好,请不要使用delayms(),之类的函数
是啊,就是这个问题,有Delayms而且用到六个,扫描很耗时间 本帖最后由 yao1 于 2012-9-28 09:10 编辑
void t0() interrupt 1 using 1/*中断程序负责显示b的值 */
{
unsigned char a1=0,a2=0,a3=0,a4=0; //临时变量
static int k=0;
TH0=(65536-1000)/256;//1ms
TL0=(65536-1000)%256;;//扫描速度
a1=b/1000;/*取b的千位*/
a2=b%1000/100;/*取b的百位*/
a3=b%100/10;/*取b的十位*/
a4=b%10;/*取b的个位*/
if (k==0){shu1=1;shu2=0;shu3=0;shu4=0;P0=yima;}
else if(k==1){shu1=0;shu2=1;shu3=0;shu4=0;P0=yima;}
else if(k==2){shu1=0;shu2=0;shu3=1;shu4=0;P0=yima;}
else if(k==3){shu1=0;shu2=0;shu3=0;shu4=1;P0=yima;}
k++;
if(k>3) k=0;
}
延迟可以这么写
void display()
{
unsigned char a1=0,a2=0,a3=0,a4=0; //临时变量
static int k=0;
a1=b/1000;/*取b的千位*/
a2=b%1000/100;/*取b的百位*/
a3=b%100/10;/*取b的十位*/
a4=b%10;/*取b的个位*/
if (k==0){shu1=1;shu2=0;shu3=0;shu4=0;P0=yima;}
else if(k==1){shu1=0;shu2=1;shu3=0;shu4=0;P0=yima;}
else if(k==2){shu1=0;shu2=0;shu3=1;shu4=0;P0=yima;}
else if(k==3){shu1=0;shu2=0;shu3=0;shu4=1;P0=yima;}
k++;
if(k>3) k=0;
delayms(1); //扫描速度1ms
}
带闪烁:
void tiTimer0() interrupt 1
{
unsigned char a1=0,a2=0,a3=0,a4=0; //临时变量
static int k=0;
static unsigned int Time0count=0;
TH0=(65536-1000)/256;//1ms
TL0=(65536-1000)%256;
time_1ms_ok=1; //1ms标志
Time0count++; //1ms
if(Time0count>flashTime)Time0count=0; //主函数宏定义#define flashTime 600 闪烁速度
a1=b1;
a2=b2/100;
a3=b2%100/10;
a4=b2%10;
k++;
if(k>3)k=0;
if(flash==1) //进入设定标志 闪烁 速度300ms
{
if(Time0count<flashTime/2) //显示
{
if (k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima;}
else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima;}
else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima;}
else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima;}
}
else//熄灭
{
shu1=shu2=shu3=shu4=0; // P0=yima;
}
}
else //正常显示
{
if (k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima;}
else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima;}
else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima;}
else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima;}
}
}
if((k_see==0)&&(k_seeflag==0))
{
if(k_see_time_1ms_ok)//1ms
{
k_see_time_1ms_ok=0;
k_see_press_i++;
if(k_see_press_i>3000) //按下3s进入设定
{
k_see_press_i=0;
k_seeflag=1;
k_see_count=1;
}
}
}
else if(k_see==1) { k_seeflag=0;}
if((k_jia==0)&&(k_jia_flag==0)) //+
{
if(key_time_1ms_ok)//1ms
{
key_time_1ms_ok=0;
k_jia_press_i++;
if(k_jia_press_i>50) //50ms 消抖
{
if(k_jia==0) //确认+按键 按下
{
k_jia_flag=1;
see_cnt++;
if(see_cnt>N-1) see_cnt=1;
}
}
}
}
else if(k_jia==1) { k_jia_flag=0;k_jia_press_i=0; } yao1 发表于 2012-9-28 08:46 static/image/common/back.gif
void t0() interrupt 1 using 1/*中断程序负责显示b的值 */
{
unsigned char a1=0,a2=0,a3=0,a4= ...
这个群真好,有高手指导,把扫描程序也放进中断,果然也实现了键盘判断。呵呵
谢谢大哥! hameyou 发表于 2012-9-28 08:54 static/image/common/back.gif
根据数码管的位数,比如6位,开6个字节显示缓存,开一个定时器,1~2ms中断一次,每次显示一位数码管,轮询 ...
说得非常好。我想过的第一个,就是数码管每个定时器扫描一位。问题是开发板的74LS138驱动数码管,只用了三个IO,不知道有没有办法把三个脚编个组赋值的,呵呵。
键盘是74LS165驱动的,前几天好不容易在这个论坛找到的驱动,还没研究,呵呵,反正先做了个模块用起来了。 永远不要用DelayMS之类的函数,除非你只做个演示用的demo程序,这是个祸害啊
永远不要用DelayMS之类的函数,除非你只做个演示用的demo程序,这是个祸害啊
支持! 这个群真好,有高手指导,把扫描程序也放进中断,果然也实现了键盘判断。呵呵
谢谢大哥!
扫描程序别放入中断,放在主程序就行了!
liangong 发表于 2012-9-28 09:28 static/image/common/back.gif
扫描程序别放入中断,放在主程序就行了!
嗯。我明白了。反正键盘判断和数码管得在一起,不管在主程序里还是在中断里面 嗯。我明白了。反正键盘判断和数码管得在一起,不管在主程序里还是在中断里面
不一定在一起! liangong 发表于 2012-9-28 09:32 static/image/common/back.gif
不一定在一起!
又明白了。11楼的程序很精妙,是不一定在一起,显示一位就回到主程序去键盘判断。我再试试 数码管和键盘都是扫描原理的,你可以用同一根线扫描数码管和键盘,两部分都会正常了 是最好不要用delayms()?还是不要用delay()?
毫秒级的延时最好不要用,但是延时函数是不是还是能用的呀? 本帖最后由 xts 于 2012-9-28 13:06 编辑
whyui 发表于 2012-9-28 12:38 static/image/common/back.gif
是最好不要用delayms()?还是不要用delay()?
毫秒级的延时最好不要用,但是延时函数是不是还是能用的呀? ...
在http://www.amobbs.com/thread-4666558-1-1.html中可以看看。他用定时器代替了延时的程序。定时器每次延时时间的总和就变成了延时时间。
我这儿定时器的延时扫描时间一个计数器中断时间已经够扫描了。呵呵,其实完全不用delay了。加了delay也是合理地像让程序在中断中停留一会,呵呵! yao1 发表于 2012-9-28 08:46 static/image/common/back.gif
void t0() interrupt 1 using 1/*中断程序负责显示b的值 */
{
unsigned char a1=0,a2=0,a3=0,a4= ...
太可惜了,闪烁的不太会实现,能不能发个完整的闪烁程序呀!我的键盘是74LS165驱动的,所以要研究下键盘。
页:
[1]