找回密码
 立即注册
搜索
热搜: 中医 针灸 咳嗽
查看: 187|回复: 0

数码管字符串,双精度,长整型共用体解决方案

[复制链接]

3711

主题

1

回帖

1万

积分

管理员

积分
11937
发表于 2023-1-26 00:51:57 | 显示全部楼层 |阅读模式
/*
数码管字符串,双精度,长整型显示
利用共用体指针解决方案


*/
#include <REG52.H>
#include <stdio.h>
#include <string.h>

#define Uchar unsigned char
#define Uint  unsigned int
#define Ulong unsigned long

// 引脚定义区域
sbit DU       = P2 ^ 6; // 数码管段选
sbit WE       = P2 ^ 7; // 数码管位选
int IS_double = 999;

int Get_val(union DIS_VAL *val, int type);
void Dis_scan();
void DIS_play(int result, int type);
void delay(Uchar z, int mod);
void Chars_convert(union DIS_VAL *chars_ptr);
void Ulong_convert(Ulong Z);
int Double_convert(double Z);

int val_arr[] = {24, 24, 24, 24, 24, 24, 24, 24}; // 24 在表码表中定义熄灭
// 用共用体作为万能数据类型,兼容多种场景
union DIS_VAL {
    /*无符号长整型*/
    unsigned long ULONG_data;
    /*浮点型*/
    float Float_data;
    /*双精度*/
    double Double_data;
    /*字符串*/
    char *Chars_data;
};

// 段码表
Uchar code DUtabel[] = {
    0x3F, //"0"
    0x06, //"1"
    0x5B, //"2"
    0x4F, //"3"
    0x66, //"4"
    0x6D, //"5"
    0x7D, //"6"
    0x07, //"7"
    0x7F, //"8"
    0x6F, //"9"
    0x77, //"A"
    0x7C, //"B"
    0x39, //"C"
    0x5E, //"D"
    0x79, //"E"
    0x71, //"F"
    0x76, //"H"
    0x38, //"L"
    0x6d, // S
    0x6d, // S
    0x37, //"n"
    0x3E, //"u"
    0x73, //"P"
    0x63, //"o"
    0x00, // 熄灭
    0x01, // 上 -
    0x40, // 中 -
    0x08, // 下 -

};

// 位码表
Uchar code WEtabel[] = {
    0xFE, // 1
    0xFD, // 2
    0xfb, // 3
    0xf7, // 4
    0xef, // 5
    0xdf, // 6
    0xbf, // 7
    0x7f, // 8
};

// 合法字符表
Uchar code Enable_tabel[] = {
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'h',
    'l',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'H',
    'L',
    'S',
    's',
    'n',
    'N',
    'u',
    'U',
    'P',
    'p',
    'O',
    'o',
    '-',
    '_',

};

int main()
{
    union DIS_VAL val;

    // //字符串显示处理方案
    // val.Chars_data = "05-09";
    // if(Get_val(&val, 4)==1){//如果传入的数据合法

    // //长整形处理方案
    // val.ULONG_data = 23311;

    // if(Get_val(&val, 1)==1){//如果传入的数据合法

        //     // 双精度处理方案
    // val.Double_data = 88888888.55;

    // if (Get_val(&val, 3) == 1) { // 如果传入的数据合法

    // 双精度处理方案
    val.Double_data = 88888888.55;

    if (Get_val(&val, 3) == 1) { // 如果传入的数据合法

        while (1)

        {
            Dis_scan();
        }
    } else {
        // 显示错误代码 001 传入字符串有误
        val.Chars_data = "no000001";
        Chars_convert(&val);
        while (1) {
            Dis_scan();
        }
    }
}

// void display(Z)
// {
//     // Z长度
//     int Zlen = 0;
//     /*存储Z每个位的数字数组变量*/
//     int val[8];
//     int i;

