搜索
bottom↓
回复: 23

碰到动态扫描数码管和键盘的问题

[复制链接]

出0入0汤圆

发表于 2012-9-27 17:31:43 | 显示全部楼层 |阅读模式
本帖最后由 xts 于 2012-9-28 11:19 编辑

单个数码管的扫描,首先会出现高亮的一位(不一样的一位),这个就是是最后一个被扫的数码管。它的延时包含了,整个程序的延时所以和其他数码管有所不同。
另外用定时器,定时扫描的缺陷,由于它必然会在一定时间内中断去扫描数码管,因此有时主程序中一些代码会执行不了。
(我在编写键盘和数码管的时候,就发现了数码管显示正常,但是键盘的判断语句总是执行不了)


请看11楼代码
问题已经解决
另外要注意的是中断中最开始要加入数据清0代码如(P0=0xFF这个应该是共阳的吧)
共阴的写成P0=0就行了。 刚浪费了点时间在这个上面

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-9-27 17:39:41 | 显示全部楼层
请程序中不要用到任一个delayms()之类的

出0入0汤圆

发表于 2012-9-27 17:42:26 | 显示全部楼层
时间片处理!

出0入0汤圆

发表于 2012-9-27 18:19:43 | 显示全部楼层
黑猫白猫,能抓老鼠就是好猫。
有delay的程序,没delay的程序。能完成任务的就是好程序。

出0入0汤圆

发表于 2012-9-27 18:21:35 | 显示全部楼层
楼主的问题明显是程序写的有问题。。还说是定时扫描的缺陷。。

出0入0汤圆

发表于 2012-9-27 20:38:10 | 显示全部楼层
1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。  如下:
    数码管1亮;
    延时;
    数码管2亮;
    延时;
     ……
    最后位数码管亮;
    延时
    灭最后位数码管;

2、定时器扫描的话从来没遇到过LZ所述问题   难道是LZ在中断中处理数据太多?或者是中断中耗时太长?

出0入0汤圆

发表于 2012-9-27 21:01:35 | 显示全部楼层
Mr_Mo 发表于 2012-9-27 20:38
1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。  如下:
    数码管1亮;
    延时; ...

来学习经验,谢谢ls

出0入0汤圆

 楼主| 发表于 2012-9-28 08:39:16 | 显示全部楼层
Mr_Mo 发表于 2012-9-27 20:38
1、主程序扫描数码管在扫描最后一位数码管后将其熄灭,亮度就会均匀。  如下:
    数码管1亮;
    延时; ...

可能是原理图不一样造成的吧。我的数码管是74LS138驱动的。每个数码管要一个个扫描很耗时间。
void Display()
{
           DataPort=0;   //清空数据,防止有交替重影
         
      P20=0;
      P21=1;
      P22=0;
      P23=1;
          DataPort=TempData[3];
          delayms(2);

      P20=1;
      P21=1;
      P22=0;
      P23=1;
          DataPort=TempData[2];
          delayms(2);

      P20=0;
      P21=0;
      P22=1;
      P23=1;
          DataPort=TempData[1];
          delayms(2);

      P20=1;
      P21=0;
      P22=1;
      P23=1;
          DataPort=TempData[0];
          delayms(2);

               
      P20=0;
      P21=0;
      P22=0;
      P23=1;
          DataPort=TempData[5];
          delayms(2);

          P20=1;
      P21=0;
      P22=0;
      P23=1;
          DataPort=TempData[4];
          delayms(2);

}

出0入0汤圆

 楼主| 发表于 2012-9-28 08:40:37 | 显示全部楼层
hameyou 发表于 2012-9-27 17:33
还是任务没处理好,请不要使用delayms(),之类的函数

是啊,就是这个问题,有Delayms而且用到六个,扫描很耗时间

出0入0汤圆

发表于 2012-9-28 08:46:25 | 显示全部楼层
本帖最后由 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[a1];}
      else if(k==1){shu1=0;shu2=1;shu3=0;shu4=0;P0=yima[a2];}
      else if(k==2){shu1=0;shu2=0;shu3=1;shu4=0;P0=yima[a3];}
      else if(k==3){shu1=0;shu2=0;shu3=0;shu4=1;P0=yima[a4];}
      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[a1];}
      else if(k==1){shu1=0;shu2=1;shu3=0;shu4=0;P0=yima[a2];}
      else if(k==2){shu1=0;shu2=0;shu3=1;shu4=0;P0=yima[a3];}
      else if(k==3){shu1=0;shu2=0;shu3=0;shu4=1;P0=yima[a4];}
      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[a1];}
           else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima[a4];}
                   else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima[a3];}
           else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima[a2];}
             }
             else  //熄灭
        {
           shu1=shu2=shu3=shu4=0; // P0=yima[10];                         
            }
       }  
       else //正常显示
    {     
                if     (k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima[a1];}
        else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima[a4];}
                else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima[a3];}
        else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima[a2];}
       }   
     
}



                               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; }

