lmt50211 发表于 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 = table_seg];    //查LED段码表
    }
    switch (r_dig_bit)                                    //在公共端接限流电阻,在数码管位数少时布线时有优势
    {
      case 1:
            p_seg_a = 0;                                    //扫描a段
            if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
            if(r_dis_data & 0x01) p_dig_2 = 1;
            if(r_dis_data & 0x01) p_dig_3 = 1;
            if(r_dis_data & 0x01) p_dig_4 = 1;
            if(r_dis_buff & 0x01) p_dig_5 = 1;
            if(r_dis_buff & 0x01) p_dig_6 = 1;
            break;
      case 2:
            p_seg_b = 0;
            if(r_dis_data & 0x02) p_dig_1 = 1;
            if(r_dis_data & 0x02) p_dig_2 = 1;
            if(r_dis_data & 0x02) p_dig_3 = 1;
            if(r_dis_data & 0x02) p_dig_4 = 1;
            if(r_dis_buff & 0x02) p_dig_5 = 1;
            if(r_dis_buff & 0x02) p_dig_6 = 1;
            break;
      case 3:
            p_seg_c = 0;
            if(r_dis_data & 0x04) p_dig_1 = 1;
            if(r_dis_data & 0x04) p_dig_2 = 1;
            if(r_dis_data & 0x04) p_dig_3 = 1;
            if(r_dis_data & 0x04) p_dig_4 = 1;
            if(r_dis_buff & 0x04) p_dig_5 = 1;
            if(r_dis_buff & 0x04) p_dig_6 = 1;
            break;
      case 4:
            p_seg_d = 0;
            if(r_dis_data & 0x08) p_dig_1 = 1;
            if(r_dis_data & 0x08) p_dig_2 = 1;
            if(r_dis_data & 0x08) p_dig_3 = 1;
            if(r_dis_data & 0x08) p_dig_4 = 1;
            if(r_dis_buff & 0x08) p_dig_5 = 1;
            if(r_dis_buff & 0x08) p_dig_6 = 1;
            break;
      case 5:   
            p_seg_e = 0;
            if(r_dis_data & 0x10) p_dig_1 = 1;
            if(r_dis_data & 0x10) p_dig_2 = 1;
            if(r_dis_data & 0x10) p_dig_3 = 1;
            if(r_dis_data & 0x10) p_dig_4 = 1;
            if(r_dis_buff & 0x10) p_dig_5 = 1;
            if(r_dis_buff & 0x10) p_dig_6 = 1;
            break;
      case 6:
            p_seg_f = 0;
            if(r_dis_data & 0x20) p_dig_1 = 1;
            if(r_dis_data & 0x20) p_dig_2 = 1;
            if(r_dis_data & 0x20) p_dig_3 = 1;
            if(r_dis_data & 0x20) p_dig_4 = 1;
            if(r_dis_buff & 0x20) p_dig_5 = 1;
            if(r_dis_buff & 0x20) p_dig_6 = 1;
            break;
      case 7:
            p_seg_g = 0;
            if(r_dis_data & 0x40) p_dig_1 = 1;
            if(r_dis_data & 0x40) p_dig_2 = 1;
            if(r_dis_data & 0x40) p_dig_3 = 1;
            if(r_dis_data & 0x40) p_dig_4 = 1;
            if(r_dis_buff & 0x40) p_dig_5 = 1;
            if(r_dis_buff & 0x40) p_dig_6 = 1;
            break;
      case 8:
            p_seg_h = 0;
            if(r_dis_data & 0x80) p_dig_1 = 1;
            if(r_dis_data & 0x80) p_dig_2 = 1;
            if(r_dis_data & 0x80) p_dig_3 = 1;
            if(r_dis_data & 0x80) p_dig_4 = 1;
            if(r_dis_buff & 0x80) p_dig_5 = 1;
            if(r_dis_buff & 0x80) p_dig_6 = 1;
            break;
      default:
            keyscan_process();      //按键扫描
            break;
    }
    r_dig_bit ++;
    if(r_dig_bit >= 9)    //扫描时基
    r_dig_bit = 0;
}