//     while (Z != 0) {
//         // 提取n的各个数位上的数
//         val[Zlen++] = Z % 10;
//         Z /= 10;
//     }
// }
/*

这个一个万能变量的处理函数
/////////////////////////////////////////
参数1:union 指针
参数2:tpye  处理类型
返回值说明:0 传入数据有误,进程终止 1:处理成功
/////////////////////////////////////////
1:无符号长整型
2:浮点型
3:双精度
4.字符串
*/
int Get_val(union DIS_VAL *val, int type)
{

    char *charP       = val->Chars_data;
    Ulong *ulongP     = val->ULONG_data;
    double Double_val = val->Double_data;
    int count;
    int find_char;
    int i = 0;

    switch (type) {
        case 1: // 无符号长整型
            if (val->ULONG_data < 0 || val->ULONG_data > 99999999) {
                return 0;
            }

            Ulong_convert(ulongP);
            break;

        case 2: // 浮点型
            // printf("%f", val->Float_data);
            if (val->Float_data < 0 || val->Float_data > 99999999) {
                return 0;
            }

            break;
        case 3: // 双精度

            if (val->Double_data < 0 || val->Double_data > 99999999) {
                return 0;
            }
            IS_double = Double_convert(Double_val);

            break;
        case 4: // 字符串
            // printf("%s", val->Chars_data);

            count     = 0;
            find_char = 1; // 和编码表比对字符串 1表示找到了  0代表找不到
            Chars_convert(val);
            // 传入的字符串合法性检测 如果中途返回0 则表示 传入的数据有误
            while (charP[count] != '\0') {
                int count_char = count;
                count++;
                for (i = 0; i < sizeof(Enable_tabel) / sizeof(Uchar); i++) {
                    if (Enable_tabel[i] == charP[count_char]) {

                        find_char = 1;
                        // continue;
                        break;
                    } else {

                        find_char = 0;
                    }
                }

                if (find_char == 0 || count >= 9) {
                    return 0;
                } else {
                    continue;
                }
            }

            break;

        default:
            break;
    }

    return 1;
}

/*数码管扫描显示
参数1:传入显示数据的指针首地址;
*/
void Dis_scan()
{
    int i;

    for (i = 0; i < 8; i++) {

        DIS_play(val_arr[i], i);
    }
}
/*单位数码管显示
参数1:显示的结果     详情查询段位表DUtabel[]
参数2:显示在哪一位上 0-7
*/
void DIS_play(int result, int WE_int)
{
    P0 = 0XFF;            // 清除断码
    WE = 1;               // 打开位选锁存器
    P0 = WEtabel[WE_int]; // 1111 1110 选通第WE_int位数码管
    WE = 0;               // 锁存位选数据

    DU = 1;               // 打开段选锁存器
    P0 = DUtabel[result]; // 推送数据

        /*判断小数点,加小数点*/
    if (IS_double != 999 && IS_double == WE_int) {
        P0 = DUtabel[result];
        P0 |= 0x80;

    } else {
        P0 = DUtabel[result];
    }
    DU = 0; // 锁存段选数据
    delay(2, 1);
}
/*
延迟函数.晶振:11.0592
参数1:z为数量
参数2:mod为模式
1:毫秒
2:秒
*/
void delay(Uchar z, int mod)
{
    Uint i;

    if (mod == 1) {
        for (i = 0; i < z; i++) {

            unsigned char a, b;
            for (b = 102; b > 0; b--)
                for (a = 3; a > 0; a--)
                    ;
        }
    }

    else if (mod == 2) {
        for (i = 0; i < z * 1000; i++) {
            // 10000us //误差 -0.000000000002us
            unsigned char a, b;
            for (b = 102; b > 0; b--)
                for (a = 3; a > 0; a--)
                    ;
        }
    }
}
/*转换到段表*/
void Chars_convert(union DIS_VAL *chars_ptr)
{
    int i;
    int char_i = 0;
    while (chars_ptr->Chars_data[char_i] != '\0') {
        char_i++;
    }

    for (i = 0; i < char_i; i++) {

        switch ((chars_ptr->Chars_data)[i]) {
            case '0':
                val_arr[i] = 0;
                break;
            case '1':
                val_arr[i] = 1;
                break;
            case '2':
                val_arr[i] = 2;
                break;
            case '3':
                val_arr[i] = 3;
                break;
            case '4':
                val_arr[i] = 4;
                break;
            case '5':
                val_arr[i] = 5;
                break;
            case '6':
                val_arr[i] = 6;
                break;
            case '7':
                val_arr[i] = 7;
                break;
            case '8':
                val_arr[i] = 8;
                break;

            case '9':
                val_arr[i] = 9;
                break;
            case 'a':
                val_arr[i] = 10;
                break;
            case 'A':
                val_arr[i] = 10;
                break;
            case 'b':
                val_arr[i] = 11;
                break;
            case 'B':
                val_arr[i] = 11;
                break;
            case 'c':
                val_arr[i] = 12;
                break;
            case 'C':
                val_arr[i] = 12;
                break;
            case 'D':
                val_arr[i] = 13;
                break;
            case 'd':
                val_arr[i] = 13;
                break;
            case 'E':
                val_arr[i] = 14;
                break;
            case 'e':
                val_arr[i] = 14;
                break;

            case 'F':
                val_arr[i] = 15;
                break;
            case 'f':
                val_arr[i] = 15;
                break;
            case 'H':
                val_arr[i] = 16;
                break;
            case 'h':
                val_arr[i] = 16;
                break;
            case 'L':
                val_arr[i] = 17;
                break;
            case 'l':
                val_arr[i] = 17;
                break;
            case 's':
                val_arr[i] = 18;
                break;
            case 'S':
                val_arr[i] = 18;
                break;

            case 'n':
                val_arr[i] = 20;
                break;
            case 'N':
                val_arr[i] = 20;
                break;
            case 'u':
                val_arr[i] = 21;
                break;
            case 'U':
                val_arr[i] = 21;
                break;
            case 'P':
                val_arr[i] = 22;
                break;
            case 'p':
                val_arr[i] = 22;
                break;
            case 'o':
                val_arr[i] = 23;
                break;
            case 'O':
                val_arr[i] = 23;
                break;
            case 0x00:
                val_arr[i] = 24;
                break;
            case '`':
                val_arr[i] = 25;
                break;
            case '-':
                val_arr[i] = 26;
                break;
            case '_':
                val_arr[i] = 27;
                break;

            default:
                break;
        }
    }
}

