打印

请教高人。数码管的显示问题

[复制链接]
3740|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
softerchang|  楼主 | 2010-10-28 09:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大哥大姐:
   小弟目前写一个软件,数码管显示6个阿拉伯数字。我使用的是cd4094来扩展io口,软件仿真是正常的,但一到实验板上,按一下加的时,数字从1变到6,而按一下减时,数字从6变到1,中间怎么按按键数字都不会变化。不知这时为什么?
void led_8display(uchar k)
{
   //uchar dis_data;
   switch(k)
   {
       case 1:  dis_data=0xf9;break;
       case 2:  dis_data=0xa3;break;
       case 3:  dis_data=0xb0;break;
       case 4:  dis_data=0xaa;break;
       case 5:  dis_data=0xa2;break;
       case 6:  dis_data=0x82;break;
      default: break;
    }
       delay_10ms( );
       dis_play( );
      
}

void  dis_play( )
{
   uchar j,i;
   i=dis_data;
   for(j=0;j<8;j++)
   {
      if((i<<j)&0x80)
        SDA=1;
      else
        SDA=0;
      _nop_();
      _nop_();
      CLK=1;
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      CLK=0;
      }
      STR=1;
      _nop_();
      _nop_();
      STR=0;
}

相关帖子

沙发
softerchang|  楼主 | 2010-10-28 12:06 | 只看该作者
刚才试验了一下,将我的定时器0的中断时间改为5ms后,就可正常显示了,但我原现使用的中断时间为1ms,这样一改后我的led显示就不正常了,这之间不知有什么好的平衡做法?

使用特权

评论回复
板凳
softerchang|  楼主 | 2010-10-28 15:08 | 只看该作者
怀疑是因为进入中断后,显示数据没有进行保护而引起错误,在c语言程序中,如何才能保护变量值呢?

使用特权

评论回复
地板
jtone| | 2010-10-28 16:36 | 只看该作者
楼主。。。

使用特权

评论回复
5
softerchang|  楼主 | 2010-10-29 12:04 | 只看该作者
我用汇编语言重写一遍后,ok,能正常显示。依此推断是我的定时中断时间短,而在mcu与cd4094通信时进入中断时当前值得不到保护才会出现错误。但是,在c当中如何才能做这点呢?

使用特权

评论回复
6
刘前辈| | 2010-10-29 15:41 | 只看该作者
本帖最后由 刘前辈 于 2010-10-29 15:50 编辑

哈!
1、中断程序使用(与前台不一样的)寄存器区1即可:   interrupt  using  1
2、或者:需要保护的临时变量不使用工作寄存器优化(编译时使用3级以下优化,躲开第4级。)
3、或者:需要独立执行完,不受中断影响的前台函数,在函数之前加入
#pragma  disable
     以禁止中断。
4、或者:需要保护现场的函数后加入 reentrant  
5、……

使用特权

评论回复
7
john_light| | 2010-10-29 16:04 | 只看该作者
利用参数传递显示段码,不要使用全局变量。

使用特权

评论回复
8
softerchang|  楼主 | 2010-10-29 16:06 | 只看该作者
谢6楼的答复。需要说明的是,我使用了你说的第一点,但没效果。第二点不知怎么用。我想试试你说的第四点。

使用特权

评论回复
9
softerchang|  楼主 | 2010-10-29 16:09 | 只看该作者
回第8楼:我利用局部变量来传递显示参数,还是不行。正要考虑使用指针呢。不过还是先试下6楼提供的方法。

使用特权

评论回复
10
john_light| | 2010-10-29 16:15 | 只看该作者
你按键消抖了吗?

使用特权

评论回复
11
刘前辈| | 2010-10-29 18:45 | 只看该作者
本帖最后由 刘前辈 于 2010-10-29 18:50 编辑

看所长的5ms、20ms同一timer0( )定时中断,很精彩的:5ms用于LED动态扫描,20ms用于键盘消抖。

