搜索
bottom↓
回复: 45

段式数码管扫描程序如何减少代码量(采用扫描段码方式)

  [复制链接]

出0入0汤圆

发表于 2014-4-11 14:27:27 | 显示全部楼层 |阅读模式
最近弄LED段式数码管程序(采用扫描段码方式),但是编写后发现代码多,不知如何可以减少代码量。

//====================================================================
//===          显示扫描函数          ===//
void display_scan(void)
{
    unsigned char i;
    P1 &= Bin(11111110);
    P1 |= Bin(11111000);
    P2 &= Bin(00000000);
    P3 &= Bin(01100111);
    P3 |= Bin(01100110);  //关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
//======================================//
    for(i = 0;i < 4;i ++)
    {
        r_dis_data[i] = table_seg[r_dis_buff[i]];    //查LED段码表
    }
    switch (r_dig_bit)                                      //在公共端接限流电阻,在数码管位数少时布线时有优势
    {
        case 1:
            p_seg_a = 0;                                    //扫描a段
            if(r_dis_data[0] & 0x01) p_dig_1 = 1;  //如果r_dis_data[0]第0位为高,则需要点亮,反之则不点亮
            if(r_dis_data[1] & 0x01) p_dig_2 = 1;
            if(r_dis_data[2] & 0x01) p_dig_3 = 1;
            if(r_dis_data[3] & 0x01) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x01) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x01) p_dig_6 = 1;
            break;
        case 2:
            p_seg_b = 0;
            if(r_dis_data[0] & 0x02) p_dig_1 = 1;
            if(r_dis_data[1] & 0x02) p_dig_2 = 1;
            if(r_dis_data[2] & 0x02) p_dig_3 = 1;
            if(r_dis_data[3] & 0x02) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x02) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x02) p_dig_6 = 1;
            break;
        case 3:
            p_seg_c = 0;
            if(r_dis_data[0] & 0x04) p_dig_1 = 1;
            if(r_dis_data[1] & 0x04) p_dig_2 = 1;
            if(r_dis_data[2] & 0x04) p_dig_3 = 1;
            if(r_dis_data[3] & 0x04) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x04) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x04) p_dig_6 = 1;
            break;
        case 4:
            p_seg_d = 0;
            if(r_dis_data[0] & 0x08) p_dig_1 = 1;
            if(r_dis_data[1] & 0x08) p_dig_2 = 1;
            if(r_dis_data[2] & 0x08) p_dig_3 = 1;
            if(r_dis_data[3] & 0x08) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x08) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x08) p_dig_6 = 1;
            break;
        case 5:     
            p_seg_e = 0;
            if(r_dis_data[0] & 0x10) p_dig_1 = 1;
            if(r_dis_data[1] & 0x10) p_dig_2 = 1;
            if(r_dis_data[2] & 0x10) p_dig_3 = 1;
            if(r_dis_data[3] & 0x10) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x10) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x10) p_dig_6 = 1;
            break;
        case 6:
            p_seg_f = 0;
            if(r_dis_data[0] & 0x20) p_dig_1 = 1;
            if(r_dis_data[1] & 0x20) p_dig_2 = 1;
            if(r_dis_data[2] & 0x20) p_dig_3 = 1;
            if(r_dis_data[3] & 0x20) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x20) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x20) p_dig_6 = 1;
            break;
        case 7:
            p_seg_g = 0;
            if(r_dis_data[0] & 0x40) p_dig_1 = 1;
            if(r_dis_data[1] & 0x40) p_dig_2 = 1;
            if(r_dis_data[2] & 0x40) p_dig_3 = 1;
            if(r_dis_data[3] & 0x40) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x40) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x40) p_dig_6 = 1;
            break;
        case 8:
            p_seg_h = 0;
            if(r_dis_data[0] & 0x80) p_dig_1 = 1;
            if(r_dis_data[1] & 0x80) p_dig_2 = 1;
            if(r_dis_data[2] & 0x80) p_dig_3 = 1;
            if(r_dis_data[3] & 0x80) p_dig_4 = 1;
            if(r_dis_buff[4] & 0x80) p_dig_5 = 1;
            if(r_dis_buff[5] & 0x80) p_dig_6 = 1;
            break;
        default:
            keyscan_process();      //按键扫描
            break;
    }
    r_dig_bit ++;
    if(r_dig_bit >= 9)    //扫描时基
    r_dig_bit = 0;
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-14 09:22:37 | 显示全部楼层
switch (r_dig_bit)
{
        case 0:
            p_seg_a = 0;
            break;
                case 1:
            p_seg_b = 0;
                        break;
                ......
}
if(r_dis_data[0] & (1<<r_dig_bit)) p_dig_1 = 1;
if(r_dis_data[1] & (1<<r_dig_bit)) p_dig_2 = 1;
......
r_dig_bit ++;
if(r_dig_bit >= 8)    //扫描时基
r_dig_bit = 0;