lcw_swust 发表于 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 & (1<<r_dig_bit)) p_dig_1 = 1;
if(r_dis_data & (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;//置高某些位
P1&=table_p1clr;//置低某些位

yilin411 发表于 2014-4-14 13:00:22

本帖最后由 yilin411 于 2014-4-14 13:05 编辑

/*****************************************************************************
显示表格
*****************************************************************************/
const u8 LedDisplay_B = {0x1b,0x08,0x1d,0x1c,0x0e,0x16,0x17,0x18,0x1f,0x1e};
const u8 LedDisplay_C = {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;                
                _pc |= LedDisplay_C;        
        }        
        else if(1 == R_Display_cnt)        
        {                
                Dispaly_Off();                
                _pb |= LedDisplay_B;                
                _pc |= LedDisplay_C;       
        }
       
        R_Display_cnt++;        
        if(R_Display_cnt >= 2)        
        {                
                R_Display_cnt = 0;        
        }
}

laujc 发表于 2014-4-14 13:32:14

yilin411 发表于 2014-4-14 13:00
/*****************************************************************************
显示表格
********* ...

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

lyhfdz 发表于 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;// 百位
       
                                if(Disp_N1)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_1 = Duan_Liang;
                        }
                        break;
                case        2:
                        //显示 第 2 个 8 字
                        if(Dis2 == Duan_Liang)
                        {
                                P2 = Display_Buf;// 十位
                                if(Disp_N2)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_2 = Duan_Liang;
                        }
                        break;
                case        3:
                        //显示 第 3 个 8 字
                        if(Dis3 == Duan_Liang)
                        {
                                P2 = Display_Buf;// 个位
                                if(Disp_N3)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_3 = Duan_Liang;
                        }
                //        Disp_Num = 0;
                        break;
                case        4:
                        //显示 第 1 个 8 字
                        if(Dis4 == Duan_Liang)
                        {
                                P2 = Display_Buf;// 百位
       
                                if(Disp_N4)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_4 = Duan_Liang;
                        }
                        break;
                case        5:
                        //显示 第 2 个 8 字
                        if(Dis5 == Duan_Liang)
                        {
                                P2 = Display_Buf;// 十位
                                if(Disp_N5)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_5 = Duan_Liang;
                        }
                        break;
                case        6:
                        //显示 第 3 个 8 字
                        if(Dis6 == Duan_Liang)
                        {
                                P2 = Display_Buf;// 个位
                                if(Disp_N6)//如果 Disp_N1 为 1,表示显示小数点
                                {
                                        P2 = P2 ^ Number;
                                }
                                Disp_6 = Duan_Liang;
                        }
                        Disp_Num = 0;
                        break;
        }
}

lqs123 发表于 2014-4-14 20:42:57

{:smile:}{:smile:}长见识

lmt50211 发表于 2014-4-16 09:06:12

yilin411 发表于 2014-4-14 13:00
/*****************************************************************************
显示表格
********* ...

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

lmt50211 发表于 2014-4-16 09:07:50

lcw_swust 发表于 2014-4-14 09:22
switch (r_dig_bit)
{
      case 0:


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

lmt50211 发表于 2014-4-16 09:09:55

lyhfdz 发表于 2014-4-14 20:25
1位 6段,大侠给瞅瞅。
/*********** 显示子程序 *************/
void        Disp()//显示


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

yilin411 发表于 2014-4-16 09:13:08

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

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

cmheia 发表于 2014-4-16 09:33:40

{:lol:}用3维数组做段码液晶表的路过(这是我第一次接触段码液晶)

lmt50211 发表于 2014-4-16 09:40:19

以前有做个二维的

lmt50211 发表于 2014-4-16 09:42:50

cmheia 发表于 2014-4-16 09:33
用3维数组做段码液晶表的路过(这是我第一次接触段码液晶)

以前有做个二维的

surken 发表于 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;
    }
}

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

机器人天空 发表于 2014-4-16 13:06:45

学习一下{:lol:}

pygh 发表于 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.2HZ8段 每段 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次
}

pygh 发表于 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;
         }
        }