出0入0汤圆

 楼主| 发表于 2012-9-28 09:08:34 | 显示全部楼层
yao1 发表于 2012-9-28 08:46
void t0() interrupt 1 using 1  /*中断程序负责显示b的值 */
{
        unsigned char a1=0,a2=0,a3=0,a4= ...

这个群真好,有高手指导,把扫描程序也放进中断,果然也实现了键盘判断。呵呵
谢谢大哥!

出0入0汤圆

 楼主| 发表于 2012-9-28 09:15:25 | 显示全部楼层
hameyou 发表于 2012-9-28 08:54
根据数码管的位数,比如6位,开6个字节显示缓存,开一个定时器,1~2ms中断一次,每次显示一位数码管,轮询 ...

说得非常好。我想过的第一个,就是数码管每个定时器扫描一位。问题是开发板的74LS138驱动数码管,只用了三个IO,不知道有没有办法把三个脚编个组赋值的,呵呵。
键盘是74LS165驱动的,前几天好不容易在这个论坛找到的驱动,还没研究,呵呵,反正先做了个模块用起来了。

出0入0汤圆

发表于 2012-9-28 09:19:14 | 显示全部楼层
永远不要用DelayMS之类的函数,除非你只做个演示用的demo程序,这是个祸害啊

出0入0汤圆

发表于 2012-9-28 09:23:45 | 显示全部楼层
永远不要用DelayMS之类的函数,除非你只做个演示用的demo程序,这是个祸害啊



支持!

出0入0汤圆

发表于 2012-9-28 09:28:19 | 显示全部楼层
这个群真好,有高手指导,把扫描程序也放进中断,果然也实现了键盘判断。呵呵
谢谢大哥!



扫描程序别放入中断,放在主程序就行了!

出0入0汤圆

 楼主| 发表于 2012-9-28 09:30:08 | 显示全部楼层
liangong 发表于 2012-9-28 09:28
扫描程序别放入中断,放在主程序就行了!

嗯。我明白了。反正键盘判断和数码管得在一起,不管在主程序里还是在中断里面

出0入0汤圆

发表于 2012-9-28 09:32:19 | 显示全部楼层
嗯。我明白了。反正键盘判断和数码管得在一起,不管在主程序里还是在中断里面




不一定在一起!

出0入0汤圆

 楼主| 发表于 2012-9-28 09:36:52 | 显示全部楼层
liangong 发表于 2012-9-28 09:32
不一定在一起!

又明白了。11楼的程序很精妙,是不一定在一起,显示一位就回到主程序去键盘判断。我再试试

出0入0汤圆

发表于 2012-9-28 09:47:04 | 显示全部楼层
数码管和键盘都是扫描原理的,你可以用同一根线扫描数码管和键盘,两部分都会正常了

出0入0汤圆

发表于 2012-9-28 12:38:04 | 显示全部楼层
是最好不要用delayms()?还是不要用delay()?

毫秒级的延时最好不要用,但是延时函数是不是还是能用的呀?

出0入0汤圆

 楼主| 发表于 2012-9-28 12:59:35 | 显示全部楼层
本帖最后由 xts 于 2012-9-28 13:06 编辑
whyui 发表于 2012-9-28 12:38
是最好不要用delayms()?还是不要用delay()?

毫秒级的延时最好不要用,但是延时函数是不是还是能用的呀? ...


http://www.amobbs.com/thread-4666558-1-1.html中可以看看。他用定时器代替了延时的程序。定时器每次延时时间的总和就变成了延时时间。
我这儿定时器的延时扫描时间一个计数器中断时间已经够扫描了。呵呵,其实完全不用delay了。加了delay也是合理地像让程序在中断中停留一会,呵呵!

出0入0汤圆

 楼主| 发表于 2012-9-28 15:25:12 | 显示全部楼层
yao1 发表于 2012-9-28 08:46
void t0() interrupt 1 using 1  /*中断程序负责显示b的值 */
{
        unsigned char a1=0,a2=0,a3=0,a4= ...

太可惜了,闪烁的不太会实现,能不能发个完整的闪烁程序呀!我的键盘是74LS165驱动的,所以要研究下键盘。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 18:49

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表