(1<<r_dig_bit)可以用数组代替。
这个switch 语句也可以用数组代替。
例如:
P1|=table_p1set[r_dig_bit];//置高某些位
P1&=table_p1clr[r_dig_bit];//置低某些位

出0入0汤圆

发表于 2014-4-14 13:00:22 | 显示全部楼层
本帖最后由 yilin411 于 2014-4-14 13:05 编辑

/*****************************************************************************  
显示表格
*****************************************************************************/
const u8 LedDisplay_B[10] = {0x1b,0x08,0x1d,0x1c,0x0e,0x16,0x17,0x18,0x1f,0x1e};
const u8 LedDisplay_C[10] = {0x03,0x01,0x02,0x03,0x01,0x03,0x03,0x01,0x03,0x03};//数字0~9  

#define Dispaly_Off()   _pb = 0x20;_pc = 0x04   

/*****************************************************************************  
函 数 名  : F_Display  
功能描述  : 数码管分时扫描(2位7段数码管)  
输入参数  : R_Display_Dat   
输出参数  : 无  
返 回 值  : 无  
调用函数  : 无  
被调函数  : 无
*****************************************************************************/
void F_Display(u8 R_Display_Dat)
{        
        R_Display_Dat_shi = R_Display_Dat / 10;        
        R_Display_Dat_ge  = R_Display_Dat % 10;
         
        if(0 == R_Display_cnt)        
        {                
                Dispaly_Off();                
                _pb |= LedDisplay_B[R_Display_Dat_ge];                
                _pc |= LedDisplay_C[R_Display_Dat_ge];        
        }        
        else if(1 == R_Display_cnt)        
        {                
                Dispaly_Off();                
                _pb |= LedDisplay_B[R_Display_Dat_shi];                
                _pc |= LedDisplay_C[R_Display_Dat_shi];         
        }
       
        R_Display_cnt++;        
        if(R_Display_cnt >= 2)        
        {                
                R_Display_cnt = 0;        
        }
}

出0入4汤圆

发表于 2014-4-14 13:32:14 | 显示全部楼层
yilin411 发表于 2014-4-14 13:00
/*****************************************************************************  
显示表格
********* ...

我程序就是用这种方式,感觉挺省的。

出0入0汤圆

发表于 2014-4-14 20:25:54 | 显示全部楼层
1位 6段,大侠给瞅瞅。
/*********** 显示子程序 *************/
void        Disp()//显示
{
        Disp_Num++;
        Disp_F_Num++;
        if(Disp_F_Num == 100)
        {
                Disp_F_Num = 0;
                if(Disp_1_F)//数码闪烁
                        Dis1 = ~Dis1;
                else//数码不闪烁
                        Dis1 = Duan_Liang;
                if(Disp_2_F)//数码闪烁
                        Dis2 = ~Dis2;
                else//数码不闪烁
                        Dis2 = Duan_Liang;
                if(Disp_3_F)//数码闪烁
                        Dis3 = ~Dis3;
                else//数码不闪烁
                        Dis3 = Duan_Liang;
                if(Disp_4_F)//数码闪烁
                        Dis4 = ~Dis4;
                else//数码不闪烁
                        Dis4 = Duan_Liang;
                if(Disp_5_F)//数码闪烁
                        Dis5 = ~Dis5;
                else//数码不闪烁
                        Dis5 = Duan_Liang;
                if(Disp_6_F)//数码闪烁
                        Dis6 = ~Dis6;
                else//数码不闪烁
                        Dis6 = Duan_Liang;
        }

        Disp_1 = Disp_2 = Disp_3 = Disp_4 = Disp_5 = Disp_6 = Duan_Mie;//先都熄灭
        switch(Disp_Num)
        {//第 1 数码管显示 20MS后,显示第 2 数码管
                case        1:
                        //显示 第 1 个 8 字
                        if(Dis1 == Duan_Liang)
                        {
                                P2 = Display_Buf[0];// 百位
       
                                if(Disp_N1)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_1 = Duan_Liang;
                        }
                        break;
                case        2:
                        //显示 第 2 个 8 字
                        if(Dis2 == Duan_Liang)
                        {
                                P2 = Display_Buf[1];// 十位
                                if(Disp_N2)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_2 = Duan_Liang;
                        }
                        break;
                case        3:
                        //显示 第 3 个 8 字
                        if(Dis3 == Duan_Liang)
                        {
                                P2 = Display_Buf[2];// 个位
                                if(Disp_N3)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_3 = Duan_Liang;
                        }
                //        Disp_Num = 0;
                        break;
                case        4:
                        //显示 第 1 个 8 字
                        if(Dis4 == Duan_Liang)
                        {
                                P2 = Display_Buf[3];// 百位
       
                                if(Disp_N4)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_4 = Duan_Liang;
                        }
                        break;
                case        5:
                        //显示 第 2 个 8 字
                        if(Dis5 == Duan_Liang)
                        {
                                P2 = Display_Buf[4];// 十位
                                if(Disp_N5)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_5 = Duan_Liang;
                        }
                        break;
                case        6:
                        //显示 第 3 个 8 字
                        if(Dis6 == Duan_Liang)
                        {
                                P2 = Display_Buf[5];// 个位
                                if(Disp_N6)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number[11];
                                }
                                Disp_6 = Duan_Liang;
                        }
                        Disp_Num = 0;
                        break;
        }
}