LM1876 发表于 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];
         LED1_pin = LED_LIGHT;
         break;
       case 1:
         P0 = LEDs_display];
         LED2_pin = LED_LIGHT;
         break;
       case 2:
         P0 = LEDs_display];
         LED3_pin = LED_LIGHT;
         break;
       case 3:
         P0 = LEDs_display];
         LED4_pin = LED_LIGHT;
         break;
       case 4:
         P0 = LEDs_display];
         LED5_pin = LED_LIGHT;
         break;
   }
}

xiaoguo_nihao 发表于 2014-5-12 14:18:27

好多代码啊,慢慢看,学习学习

jacky_yhy 发表于 2014-5-12 14:35:43

直接上专用片子就行。

lmt50211 发表于 2014-5-13 08:27:34

jacky_yhy 发表于 2014-5-12 14:35
直接上专用片子就行。

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

lmt50211 发表于 2014-5-13 08:28:15

xiaoguo_nihao 发表于 2014-5-12 14:18
好多代码啊,慢慢看,学习学习

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

iwqt1983 发表于 2014-5-31 11:09:40

为用专用的芯片省事.

kebaojun305 发表于 2014-5-31 12:15:43

iwqt1983 发表于 2014-5-31 11:09
为用专用的芯片省事.

专用的芯片贵啊。

三国小兵 发表于 2014-6-11 16:08:50

看看代码学习一下。。。。。。。。。。

dz20062008 发表于 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
          CLRLED_DUAN
          MOV LED_DATA,#0FFH
          SETB LED_WEI
          CLRLED_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

gotofly100 发表于 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];    //查LED段码表
    }
    switch (r_dig_bit)                                    //在公共端接限流电阻,在数码管位数少时布线时有优势
    {
      case 1:
            p_seg_a = 0;   //扫描a段
            // if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
            // if(r_dis_data & 0x01) p_dig_2 = 1;
            // if(r_dis_data & 0x01) p_dig_3 = 1;
            // if(r_dis_data & 0x01) p_dig_4 = 1;
            // if(r_dis_buff & 0x01) p_dig_5 = 1;
            // if(r_dis_buff & 0x01) p_dig_6 = 1;
                        //i=0x01;
                       
            break;
      case 2:
            p_seg_b = 0;
            // if(r_dis_data & 0x02) p_dig_1 = 1;
            // if(r_dis_data & 0x02) p_dig_2 = 1;
            // if(r_dis_data & 0x02) p_dig_3 = 1;
            // if(r_dis_data & 0x02) p_dig_4 = 1;
            // if(r_dis_buff & 0x02) p_dig_5 = 1;
            // if(r_dis_buff & 0x02) p_dig_6 = 1;
                                //i=0x02;
            break;
      case 3:
            p_seg_c = 0;
            // if(r_dis_data & 0x04) p_dig_1 = 1;
            // if(r_dis_data & 0x04) p_dig_2 = 1;
            // if(r_dis_data & 0x04) p_dig_3 = 1;
            // if(r_dis_data & 0x04) p_dig_4 = 1;
            // if(r_dis_buff & 0x04) p_dig_5 = 1;
            // if(r_dis_buff & 0x04) p_dig_6 = 1;
            break;
      case 4:
             p_seg_d = 0;
            // if(r_dis_data & 0x08) p_dig_1 = 1;
            // if(r_dis_data & 0x08) p_dig_2 = 1;
            // if(r_dis_data & 0x08) p_dig_3 = 1;
            // if(r_dis_data & 0x08) p_dig_4 = 1;
            // if(r_dis_buff & 0x08) p_dig_5 = 1;
            // if(r_dis_buff & 0x08) p_dig_6 = 1;
            break;
      case 5:   
            p_seg_e = 0;
            // if(r_dis_data & 0x10) p_dig_1 = 1;
            // if(r_dis_data & 0x10) p_dig_2 = 1;
            // if(r_dis_data & 0x10) p_dig_3 = 1;
            // if(r_dis_data & 0x10) p_dig_4 = 1;
            // if(r_dis_buff & 0x10) p_dig_5 = 1;
            // if(r_dis_buff & 0x10) p_dig_6 = 1;
            break;
      case 6:
            p_seg_f = 0;
            // if(r_dis_data & 0x20) p_dig_1 = 1;
            // if(r_dis_data & 0x20) p_dig_2 = 1;
            // if(r_dis_data & 0x20) p_dig_3 = 1;
            // if(r_dis_data & 0x20) p_dig_4 = 1;
            // if(r_dis_buff & 0x20) p_dig_5 = 1;
            // if(r_dis_buff & 0x20) p_dig_6 = 1;
            break;
      case 7:
            p_seg_g = 0;
            // if(r_dis_data & 0x40) p_dig_1 = 1;
            // if(r_dis_data & 0x40) p_dig_2 = 1;
            // if(r_dis_data & 0x40) p_dig_3 = 1;
            // if(r_dis_data & 0x40) p_dig_4 = 1;
            // if(r_dis_buff & 0x40) p_dig_5 = 1;
            // if(r_dis_buff & 0x40) p_dig_6 = 1;
            break;
      case 8:
            p_seg_h = 0;
            // if(r_dis_data & 0x80) p_dig_1 = 1;
            // if(r_dis_data & 0x80) p_dig_2 = 1;
            // if(r_dis_data & 0x80) p_dig_3 = 1;
            // if(r_dis_data & 0x80) p_dig_4 = 1;
            // if(r_dis_buff & 0x80) p_dig_5 = 1;
            // if(r_dis_buff & 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 & i) p_dig_1 = 1;
             if(r_dis_data & i) p_dig_2 = 1;
             if(r_dis_data & i) p_dig_3 = 1;
             if(r_dis_data & i) p_dig_4 = 1;
             if(r_dis_buff & i) p_dig_5 = 1;
             if(r_dis_buff & i) p_dig_6 = 1;               
               
                       
        }
       
       
    r_dig_bit ++;
    if(r_dig_bit >= 9)    //扫描时基
    r_dig_bit = 0;
}