// 长整型处理方案
void Ulong_convert(Ulong Z)
{
    // Z长度
    int Zlen = 0;
    int Ulongi;
    int temp[8] = {24};
    int ii;
    for (ii = 0; ii < 8; ii++) {
        val_arr[ii] = 24;
    }

    /*存储Z每个位的数字数组变量*/
    if (Z == 0) {
        val_arr[0] = 0;
    }
    while (Z != 0) {
        // 提取n的各个数位上的数
        val_arr[Zlen] = Z % 10;
        Z /= 10;
        Zlen++;
    }

    for (Ulongi = 0; Ulongi < 8; Ulongi++) {
        temp[Ulongi] = val_arr[7 - Ulongi];
    }

    for (Ulongi = 0; Ulongi < 8; Ulongi++) {
        val_arr[Ulongi] = temp[Ulongi];
    }
}
int Double_convert(double Z)
{
    int Zlen       = 0;
    Ulong zhengshu = Z / 1; // 整数部分
    int ge;                 // 个位数
    int zhengshu_count = 0; // 整数位数
    double xiaoshu     = Z - (double)zhengshu;
    int i              = 0;
    Ulong tempge;
    Uint ii = 0;
    Ulong temp_zhengshu;
    Ulong z = Z / 1;
    if (z == 0) {
        val_arr[0] = 0;
        i          = 1;
        IS_double  = 0;
        ge         = 0;
    } else {
        temp_zhengshu = zhengshu;
        while (temp_zhengshu > 0) {
            // 提取n的各个数位上的数
            temp_zhengshu /= 10;
            ii++;
        }
    }

    while (zhengshu > 0) {
        // 提取n的各个数位上的数

        val_arr[ii - Zlen - 1] = zhengshu % 10;
        zhengshu /= 10;
        Zlen++;
    }
    ge = Zlen;

    if (z == 0) {

        if (8 - Zlen > 0 || 8 - i > 0) {

            for (i = ge + 1; i < 8; i++) {
                val_arr[i] = (xiaoshu * 10) / 1;
                tempge     = xiaoshu * 10;
                xiaoshu    = xiaoshu * 10 - tempge;
            }
        }

    } else {
        if (8 - Zlen > 0 || 8 - i > 0) {

            for (i = ge ; i < 8; i++) {
                val_arr[i] = (xiaoshu * 10) / 1;
                tempge     = xiaoshu * 10;
                xiaoshu    = xiaoshu * 10 - tempge;
            }
        }

                 return ge-1;
    }

    return ge;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|私人站点 ( 冀ICP备2023028127号-2 )

GMT+8, 2025-7-5 13:48 , Processed in 0.081516 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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