出0入0汤圆

发表于 2014-4-14 20:42:57 | 显示全部楼层
长见识

出0入0汤圆

 楼主| 发表于 2014-4-16 09:06:12 | 显示全部楼层
yilin411 发表于 2014-4-14 13:00
/*****************************************************************************  
显示表格
********* ...

您这个是段码,位码分别在同一组IO口。如果在不同IO口怎么办呢?

出0入0汤圆

 楼主| 发表于 2014-4-16 09:07:50 | 显示全部楼层
lcw_swust 发表于 2014-4-14 09:22
switch (r_dig_bit)
{
        case 0:


试过了这个程序,比之前代码少了1/4左右,虽然有点少,不过能减少代码还是很不错的。。。。多谢您提供方法。

出0入0汤圆

 楼主| 发表于 2014-4-16 09:09:55 | 显示全部楼层
lyhfdz 发表于 2014-4-14 20:25
1位 6段,大侠给瞅瞅。
/*********** 显示子程序 *************/
void        Disp()//显示

您这个代码量比我的应该不会少吧?

出0入0汤圆

发表于 2014-4-16 09:13:08 | 显示全部楼层
lmt50211 发表于 2014-4-16 09:06
您这个是段码,位码分别在同一组IO口。如果在不同IO口怎么办呢?

只是给你参考,不在同一口这样的问题应该难不倒你吧。同一个口多的做成表格,少的直接控制,很简单的事

出0入0汤圆

发表于 2014-4-16 09:33:40 | 显示全部楼层
用3维数组做段码液晶表的路过(这是我第一次接触段码液晶)

出0入0汤圆

 楼主| 发表于 2014-4-16 09:40:19 | 显示全部楼层
以前有做个二维的

出0入0汤圆

 楼主| 发表于 2014-4-16 09:42:50 | 显示全部楼层
cmheia 发表于 2014-4-16 09:33
用3维数组做段码液晶表的路过(这是我第一次接触段码液晶)

以前有做个二维的

出0入0汤圆

发表于 2014-4-16 12:13:38 | 显示全部楼层
是不是这个意思?
unsigned char segment;  //扫描段数

void TransmitDisplayByte(unsigned char code){
   
}

void segmentScan(unsigned char *bufferAddress, unsigned char amount){
    unsigend char i;
    unsigend char buffer = 0;
    for (i = 0; i < amount; i++){  //位码转换  末位 ---> 首位
        buffer <<= 1;
        if (*(bufferAddress + i) & (1 << segment)){
            buffer++;
        }
        if ((i + 1) % 8 == 0){  //发送位码
            TransmitDisplayByte(buffer);
        }
    }
    if (i % 8 != 0){  //发送最后几位位码
        TransmitDisplayByte(buffer);
    }
    //发送段码
    TransmitDisplayByte();
    if (segment < 7){  //8段数码管 一个完整显示周期扫描8次
        segment++;
    }else{
        segment = 0;
    }
}

上面的代码没试过,只是个思路。

出0入0汤圆