jzhwang 发表于 2014-8-25 22:05:15

楼上代码看的脑袋歪了, 重新给你编辑一下
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;    //查LED段码表
    }
    switch (r_dig_bit)                                    //在公共端接限流电阻,在数码管位数少时布线时有优势
    {
      case 1:
            p_seg_a = 0;   //扫描a段
            // if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
            // if(r_dis_data & 0x01) p_dig_2 = 1;
            // if(r_dis_data & 0x01) p_dig_3 = 1;
            // if(r_dis_data & 0x01) p_dig_4 = 1;
            // if(r_dis_buff & 0x01) p_dig_5 = 1;
            // if(r_dis_buff & 0x01) p_dig_6 = 1;
                        //i=0x01;
                        
            break;
      case 2:
            p_seg_b = 0;
            // if(r_dis_data & 0x02) p_dig_1 = 1;
            // if(r_dis_data & 0x02) p_dig_2 = 1;
            // if(r_dis_data & 0x02) p_dig_3 = 1;
            // if(r_dis_data & 0x02) p_dig_4 = 1;
            // if(r_dis_buff & 0x02) p_dig_5 = 1;
            // if(r_dis_buff & 0x02) p_dig_6 = 1;
                              //i=0x02;
            break;
      case 3:
            p_seg_c = 0;
            // if(r_dis_data & 0x04) p_dig_1 = 1;
            // if(r_dis_data & 0x04) p_dig_2 = 1;
            // if(r_dis_data & 0x04) p_dig_3 = 1;
            // if(r_dis_data & 0x04) p_dig_4 = 1;
            // if(r_dis_buff & 0x04) p_dig_5 = 1;
            // if(r_dis_buff & 0x04) p_dig_6 = 1;
            break;
      case 4:
             p_seg_d = 0;
            // if(r_dis_data & 0x08) p_dig_1 = 1;
            // if(r_dis_data & 0x08) p_dig_2 = 1;
            // if(r_dis_data & 0x08) p_dig_3 = 1;
            // if(r_dis_data & 0x08) p_dig_4 = 1;
            // if(r_dis_buff & 0x08) p_dig_5 = 1;
            // if(r_dis_buff & 0x08) p_dig_6 = 1;
            break;
      case 5:   
            p_seg_e = 0;
            // if(r_dis_data & 0x10) p_dig_1 = 1;
            // if(r_dis_data & 0x10) p_dig_2 = 1;
            // if(r_dis_data & 0x10) p_dig_3 = 1;
            // if(r_dis_data & 0x10) p_dig_4 = 1;
            // if(r_dis_buff & 0x10) p_dig_5 = 1;
            // if(r_dis_buff & 0x10) p_dig_6 = 1;
            break;
      case 6:
            p_seg_f = 0;
            // if(r_dis_data & 0x20) p_dig_1 = 1;
            // if(r_dis_data & 0x20) p_dig_2 = 1;
            // if(r_dis_data & 0x20) p_dig_3 = 1;
            // if(r_dis_data & 0x20) p_dig_4 = 1;
            // if(r_dis_buff & 0x20) p_dig_5 = 1;
            // if(r_dis_buff & 0x20) p_dig_6 = 1;
            break;
      case 7:
            p_seg_g = 0;
            // if(r_dis_data & 0x40) p_dig_1 = 1;
            // if(r_dis_data & 0x40) p_dig_2 = 1;
            // if(r_dis_data & 0x40) p_dig_3 = 1;
            // if(r_dis_data & 0x40) p_dig_4 = 1;
            // if(r_dis_buff & 0x40) p_dig_5 = 1;
            // if(r_dis_buff & 0x40) p_dig_6 = 1;
            break;
      case 8:
            p_seg_h = 0;
            // if(r_dis_data & 0x80) p_dig_1 = 1;
            // if(r_dis_data & 0x80) p_dig_2 = 1;
            // if(r_dis_data & 0x80) p_dig_3 = 1;
            // if(r_dis_data & 0x80) p_dig_4 = 1;
            // if(r_dis_buff & 0x80) p_dig_5 = 1;
            // if(r_dis_buff & 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 & i) p_dig_1 = 1;
             if(r_dis_data & i) p_dig_2 = 1;
             if(r_dis_data & i) p_dig_3 = 1;
             if(r_dis_data & i) p_dig_4 = 1;
             if(r_dis_buff & i) p_dig_5 = 1;
             if(r_dis_buff & i) p_dig_6 = 1;               
               
                        
      }
      
      
    r_dig_bit ++;
    if(r_dig_bit >= 9)    //扫描时基
    r_dig_bit = 0;
}

