【解析新特性】300W单路输出工业电源>>
电子产品世界 » 论坛首页 » 综合技术 » 电源与模拟 » 51单片机进行​LED数码管扫描,程序如何减少代码量?

共5条 1/1 1 跳转至

51单片机进行​LED数码管扫描,程序如何减少代码量?

助工
2020-03-16 17:12:21    评分
最近弄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;
}

    电路图如下:

    LED数码管驱动控制电路.pdf




    关键词: 数码管     LED     扫描     程序     驱动    

    助工
    2020-03-16 17:27:29    评分
    2楼

    楼主改进这样如何?

    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];//置低某些位


    助工
    2020-03-16 17:31:19    评分
    3楼


    /*****************************************************************************  
    显示表格 
    *****************************************************************************/ 
    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;         
            } 
    }


    助工
    2020-03-16 17:36:48    评分
    4楼

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


    助工
    2020-03-16 21:54:52    评分
    5楼

    感谢大家的分享


    共5条 1/1 1 跳转至

    回复

    匿名不能发帖!请先 [ 登陆 注册 ]