发表于 2014-4-16 13:06:45 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-5-11 11:56:04 | 显示全部楼层
楼上的扫描代码测试通过
static void SegmentSan(unsigned char *bufferAddress, unsigned char com)
{
           static unsigned char segment = 0;  //扫描段数
           unsigned char i;
     unsigned char buffer =0;
           //消隐,关闭段码&位码 如共阴(COM 置高,段码置低)
          WriteOneByte(0xFF);  //发送位码         
                 WriteOneByte(0x00);  //发送段码   
                 HC595_LATCH(0);   
     HC595_LATCH(1);     
   //一个循环周期16ms 65.2HZ  8段 每段 16/8=2ms  
   //限流电阻放置在公共端,在数码管位数少时布线时有优势  适合段示扫描  
   for (i = 0; i < com; i++)             //位码转换  末位 ---> 首位
     {      
         buffer <<= 1;   
        if(*(bufferAddress + i) & (1 <<segment))
                {         
            buffer|=0x1;            
         }
        if ((i + 1) % 8 == 0)             //超出8位,满8位发送位码
         {                       
                        WriteOneByte(~buffer);        //位码, buf第0位为高,则需要点亮,反之则不点亮   共阴L  共阳H         
          }
       }  
      if (i % 8 != 0)                     //不满8位或超出8位的位码                        
                {
                  WriteOneByte(~buffer);        //发送位码                                                                 
          }               
    WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码   
    HC595_LATCH(0);   
    HC595_LATCH(1);            
   if(++segment > 8) segment = 0;        //8段数码管一个完整显示周期扫描8次
}

出0入0汤圆

发表于 2014-5-11 12:08:23 | 显示全部楼层
我看到有产品上使用4 位数码管做 4~20mA ,看上去效果也不错。
仔细想了一下,每个数码管的大概2mA 左右,提高扫描速度,每次只点亮一个灯。这样数码管的平均电流也差不多在2mA.

实例代码如下,已经测试通过。
static void DotSegment_Scan(unsigned char *bufferAddress, unsigned char com)
{
           static unsigned char segment = 0;  //扫描段数
     static unsigned char ComScan = 0;
     unsigned char i;
     unsigned char buffer =0;
     
     //消隐,关闭段码&位码 如共阴(COM 置高,段码置低)
     //限流电阻不要放在被扫描的一端
     WriteOneByte(0xFF);  //发送位码         
                 WriteOneByte(0x00);  //发送段码   
                 HC595_LATCH(0);   
     HC595_LATCH(1);         
     //COM*8 个灯,适合位数比较少的情况下,平均电流2.5mA
    switch(segment)   
      {
          case 0:  
            if(*(bufferAddress + ComScan) & (1 <<segment))
                     buffer|=0x1;
               WriteOneByte(~(buffer<<ComScan));
               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
               HC595_LATCH(0);   
               HC595_LATCH(1);          
               if(++ComScan > com)
                       {
                               ComScan = 0;   
                  segment++;       
                }          
               break;       
           case 1:          
                   if(*(bufferAddress + ComScan) & (1 <<segment))
                     buffer|=0x1;
               WriteOneByte(~(buffer<<ComScan));
               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
               HC595_LATCH(0);   
               HC595_LATCH(1);               
               if(++ComScan > com)
                       {  ComScan = 0;   
                   segment++;       
                }          
               break;
            case 2:          
                          if(*(bufferAddress + ComScan) & (1 <<segment))
                             buffer|=0x1;
                       WriteOneByte(~(buffer<<ComScan));
                       WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                       HC595_LATCH(0);   
                       HC595_LATCH(1);                        
                       if(++ComScan > com)
                               {  
                                       ComScan = 0;   
                          segment++;       
                        }          
                       break;
             case 3:          
                                  if(*(bufferAddress + ComScan) & (1 <<segment))
                                    buffer|=0x1;
                              WriteOneByte(~(buffer<<ComScan));
                              WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                              HC595_LATCH(0);   
                              HC595_LATCH(1);                                        
                              if(++ComScan > com)
                                       {  
                                               ComScan = 0;   
                                  segment++;       
                                }          
                               break;
              case 4:          
                                   if(*(bufferAddress + ComScan) & (1 <<segment))
                                     buffer|=0x1;
                               WriteOneByte(~(buffer<<ComScan));
                               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                               HC595_LATCH(0);   
                               HC595_LATCH(1);          
                               if(++ComScan > com)
                                       {  
                                               ComScan = 0;   
                                  segment++;       
                                }          
                               break;
             case 5:          
                                    if(*(bufferAddress + ComScan) & (1 <<segment))
                                     buffer|=0x1;
                               WriteOneByte(~(buffer<<ComScan));
                               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                               HC595_LATCH(0);   
                               HC595_LATCH(1);       
                               if(++ComScan > com)
                                       {  
                                               ComScan = 0;   
                                  segment++;       
                                }          
                               break;
              case 6:          
                                    if(*(bufferAddress + ComScan) & (1 <<segment))
                                     buffer|=0x1;
                               WriteOneByte(~(buffer<<ComScan));
                               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                               HC595_LATCH(0);   
                               HC595_LATCH(1);          
                               if(++ComScan > com)
                                       {  
                                               ComScan = 0;   
                                  segment++;       
                                }          
                               break;
              case 7:          
                                   if(*(bufferAddress + ComScan) & (1 <<segment))
                                     buffer|=0x1;
                               WriteOneByte(~(buffer<<ComScan));
                               WriteOneByte(*(const unsigned char*)(bitDispDef+segment));  //发送段码
                               HC595_LATCH(0);   
                               HC595_LATCH(1);                        
                               if(++ComScan > com)
                                       {  
                                               ComScan = 0;   
                                  segment =0;       
                                }          
                 break;        
                     default: segment =0; break;
           }
        }