你是否还记的 发表于 2014-8-25 23:50:55

学习学习

zrdzpcb 发表于 2014-10-4 16:20:57

我来学习

sensitiveplant 发表于 2014-10-4 22:59:02

放定时器中断里面,代码量最小,且效果最好。

witlong 发表于 2014-10-4 23:20:52

学习各位大侠的方法。

nongsan 发表于 2014-10-5 00:07:02

这个好,收藏了

zhan_li 发表于 2014-10-5 11:58:05

本帖最后由 zhan_li 于 2014-10-5 11:59 编辑

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

dsp56789 发表于 2014-10-5 12:02:18

mark, 支持一下

lovecxm 发表于 2015-2-6 23:26:27

最近项目正用上了。

higeo 发表于 2015-8-2 23:29:10

mark下,到公司研究研究能不能改进下我的方法

52HLX 发表于 2017-3-13 18:35:44

正好用的,好好学习一下。数码管和按键公用 IO

dxdqdxdq 发表于 2017-3-13 20:27:29

kebaojun305 发表于 2014-5-31 12:15
专用的芯片贵啊。

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

zhcj66 发表于 2020-3-16 16:24:51

LM1876 发表于 2014-5-11 12:21
void LEDsFlash_Update()
{
   static uchar data loop;


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

LM1876 发表于 2020-3-17 08:37:25

zhcj66 发表于 2020-3-16 16:24
这个代码 显示有闪烁感吗?

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

zhcj66 发表于 2020-3-17 09:26:05

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

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

LM1876 发表于 2020-3-17 09:55:11

zhcj66 发表于 2020-3-17 09:26
他们搞的10几个不闪烁不知道用mcu怎么实现的?

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

zhcj66 发表于 2020-3-17 11:12:32

LM1876 发表于 2020-3-17 09:55
10来段的得用专用芯片了吧?不然光靠单片机的话,占太多资源了

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

lijianxing 发表于 2020-4-13 20:18:41

学习学习,谢谢提供

waymcu 发表于 2020-4-13 23:12:05

学习,参考
页: [1]
查看完整版本: 段式数码管扫描程序如何减少代码量(采用扫描段码方式)