//系统时间管理
//T0产生系统时间20ms
//T0中断5ms,处理弱实时任务。20ms主要提供按键扫描,5ms主要提供给数码LED用。

//T0中断
//处理弱实时任务,并产生20MS系统时间
//-------------------------------------------------------------------------
void Timer0(void) interrupt 1 using 1
{
    TH0 = sInSysTimer.mT0_PreLoad;        //重装T0高位初始值

    if( ++sInSysTimer.m20msCount > 3 ){      //  刘注:大于3=4,  4x5=20ms.  
        sInSysTimer.m20msCount = 0;
        //20ms触发
        fInSys_20ms = 1;
        //调用20ms中断要处理的弱实时任务
        if( sInSysTimer.Weekness_20ms )(*sInSysTimer.Weekness_20ms)();
    }

    //调用5ms中断要处理的弱实时任务。
    if( sInSysTimer.Weekness_5ms )(*sInSysTimer.Weekness_5ms)();

使用特权

评论回复
12
softerchang|  楼主 | 2010-10-29 18:55 | 只看该作者
我的按键消抖时间是15ms。

使用特权

评论回复
13
刘前辈| | 2010-10-29 19:14 | 只看该作者
要什么消抖?把下面2句调换顺序:
   delay_10ms( );
       dis_play( );

写成:
   dis_play( );
     delay_1s( );


一秒钟增长一个数,可行之后,再慢慢改进。

使用特权

评论回复
14
softerchang|  楼主 | 2010-10-30 09:14 | 只看该作者
问题是我不能有这么长的时间延时,因为我的负载工作的时间只能在10-100ms左右,这样我的时间是受限制的。

使用特权

评论回复
15
刘前辈| | 2010-10-30 10:21 | 只看该作者
交给我,很容易解决。
若不愿贴程序,就贴流程图也行。
把问题讲清楚。到底几个问题?

使用特权

评论回复
16
dong_abc| | 2010-10-30 19:54 | 只看该作者
顶LS

使用特权

评论回复
17
softerchang|  楼主 | 2010-11-1 16:18 | 只看该作者
本帖最后由 softerchang 于 2010-11-1 16:20 编辑

我帖出原程序,不过去掉了一些功能。但是不会影响主要的程序流程.
#include "ABSACC.h"
#include "intrins.h"
#include "STC12C5410AD.h"

#define  uchar  unsigned char
#define  unit   unsigned int

#define  m_force1_time  15
#define  m_force2_time  30
#define  m_force3_time  45
#define  m_force4_time  60
#define  m_force5_time  80
#define  m_force6_time  120                                                            
                                   
uchar  code  m1_table[ ],m2_table[ ],m3_table[ ];
uchar  code  *point1;


sbit  POWER_KEY=P3^0;
sbit  ADD_KEY=P3^0;
sbit  SUB_KEY=P3^0;

sbit  ALL_KEY=P2^3;
sbit  UP_KEY=P2^3;
sbit  DOWN_KEY=P2^3;

sbit  HOT_KEY=P2^2;

sbit  POWER_LED=P3^1;
sbit  HOT_LED=P3^2;

sbit  ALL_LED=P3^1;
sbit  UP_LED=P3^2;
sbit  DOWN_LED=P3^3;

sbit  SDA=P1^6;
sbit  CLK=P1^5;
sbit  STR=P1^7;

sbit  M1_OUT=P2^0;
sbit  M2_OUT=P2^1;
sbit  M3_OUT=P2^4;
sbit  M4_OUT=P2^5;

sbit  HOT_OUT=P2^6;

sbit  P1_0=P1^0;
sbit  P1_1=P1^1;
sbit  P2_2=P2^2;
sbit  P2_3=P2^3;
sbit  P3_0=P3^0;
sbit  P3_1=P3^1;
sbit  P3_2=P3^2;
sbit  P3_3=P3^3;
//uchar bdata time_flag;
uchar  bdata  key_flag;
sbit   POWER_PB_FLAG=key_flag^0;
sbit   ALL_PB_FLAG=key_flag^1;
sbit   UP_PB_FLAG=key_flag^2;
sbit   DOWN_PB_FLAG=key_flag^3;
sbit   ADD_PB_FLAG=key_flag^4;
sbit   SUB_PB_FLAG=key_flag^5;
sbit   HOT_PB_FLAG=key_flag^6;
sbit   POWER_FLAG=key_flag^7;

uchar  bdata  led_flag;
sbit   POWER_LED_FLAG=led_flag^0;
sbit   HOT_LED_FLAG=led_flag^1;
sbit   ALL_LED_FLAG=led_flag^2;
sbit   UP_LED_FLAG=led_flag^3;
sbit   DOWN_LED_FLAG=led_flag^4;

uchar   bdata   other_flag;
sbit   M_TIME_ENABLE=other_flag^0;
sbit   M_OPEN_FLAG=other_flag^1;
sbit   HOT_FLAG=other_flag^2;
sbit   M_START_FLAG=other_flag^3;
sbit   TIMER_ENABLE=other_flag^4;
sbit   KEY_OK_FLAG=other_flag^5;
sbit   KEY_PRESSED_FLAG=other_flag^6;


uchar  bdata   program_flag;
sbit   ALL_PROGRAM_FLAG=program_flag^0;
sbit   UP_PROGRAM_FLAG=program_flag^1;
sbit   DOWN_PROGRAM_FLAG=program_flag^2;
   

uchar data  clock_1s,key_timer,led_count,clock_10ms,clock_100ms;
uchar data  m1_data,m2_data,m3_data,m4_data,m_time,m_cnt,m_force,m_time_cnt;
uchar data  dis_buf;//dis_data;         //dis_data,

unit  data  timer_15m;

void  all_program( );
void  hot_program( );
void  speed_program( );
//void  delay_200ms( );
void  inital( );
void  led_8display( );
void  keyscan( );
void  ledscan( );
void  check_act_time( );
void  keyvalue( );
void  loaddata( );
void  set_time( );
void  motor_act( );
void  add_force( );
void  sub_force( );
void  dis_play(uchar ) reentrant;
void  power_off();
void  motor_out( );
void  delay500ms();
void  Pca_Init();
void  auto_test( );
void  delay_10ms( );
void  speed_adj( );

void main(void)
{
  inital( );
  Pca_Init();
  delay500ms();
  do
  {
  /* if(POWER_FLAG==0)
   {
     if(DOWN_PB_FLAG)
       DOWN_PB_FLAG=0;
           ALL_KEY=1;
           HOT_KEY=1;
         if(POWER_KEY==0)
         {
      do
         {
            auto_test( );
                }while(POWER_PB_FLAG);
         }
   }  */
  if(M_START_FLAG)
   {
          if(TIMER_ENABLE==0)
           {
                  power_off( );
                        inital( );
                        }
                else
                {
          // dis_play( );
       motor_act( );
             }
           }
   if(POWER_PB_FLAG)
     {
            POWER_PB_FLAG=0;
                POWER_FLAG=~POWER_FLAG;
                if(POWER_FLAG)
                 {
                        clock_10ms=10;
                        
                        TIMER_ENABLE=1;                        
                 }
                 else
                 {
                   power_off( );
                        inital( );         
                 }
          }
        if(POWER_FLAG)
        {
            if(ALL_PB_FLAG)
            {
            all_program( );
                }
            
            if(HOT_PB_FLAG)
             {
              hot_program( );
              }
                speed_adj( );           
           }
     }while(1);           
}



   
void  inital( )
{
   uchar display_data;
   TMOD=0x21;
   TH0=0xfc;
   TL0=0x18;
   ET0=1;
   EA=1;
   TR0=1;
   clock_1s=10;
   P1=0xff;
   P2=0xFF;
   P3=0xFF;
   led_flag=0xff;
   timer_15m=900;
   key_flag=0x00;
   other_flag=0x00;
   program_flag=0x00;
   led_count=0;
   clock_100ms=100;
   m_force=0;
   m_time_cnt=0;
//   dis_data=0xff;
   display_data=0xff;
   dis_play(display_data);
   }



void  time(void) interrupt 1 using 1
{
   
        TH0=0xfc;
    TL0=0x18;
   
        P3=(P3|0xff);
        _nop_();
        _nop_();
        P2_2=0;
        P2_3=0;
        P3_0=0;
        keyscan( );        
        if(KEY_PRESSED_FLAG)
        {
          if(KEY_OK_FLAG==0)
           {
              key_timer=15;
                  KEY_OK_FLAG=1;
                 }
          else
            {
                  key_timer--;
                  if(key_timer==0)
                            keyvalue( );
                 }      
          }
         ledscan( );
         check_act_time( );
        

         
}

void keyscan( )
{
   

   if((P3&0xfe)!=0xfe)
        {
             if((P3&0xfe)!=0xfe)
                  {
                    KEY_PRESSED_FLAG=1;
                        //key_timer=20;
                        }
        }
//        else
//        {
  //    key_timer=20;                                                
//        }
                        
}
   
void  keyvalue( )
{
    bit C;
    KEY_OK_FLAG=0;
           P2_2=1;
        P2_3=1;
        P3_0=1;
        _nop_();
        _nop_();
    P3_1=0;
        P3_2=1;
        P3_3=1;
    _nop_();
        _nop_();
         
         C=HOT_KEY;
         HOT_PB_FLAG=~C;
         C=ALL_KEY;
         ALL_PB_FLAG=~C;
         C=POWER_KEY;
         POWER_PB_FLAG=~C;
               
        P3_1=1;
        P3_2=0;
        P3_3=1;
    _nop_();
        _nop_();
        C=UP_KEY;               
        UP_PB_FLAG=~C;
        C=ADD_KEY;
        ADD_PB_FLAG=~C;
        
        P3_1=1;
        P3_2=1;
        P3_3=0;
    _nop_();
        _nop_();
        C=DOWN_KEY;            
        DOWN_PB_FLAG=~C;
        C=SUB_KEY;                 
        SUB_PB_FLAG=~C;
         
        P3_1=1;
        P3_2=1;
        P3_3=1;
        _nop_();
        _nop_();
  }  
  
void  ledscan( )
{
    P3_1=1;
        P3_2=1;
        P3_3=1;
    P1_0=1;
        P1_1=1;
        
        _nop_();
        _nop_();
        if(POWER_FLAG==0)
        {
          P1_0=0;P1_1=1;
          POWER_LED=POWER_LED_FLAG;
          }
        else
         {
           led_count++;
       switch(led_count)
              {
                     
                         case 1:P1_0=0;P1_1=1;
                                 POWER_LED=POWER_LED_FLAG;HOT_LED=HOT_LED_FLAG;break;
                         case 2:P1_0=1;P1_1=0;
                                 ALL_LED=ALL_LED_FLAG;UP_LED=UP_LED_FLAG;
                                 DOWN_LED=DOWN_LED_FLAG;led_count=0;break;
                         default:break;
                         }
          }
}         

void  check_act_time( )
{
   bit CB;
   clock_10ms--;
   if(clock_10ms==0)
  {
         clock_10ms=10;
         if(M_TIME_ENABLE)
         {
            m_time--;
                if(m_time==0)
                {
                   M_TIME_ENABLE=0;
                   }
                }
    }               

   
}

void motor_act( )
{
    if(M_OPEN_FLAG==0)
        {
           M_OPEN_FLAG=1;
           loaddata( );
           set_time( );           
           motor_out( );
           }
        else
        {
           if(M_TIME_ENABLE==0)
           {
              m_cnt--;
                  if(m_cnt==0)
                  {
                    loaddata( );
                   if(m1_data==0xff)
                   {
                     if(ALL_PROGRAM_FLAG)
                           point1=m1_table;
                         if(UP_PROGRAM_FLAG)
                            point1=m2_table;
                         if(DOWN_PROGRAM_FLAG)
                                    point1=m3_table;
                           M1_OUT=1;
                           _nop_();
                           _nop_();
                           M2_OUT=1;
                           _nop_();
                           _nop_();
                           M3_OUT=1;
                           _nop_();
                           _nop_();
                           M4_OUT=1;
                           _nop_();
                           _nop_();
                         M_OPEN_FLAG=0;
                    }
                   else
                      {
                   set_time( );
                       motor_out( );
                            }
                   }        
                   else
               {
                   set_time( );
                   }         
            }
        }  
           
}
   
void  loaddata( )
{
    m1_data=*point1;
        point1++;
        m2_data=*point1;
        point1++;
        m3_data=*point1;
        point1++;
        m4_data=*point1;
        point1++;
        m_cnt=*point1;
        point1++;
        }

void set_time( )
{
   switch(m_time_cnt)
   {
      case 1:m_time=m_force1_time;break;
          case 2:m_time=m_force2_time;break;
          case 3:m_time=m_force3_time;break;
          case 4:m_time=m_force4_time;break;
          case 5:m_time=m_force5_time;break;
          case 6:m_time=m_force6_time;break;
          default:break;
          }
          M_TIME_ENABLE=1;        
}


void  motor_out( )
{
  if(m1_data==1)
        {
           M1_OUT=0;
           _nop_();
           _nop_();
        }
  else
        {
           M1_OUT=1;
           _nop_();
           _nop_();
         }
  if(m2_data==1)
        {
           M2_OUT=0;
           _nop_();
           _nop_();
        }
  else
        {
           M2_OUT=1;
           _nop_();
           _nop_();
        }
  if(m3_data==1)
        {
           M3_OUT=0;
           _nop_();
           _nop_();
        }
  else
        {
           M3_OUT=1;
           _nop_();
           _nop_();
        }         
  if(m4_data==1)
        {
           M4_OUT=0;
           _nop_();
           _nop_();
        }
  else
    {
           M4_OUT=1;
           _nop_();
           _nop_();
        }
}

void  all_program( )
{
   ALL_PB_FLAG=0;
   ALL_LED_FLAG=0;
   UP_LED_FLAG=1;
   DOWN_LED_FLAG=1;
   M_START_FLAG=1;
   ALL_PROGRAM_FLAG=1;
   UP_PROGRAM_FLAG=0;
   DOWN_PROGRAM_FLAG=0;
   point1=m1_table;
   if(m_force==0)
   {
      m_force=1;
          dis_buf=1;
          m_time_cnt=1;
          }
   else
    {
        m_time_cnt=m_force;
        dis_buf=m_force;
        }
           led_8display( );
}


void  hot_program( )
{
    HOT_PB_FLAG=0;
        HOT_FLAG=~HOT_FLAG;
        if(HOT_FLAG)
        {
           HOT_LED_FLAG=0;
           HOT_OUT=0;
           }
        else
          {
             HOT_LED_FLAG=1;
                 HOT_OUT=1;
                 }
}
void  speed_adj( )
{
if(M_START_FLAG)
{
   if(ADD_PB_FLAG)
          {
            add_force( );
                }
        if(SUB_PB_FLAG)
          {
            sub_force( );
                }
   }
}
void  add_force( )
{
   
    ADD_PB_FLAG=0;
           m_force++;
        if(m_force>6)
     m_force=6;
        dis_buf=m_force;
        m_time_cnt=m_force;
        led_8display( );

}

void  sub_force( )
{
   
    SUB_PB_FLAG=0;
        m_force--;
        if(m_force<1)
         m_force=1;
        dis_buf=m_force;
        m_time_cnt=m_force;        
        led_8display( );
        
}

void led_8display()        
{
   
           uchar dis_data;
   switch(dis_buf)
   {
       case 1:dis_data=0xf9;break;
           case 2:dis_data=0xa4;break;
           case 3:dis_data=0xb0;break;
           case 4:dis_data=0x99;break;
           case 5:dis_data=0x92;break;
           case 6:dis_data=0x82;break;
           default:break;
        }
           dis_play(dis_data);
           
}        

void  dis_play(uchar j ) reentrant
{
   uchar i;
   
   for(i=0;i<8;i++)
   {
      if((j<<i)&0x80)
            SDA=1;
          else
            SDA=0;
          CLK=1;
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          CLK=0;
          }
          STR=1;
          _nop_();
          _nop_();
          STR=0;
         
}

void delay500ms()
{
   uchar m,n,f;
                        for(m=15;m>0;m--)
                        for(n=202;n>0;n--)
                        for(f=81;f>0;f--)
                        ;
        }

void delay_10ms()
{
  uchar i,j,k;
  for(i=5;i>0;i--)
  for(j=4;j>0;j--)
  for(k=248;k>0;k--)
  ;
  }

void auto_test( )
{
   uchar  a,b;

   ALL_LED_FLAG=1;
   UP_LED_FLAG=1;
   DOWN_LED_FLAG=0;
   POWER_LED_FLAG=0;
   do
   {
           HOT_OUT=0;
       M1_OUT=0;
           M2_OUT=1;
           M3_OUT=1;
           M4_OUT=1;           
           delay500ms();
           M1_OUT=1;
           M2_OUT=0;
           M3_OUT=1;
           M4_OUT=1;           
           delay500ms();
           M1_OUT=1;
           M2_OUT=1;
           M3_OUT=0;
           M4_OUT=1;           
           delay500ms();
           M1_OUT=1;
           M2_OUT=1;
           M3_OUT=1;
           M4_OUT=0;           
           delay500ms();
           delay500ms();
           M1_OUT=0;
           M2_OUT=0;
           M3_OUT=0;
           M4_OUT=0;
           for(a=0;a<4;a++)
           {           
            delay500ms();
           }  
           M1_OUT=1;
           M2_OUT=1;
           M3_OUT=1;
           M4_OUT=1;
           for(b=0;b<4;b++)
           {           
            delay500ms();
           }
           }while(POWER_PB_FLAG);
          inital( );
}  


void Pca_Init()
{
   CMOD=0x80;
   CCON=0x00;
   CL=0x00;
   CH=0x00;
   CCAPM0=0x42;
   PCA_PWM0=0x00;
  // PCA_PWM1=0x03;

   EPCA_LVD=1;              //开 PCA 中断
   CR=1;
   EA=1;   
   
   }   
#include "all_table.inc"
#include "up_table.inc"
#include "down_table.inc"

使用特权

评论回复
18
softerchang|  楼主 | 2010-11-2 14:52 | 只看该作者
期待中!!!

使用特权

评论回复
19
刘前辈| | 2010-11-2 20:15 | 只看该作者
本帖最后由 刘前辈 于 2010-11-2 20:17 编辑

很简单:
1、把键盘扫描和处理程序从中断ISR中拿出去;放在前台处理;
2、把 ledscan( )拿出去,放在前台处理,中断设置处理标识就行;
3、把check_act_time( )拿出去放在前台处理;

总之5ms(不是1ms)中断时标程序越短越好,这样C编译器要做的保护现场工作就简单了。

如果原来可以,不愿大改,那么试一下:

#pragma  disable  //以下函数关闭中断

void led_8display()        
{
           uchar dis_data;
   switch(dis_buf)
   {
       case 1:dis_data=0xf9;break;
           case 2:dis_data=0xa4;break;
           case 3:dis_data=0xb0;break;
           case 4:dis_data=0x99;break;
           case 5:dis_data=0x92;break;
           case 6:dis_data=0x82;break;
           default:break;
        }
           dis_play(dis_data);
           
}

有问题再看。

使用特权

评论回复
20
原野之狼| | 2010-11-2 20:37 | 只看该作者
刘前辈 您把前后台的概念搞反了:)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

83

主题

327

帖子

2

粉丝