出0入0汤圆

发表于 2014-5-11 12:21:43 | 显示全部楼层
void LEDsFlash_Update()
{
   static uchar data loop;

   LEDs_OFF();

   loop++;
   if(loop>=250) { loop=0; }

   switch(loop%5)
     {                                                          

       case 0:
         P0 = LEDs_display[mLEDs_Code[4]];
         LED1_pin = LED_LIGHT;
         break;
       case 1:
         P0 = LEDs_display[mLEDs_Code[3]];
         LED2_pin = LED_LIGHT;
         break;
       case 2:
         P0 = LEDs_display[mLEDs_Code[2]];
         LED3_pin = LED_LIGHT;
         break;
       case 3:
         P0 = LEDs_display[mLEDs_Code[1]];
         LED4_pin = LED_LIGHT;  
         break;
       case 4:
         P0 = LEDs_display[mLEDs_Code[0]];
         LED5_pin = LED_LIGHT;  
         break;
     }
}

出0入0汤圆

发表于 2014-5-12 14:18:27 | 显示全部楼层
好多代码啊,慢慢看,学习学习

出0入0汤圆

发表于 2014-5-12 14:35:43 | 显示全部楼层
直接上专用片子就行。

出0入0汤圆

 楼主| 发表于 2014-5-13 08:27:34 | 显示全部楼层
jacky_yhy 发表于 2014-5-12 14:35
直接上专用片子就行。

我们是说如何能减少代码,不是要更改硬件方面的的东西。。。。

出0入0汤圆

 楼主| 发表于 2014-5-13 08:28:15 | 显示全部楼层
xiaoguo_nihao 发表于 2014-5-12 14:18
好多代码啊,慢慢看,学习学习

大家一起学习,一起进步。。。。

出0入0汤圆

发表于 2014-5-31 11:09:40 | 显示全部楼层
为用专用的芯片省事.

出0入8汤圆

发表于 2014-5-31 12:15:43 | 显示全部楼层
iwqt1983 发表于 2014-5-31 11:09
为用专用的芯片省事.

专用的芯片贵啊。

出0入0汤圆

发表于 2014-6-11 16:08:50 | 显示全部楼层
看看代码学习一下。。。。。。。。。。

出145入215汤圆

发表于 2014-6-12 12:23:15 | 显示全部楼层
本帖最后由 dz20062008 于 2014-6-12 12:29 编辑

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DISPLAY:
          MOV R0,#10H                  ;逐位把显示缓存的LED代码显示出来
          MOV R1,#00H                    ;清零刷新位数计数值
                  
          MOV A,#01111111B
          SETB CY                ;控制逐位显示刷新的刷新方向
  LEDLOOP:MOV LED_DATA,@R0                ;LED段码送LED屏
          SETB LED_DUAN                    ;送LED段码值到74HC373-A缓存
          CLR LED_DUAN                        ;缓存LED段码
          MOV LED_DATA,A                    ;LED位码送LED屏
          SETB LED_WEI                        ;送LED位码值到74HC373-B缓存
          CLR LED_WEI                        ;缓存LED位码
          LCALL LED_DELAY                ;位与位显示之间的显示延时
          MOV LED_DATA,#00H
          SETB LED_DUAN
          CLR  LED_DUAN
          MOV LED_DATA,#0FFH
          SETB LED_WEI
          CLR  LED_WEI                 
          RR A                              ;更新LED位码值
          INC R0                            ;LED段码指针增一
          INC R1                            ;LED显示位数计数
          CJNE R1,#8D,LEDLOOP               ;显示完了吗?         
          RET                               ;显示完了,返回主程序
                  
LED_DELAY:PUSH ACC
          MOV R7,#4D                        ;装入显示延时循环的外圈值
      D1:MOV     R6,#100D                  ;装入显示延时循环的内圈值
      D2:DJNZ    R6,D2                     ;内圈循环
          DJNZ    R7,D1                     ;外圈循环
          POP ACC
          RET

出0入0汤圆

发表于 2014-6-12 14:10:18 | 显示全部楼层
本帖最后由 gotofly100 于 2014-6-12 14:12 编辑

void display_scan(void)
{
    unsigned char i;
    P1 &= Bin(11111110);
    P1 |= Bin(11111000);
    P2 &= Bin(00000000);
    P3 &= Bin(01100111);
    P3 |= Bin(01100110);  //关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
//======================================//
    for(i = 0;i < 4;i ++)
    {
        r_dis_data = table_seg[r_dis_buff];    //查LED段码表
    }
    switch (r_dig_bit)                                      //在公共端接限流电阻,在数码管位数少时布线时有优势
    {
        case 1:
            p_seg_a = 0;   //扫描a段
            // if(r_dis_data[0] & 0x01) p_dig_1 = 1;  //如果r_dis_data[0]第0位为高,则需要点亮,反之则不点亮
            // if(r_dis_data[1] & 0x01) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x01) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x01) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x01) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x01) p_dig_6 = 1;
                        //i=0x01;
                       
            break;
        case 2:
            p_seg_b = 0;
            // if(r_dis_data[0] & 0x02) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x02) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x02) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x02) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x02) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x02) p_dig_6 = 1;
                                //i=0x02;
            break;
        case 3:
            p_seg_c = 0;
            // if(r_dis_data[0] & 0x04) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x04) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x04) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x04) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x04) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x04) p_dig_6 = 1;
            break;
        case 4:
             p_seg_d = 0;
            // if(r_dis_data[0] & 0x08) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x08) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x08) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x08) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x08) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x08) p_dig_6 = 1;
            break;
        case 5:     
            p_seg_e = 0;
            // if(r_dis_data[0] & 0x10) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x10) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x10) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x10) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x10) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x10) p_dig_6 = 1;
            break;
        case 6:
            p_seg_f = 0;
            // if(r_dis_data[0] & 0x20) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x20) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x20) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x20) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x20) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x20) p_dig_6 = 1;
            break;
        case 7:
            p_seg_g = 0;
            // if(r_dis_data[0] & 0x40) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x40) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x40) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x40) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x40) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x40) p_dig_6 = 1;
            break;
        case 8:
            p_seg_h = 0;
            // if(r_dis_data[0] & 0x80) p_dig_1 = 1;
            // if(r_dis_data[1] & 0x80) p_dig_2 = 1;
            // if(r_dis_data[2] & 0x80) p_dig_3 = 1;
            // if(r_dis_data[3] & 0x80) p_dig_4 = 1;
            // if(r_dis_buff[4] & 0x80) p_dig_5 = 1;
            // if(r_dis_buff[5] & 0x80) p_dig_6 = 1;
            break;
                       
                       
                       
                       
        default:
            keyscan_process();      //按键扫描
            break;
    }
        if((r_dig_bit<9)&&(r_dig_bit))
        {
       
                i=0x01<<(r_dig_bit-1);
            if(r_dis_data[0] & i) p_dig_1 = 1;
             if(r_dis_data[1] & i) p_dig_2 = 1;
             if(r_dis_data[2] & i) p_dig_3 = 1;
             if(r_dis_data[3] & i) p_dig_4 = 1;
             if(r_dis_buff[4] & i) p_dig_5 = 1;
             if(r_dis_buff[5] & i) p_dig_6 = 1;               
               
                       
        }
       
       
    r_dig_bit ++;
    if(r_dig_bit >= 9)    //扫描时基
    r_dig_bit = 0;
}

出0入0汤圆

发表于 2014-8-25 22:05:15 | 显示全部楼层
楼上代码看的脑袋歪了, 重新给你编辑一下
  1. void display_scan(void)
  2. {
  3.     unsigned char i;
  4.     P1 &= Bin(11111110);
  5.     P1 |= Bin(11111000);
  6.     P2 &= Bin(00000000);
  7.     P3 &= Bin(01100111);
  8.     P3 |= Bin(01100110);  //关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
  9. //======================================//
  10.     for(i = 0;i < 4;i ++)
  11.     {
  12.         r_dis_data = table_seg[r_dis_buff];    //查LED段码表
  13.     }
  14.     switch (r_dig_bit)                                      //在公共端接限流电阻,在数码管位数少时布线时有优势
  15.     {
  16.         case 1:
  17.             p_seg_a = 0;   //扫描a段
  18.             // if(r_dis_data[0] & 0x01) p_dig_1 = 1;  //如果r_dis_data[0]第0位为高,则需要点亮,反之则不点亮
  19.             // if(r_dis_data[1] & 0x01) p_dig_2 = 1;
  20.             // if(r_dis_data[2] & 0x01) p_dig_3 = 1;
  21.             // if(r_dis_data[3] & 0x01) p_dig_4 = 1;
  22.             // if(r_dis_buff[4] & 0x01) p_dig_5 = 1;
  23.             // if(r_dis_buff[5] & 0x01) p_dig_6 = 1;
  24.                         //i=0x01;
  25.                         
  26.             break;
  27.         case 2:
  28.             p_seg_b = 0;
  29.             // if(r_dis_data[0] & 0x02) p_dig_1 = 1;
  30.             // if(r_dis_data[1] & 0x02) p_dig_2 = 1;
  31.             // if(r_dis_data[2] & 0x02) p_dig_3 = 1;
  32.             // if(r_dis_data[3] & 0x02) p_dig_4 = 1;
  33.             // if(r_dis_buff[4] & 0x02) p_dig_5 = 1;
  34.             // if(r_dis_buff[5] & 0x02) p_dig_6 = 1;
  35.                                 //i=0x02;
  36.             break;
  37.         case 3:
  38.             p_seg_c = 0;
  39.             // if(r_dis_data[0] & 0x04) p_dig_1 = 1;
  40.             // if(r_dis_data[1] & 0x04) p_dig_2 = 1;
  41.             // if(r_dis_data[2] & 0x04) p_dig_3 = 1;
  42.             // if(r_dis_data[3] & 0x04) p_dig_4 = 1;
  43.             // if(r_dis_buff[4] & 0x04) p_dig_5 = 1;
  44.             // if(r_dis_buff[5] & 0x04) p_dig_6 = 1;
  45.             break;
  46.         case 4:
  47.              p_seg_d = 0;
  48.             // if(r_dis_data[0] & 0x08) p_dig_1 = 1;
  49.             // if(r_dis_data[1] & 0x08) p_dig_2 = 1;
  50.             // if(r_dis_data[2] & 0x08) p_dig_3 = 1;
  51.             // if(r_dis_data[3] & 0x08) p_dig_4 = 1;
  52.             // if(r_dis_buff[4] & 0x08) p_dig_5 = 1;
  53.             // if(r_dis_buff[5] & 0x08) p_dig_6 = 1;
  54.             break;
  55.         case 5:     
  56.             p_seg_e = 0;
  57.             // if(r_dis_data[0] & 0x10) p_dig_1 = 1;
  58.             // if(r_dis_data[1] & 0x10) p_dig_2 = 1;
  59.             // if(r_dis_data[2] & 0x10) p_dig_3 = 1;
  60.             // if(r_dis_data[3] & 0x10) p_dig_4 = 1;
  61.             // if(r_dis_buff[4] & 0x10) p_dig_5 = 1;
  62.             // if(r_dis_buff[5] & 0x10) p_dig_6 = 1;
  63.             break;
  64.         case 6:
  65.             p_seg_f = 0;
  66.             // if(r_dis_data[0] & 0x20) p_dig_1 = 1;
  67.             // if(r_dis_data[1] & 0x20) p_dig_2 = 1;
  68.             // if(r_dis_data[2] & 0x20) p_dig_3 = 1;
  69.             // if(r_dis_data[3] & 0x20) p_dig_4 = 1;
  70.             // if(r_dis_buff[4] & 0x20) p_dig_5 = 1;
  71.             // if(r_dis_buff[5] & 0x20) p_dig_6 = 1;
  72.             break;
  73.         case 7:
  74.             p_seg_g = 0;
  75.             // if(r_dis_data[0] & 0x40) p_dig_1 = 1;
  76.             // if(r_dis_data[1] & 0x40) p_dig_2 = 1;
  77.             // if(r_dis_data[2] & 0x40) p_dig_3 = 1;
  78.             // if(r_dis_data[3] & 0x40) p_dig_4 = 1;
  79.             // if(r_dis_buff[4] & 0x40) p_dig_5 = 1;
  80.             // if(r_dis_buff[5] & 0x40) p_dig_6 = 1;
  81.             break;
  82.         case 8:
  83.             p_seg_h = 0;
  84.             // if(r_dis_data[0] & 0x80) p_dig_1 = 1;
  85.             // if(r_dis_data[1] & 0x80) p_dig_2 = 1;
  86.             // if(r_dis_data[2] & 0x80) p_dig_3 = 1;
  87.             // if(r_dis_data[3] & 0x80) p_dig_4 = 1;
  88.             // if(r_dis_buff[4] & 0x80) p_dig_5 = 1;
  89.             // if(r_dis_buff[5] & 0x80) p_dig_6 = 1;
  90.             break;
  91.                         
  92.                         
  93.                         
  94.                         
  95.         default:
  96.             keyscan_process();      //按键扫描
  97.             break;
  98.     }
  99.         if((r_dig_bit<9)&&(r_dig_bit))
  100.         {
  101.         
  102.                 i=0x01<<(r_dig_bit-1);
  103.             if(r_dis_data[0] & i) p_dig_1 = 1;
  104.              if(r_dis_data[1] & i) p_dig_2 = 1;
  105.              if(r_dis_data[2] & i) p_dig_3 = 1;
  106.              if(r_dis_data[3] & i) p_dig_4 = 1;
  107.              if(r_dis_buff[4] & i) p_dig_5 = 1;
  108.              if(r_dis_buff[5] & i) p_dig_6 = 1;               
  109.                
  110.                         
  111.         }
  112.         
  113.         
  114.     r_dig_bit ++;
  115.     if(r_dig_bit >= 9)    //扫描时基
  116.     r_dig_bit = 0;
  117. }
复制代码

出0入0汤圆

发表于 2014-8-25 23:50:55 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2014-10-4 16:20:57 | 显示全部楼层
我来学习

出0入0汤圆

发表于 2014-10-4 22:59:02 | 显示全部楼层
放定时器中断里面,代码量最小,且效果最好。

出0入0汤圆

发表于 2014-10-4 23:20:52 | 显示全部楼层
学习各位大侠的方法。

出0入0汤圆

发表于 2014-10-5 00:07:02 | 显示全部楼层
这个好,收藏了

出0入0汤圆

发表于 2014-10-5 11:58:05 | 显示全部楼层
本帖最后由 zhan_li 于 2014-10-5 11:59 编辑

我也发一段我的不用锁存器单片机直接驱动数码管的显示程序,用定时器延迟,时间大概2MS。且是按键和数码管共用I/O的。学名为数码管和按键分时复用程序,希望对大家有帮助。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-10-5 12:02:18 | 显示全部楼层
mark, 支持一下

出0入0汤圆

发表于 2015-2-6 23:26:27 来自手机 | 显示全部楼层
最近项目正用上了。

出0入0汤圆

发表于 2015-8-2 23:29:10 | 显示全部楼层
mark下,到公司研究研究能不能改进下我的方法

出0入0汤圆

发表于 2017-3-13 18:35:44 | 显示全部楼层
正好用的,好好学习一下。数码管和按键公用 IO

出0入0汤圆

发表于 2017-3-13 20:27:29 | 显示全部楼层
kebaojun305 发表于 2014-5-31 12:15
专用的芯片贵啊。

专用芯片很贵吗?我用的aip1628才四毛多,10 段×7 位或13段×4 位,按键10×2 ,除非单片机IO口直接驱动数码管,否则真没有比用专用芯片更省钱的方案了。

出0入53汤圆

发表于 2020-3-16 16:24:51 | 显示全部楼层
LM1876 发表于 2014-5-11 12:21
void LEDsFlash_Update()
{
   static uchar data loop;

这个代码 显示有闪烁感吗?

出0入0汤圆

发表于 2020-3-17 08:37:25 | 显示全部楼层
zhcj66 发表于 2020-3-16 16:24
这个代码 显示有闪烁感吗?

这要看主程序结构,我用的是分时中断系统,放在1mS里。5位以内(含5位)就没闪烁感,5位以上就有

出0入53汤圆

发表于 2020-3-17 09:26:05 | 显示全部楼层
LM1876 发表于 2020-3-17 08:37
这要看主程序结构,我用的是分时中断系统,放在1mS里。5位以内(含5位)就没闪烁感,5位以上就有 ...

他们搞的10几个不闪烁不知道用mcu怎么实现的?

出0入0汤圆

发表于 2020-3-17 09:55:11 | 显示全部楼层
zhcj66 发表于 2020-3-17 09:26
他们搞的10几个不闪烁不知道用mcu怎么实现的?

10来段的得用专用芯片了吧?不然光靠单片机的话,占太多资源了

出0入53汤圆

发表于 2020-3-17 11:12:32 | 显示全部楼层
LM1876 发表于 2020-3-17 09:55
10来段的得用专用芯片了吧?不然光靠单片机的话,占太多资源了

他们广告屏不都是用的164芯片做出来,没有用专用芯片

出0入0汤圆

发表于 2020-4-13 20:18:41 | 显示全部楼层
学习学习,谢谢提供

出0入0汤圆

发表于 2020-4-13 23:12:05 来自手机 | 显示全部楼层
学习,参考
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-20 18:13

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

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