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

矩阵键盘

[复制链接]

3711

主题

1

回帖

1万

积分

管理员

积分
11937
发表于 2023-1-26 15:30:50 | 显示全部楼层 |阅读模式
  1. /*

  2. 矩阵键盘

  3. 数码管字符串,双精度,长整型显示
  4. 利用共用体指针解决方案


  5. */
  6. #include <REG52.H>
  7. #include <stdio.h>
  8. #include <string.h>

  9. #define Uchar unsigned char
  10. #define Uint  unsigned int
  11. #define Ulong unsigned long

  12. // 引脚定义区域
  13. sbit DU = P2 ^ 6; // 数码管段选
  14. sbit WE = P2 ^ 7; // 数码管位选
  15. Uchar y = 999;    // 行 初始化
  16. Uchar x = 999;    // 列初始化

  17. int IS_double = 999;

  18. int Get_val(union DIS_VAL *val, int type);
  19. void Dis_scan();
  20. void DIS_play(int result, int type);
  21. void delay(Uchar z, int mod);
  22. void Chars_convert(union DIS_VAL *chars_ptr);
  23. void Ulong_convert(Ulong Z);
  24. int Double_convert(double Z);

  25. int val_arr[] = {24, 24, 24, 24, 24, 24, 24, 24}; // 24 在表码表中定义熄灭

  26. // 用共用体作为万能数据类型,兼容多种场景
  27. union DIS_VAL {
  28.     /*无符号长整型*/
  29.     unsigned long ULONG_data;
  30.     /*浮点型*/
  31.     float Float_data;
  32.     /*双精度*/
  33.     double Double_data;
  34.     /*字符串*/
  35.     char *Chars_data;
  36. };
  37. // 定义4*4 矩阵键盘
  38. int code KEY_TABLE[4][4] = {
  39.     {0, 1, 2, 3},
  40.     {4, 5, 6, 7},
  41.     {8, 9, 10, 11},
  42.     {12, 13, 14, 15}

  43. };
  44. // 段码表
  45. Uchar code DUtabel[] = {
  46.     0x3F, //"0"
  47.     0x06, //"1"
  48.     0x5B, //"2"
  49.     0x4F, //"3"
  50.     0x66, //"4"
  51.     0x6D, //"5"
  52.     0x7D, //"6"
  53.     0x07, //"7"
  54.     0x7F, //"8"
  55.     0x6F, //"9"
  56.     0x77, //"A"
  57.     0x7C, //"B"
  58.     0x39, //"C"
  59.     0x5E, //"D"
  60.     0x79, //"E"
  61.     0x71, //"F"
  62.     0x76, //"H"
  63.     0x38, //"L"
  64.     0x6d, // S
  65.     0x6d, // S
  66.     0x37, //"n"
  67.     0x3E, //"u"
  68.     0x73, //"P"
  69.     0x63, //"o"
  70.     0x00, // 熄灭
  71.     0x01, // 上 -
  72.     0x40, // 中 -
  73.     0x08, // 下 -

  74. };

  75. // 位码表
  76. Uchar code WEtabel[] = {
  77.     0xFE, // 1
  78.     0xFD, // 2
  79.     0xfb, // 3
  80.     0xf7, // 4
  81.     0xef, // 5
  82.     0xdf, // 6
  83.     0xbf, // 7
  84.     0x7f, // 8
  85. };

  86. // 合法字符表
  87. Uchar code Enable_tabel[] = {
  88.     '0',
  89.     '1',
  90.     '2',
  91.     '3',
  92.     '4',
  93.     '5',
  94.     '6',
  95.     '7',
  96.     '8',
  97.     '9',
  98.     'a',
  99.     'b',
  100.     'c',
  101.     'd',
  102.     'e',
  103.     'f',
  104.     'h',
  105.     'l',
  106.     'A',
  107.     'B',
  108.     'C',
  109.     'D',
  110.     'E',
  111.     'F',
  112.     'H',
  113.     'L',
  114.     'S',
  115.     's',
  116.     'n',
  117.     'N',
  118.     'u',
  119.     'U',
  120.     'P',
  121.     'p',
  122.     'O',
  123.     'o',
  124.     '-',
  125.     '_',

  126. };

  127. int main()
  128. {
  129.     union DIS_VAL val;

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

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

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

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

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

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

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

  142.     //     while (1)

  143.     //     {
  144.     //         Dis_scan();
  145.     //     }
  146.     // } else {
  147.     //     // 显示错误代码 001 传入字符串有误
  148.     //     val.Chars_data = "no000001";
  149.     //     Chars_convert(&val);
  150.     //     while (1) {
  151.     //         Dis_scan();
  152.     //     }
  153.     // }

  154.     while (1) {

  155.         val.ULONG_data = Matrix_scan();
  156.         Get_val(&val, 1);
  157.         Dis_scan();
  158.     }
  159. }

  160. /*

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

  174.     char *charP       = val->Chars_data;
  175.     Ulong *ulongP     = val->ULONG_data;
  176.     double Double_val = val->Double_data;
  177.     int count;
  178.     int find_char;
  179.     int i = 0;

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

  185.             Ulong_convert(ulongP);
  186.             break;

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

  192.             break;
  193.         case 3: // 双精度

  194.             if (val->Double_data < 0 || val->Double_data > 99999999) {
  195.                 return 0;
  196.             }
  197.             IS_double = Double_convert(Double_val);

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

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

  210.                         find_char = 1;
  211.                         // continue;
  212.                         break;
  213.                     } else {

  214.                         find_char = 0;
  215.                     }
  216.                 }

  217.                 if (find_char == 0 || count >= 9) {
  218.                     return 0;
  219.                 } else {
  220.                     continue;
  221.                 }
  222.             }

  223.             break;

  224.         default:
  225.             break;
  226.     }

  227.     return 1;
  228. }

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

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

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

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

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

  255.     } else {
  256.         P0 = DUtabel[result];
  257.     }
  258.     DU = 0; // 锁存段选数据
  259.     delay(2, 1);
  260. }
  261. /*
  262. 延迟函数.晶振:11.0592
  263. 参数1:z为数量
  264. 参数2:mod为模式
  265. 1:毫秒
  266. 2:秒
  267. */
  268. void delay(Uchar z, int mod)
  269. {
  270.     Uint i;

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

  273.             unsigned char a, b;
  274.             for (b = 102; b > 0; b--)
  275.                 for (a = 3; a > 0; a--)
  276.                     ;
  277.         }
  278.     }

  279.     else if (mod == 2) {
  280.         for (i = 0; i < z * 1000; i++) {
  281.             // 10000us //误差 -0.000000000002us
  282.             unsigned char a, b;
  283.             for (b = 102; b > 0; b--)
  284.                 for (a = 3; a > 0; a--)
  285.                     ;
  286.         }
  287.     }
  288. }
  289. /*转换到段表*/
  290. void Chars_convert(union DIS_VAL *chars_ptr)
  291. {
  292.     int i;
  293.     int char_i = 0;
  294.     while (chars_ptr->Chars_data[char_i] != '\0') {
  295.         char_i++;
  296.     }

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

  298.         switch ((chars_ptr->Chars_data)[i]) {
  299.             case '0':
  300.                 val_arr[i] = 0;
  301.                 break;
  302.             case '1':
  303.                 val_arr[i] = 1;
  304.                 break;
  305.             case '2':
  306.                 val_arr[i] = 2;
  307.                 break;
  308.             case '3':
  309.                 val_arr[i] = 3;
  310.                 break;
  311.             case '4':
  312.                 val_arr[i] = 4;
  313.                 break;
  314.             case '5':
  315.                 val_arr[i] = 5;
  316.                 break;
  317.             case '6':
  318.                 val_arr[i] = 6;
  319.                 break;
  320.             case '7':
  321.                 val_arr[i] = 7;
  322.                 break;
  323.             case '8':
  324.                 val_arr[i] = 8;
  325.                 break;

  326.             case '9':
  327.                 val_arr[i] = 9;
  328.                 break;
  329.             case 'a':
  330.                 val_arr[i] = 10;
  331.                 break;
  332.             case 'A':
  333.                 val_arr[i] = 10;
  334.                 break;
  335.             case 'b':
  336.                 val_arr[i] = 11;
  337.                 break;
  338.             case 'B':
  339.                 val_arr[i] = 11;
  340.                 break;
  341.             case 'c':
  342.                 val_arr[i] = 12;
  343.                 break;
  344.             case 'C':
  345.                 val_arr[i] = 12;
  346.                 break;
  347.             case 'D':
  348.                 val_arr[i] = 13;
  349.                 break;
  350.             case 'd':
  351.                 val_arr[i] = 13;
  352.                 break;
  353.             case 'E':
  354.                 val_arr[i] = 14;
  355.                 break;
  356.             case 'e':
  357.                 val_arr[i] = 14;
  358.                 break;

  359.             case 'F':
  360.                 val_arr[i] = 15;
  361.                 break;
  362.             case 'f':
  363.                 val_arr[i] = 15;
  364.                 break;
  365.             case 'H':
  366.                 val_arr[i] = 16;
  367.                 break;
  368.             case 'h':
  369.                 val_arr[i] = 16;
  370.                 break;
  371.             case 'L':
  372.                 val_arr[i] = 17;
  373.                 break;
  374.             case 'l':
  375.                 val_arr[i] = 17;
  376.                 break;
  377.             case 's':
  378.                 val_arr[i] = 18;
  379.                 break;
  380.             case 'S':
  381.                 val_arr[i] = 18;
  382.                 break;

  383.             case 'n':
  384.                 val_arr[i] = 20;
  385.                 break;
  386.             case 'N':
  387.                 val_arr[i] = 20;
  388.                 break;
  389.             case 'u':
  390.                 val_arr[i] = 21;
  391.                 break;
  392.             case 'U':
  393.                 val_arr[i] = 21;
  394.                 break;
  395.             case 'P':
  396.                 val_arr[i] = 22;
  397.                 break;
  398.             case 'p':
  399.                 val_arr[i] = 22;
  400.                 break;
  401.             case 'o':
  402.                 val_arr[i] = 23;
  403.                 break;
  404.             case 'O':
  405.                 val_arr[i] = 23;
  406.                 break;
  407.             case 0x00:
  408.                 val_arr[i] = 24;
  409.                 break;
  410.             case '`':
  411.                 val_arr[i] = 25;
  412.                 break;
  413.             case '-':
  414.                 val_arr[i] = 26;
  415.                 break;
  416.             case '_':
  417.                 val_arr[i] = 27;
  418.                 break;

  419.             default:
  420.                 break;
  421.         }
  422.     }
  423. }

  424. // 长整型处理方案
  425. void Ulong_convert(Ulong Z)
  426. {
  427.     // Z长度
  428.     int Zlen = 0;
  429.     int Ulongi;
  430.     int temp[8] = {24};
  431.     int ii;
  432.     for (ii = 0; ii < 8; ii++) {
  433.         val_arr[ii] = 24;
  434.     }

  435.     /*存储Z每个位的数字数组变量*/
  436.     if (Z == 0) {
  437.         val_arr[0] = 0;
  438.     }
  439.     while (Z != 0) {
  440.         // 提取n的各个数位上的数
  441.         val_arr[Zlen] = Z % 10;
  442.         Z /= 10;
  443.         Zlen++;
  444.     }

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

  448.     for (Ulongi = 0; Ulongi < 8; Ulongi++) {
  449.         val_arr[Ulongi] = temp[Ulongi];
  450.     }
  451. }
  452. int Double_convert(double Z)
  453. {
  454.     int Zlen       = 0;
  455.     Ulong zhengshu = Z / 1; // 整数部分
  456.     int ge;                 // 个位数
  457.     int zhengshu_count = 0; // 整数位数
  458.     double xiaoshu     = Z - (double)zhengshu;
  459.     int i              = 0;
  460.     Ulong tempge;
  461.     Uint ii = 0;
  462.     Ulong temp_zhengshu;
  463.     Ulong z = Z / 1;
  464.     if (z == 0) {
  465.         val_arr[0] = 0;
  466.         i          = 1;
  467.         IS_double  = 0;
  468.         ge         = 0;
  469.     } else {
  470.         temp_zhengshu = zhengshu;
  471.         while (temp_zhengshu > 0) {
  472.             // 提取n的各个数位上的数
  473.             temp_zhengshu /= 10;
  474.             ii++;
  475.         }
  476.     }

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

  479.         val_arr[ii - Zlen - 1] = zhengshu % 10;
  480.         zhengshu /= 10;
  481.         Zlen++;
  482.     }
  483.     ge = Zlen;

  484.     if (z == 0) {

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

  486.             for (i = ge + 1; i < 8; i++) {
  487.                 val_arr[i] = (xiaoshu * 10) / 1;
  488.                 tempge     = xiaoshu * 10;
  489.                 xiaoshu    = xiaoshu * 10 - tempge;
  490.             }
  491.         }

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

  494.             for (i = ge; i < 8; i++) {
  495.                 val_arr[i] = (xiaoshu * 10) / 1;
  496.                 tempge     = xiaoshu * 10;
  497.                 xiaoshu    = xiaoshu * 10 - tempge;
  498.             }
  499.         }

  500.         return ge - 1;
  501.     }

  502.     return ge;
  503. }

  504. int Matrix_scan()
  505. {

  506.     P3 = 0XF0;
  507.     if (P3 != 0XF0) {

  508.         x = P3;
  509.         delay(10, 1);
  510.         P3 = 0X0F;
  511.     }
  512.     P3 = 0X0F;
  513.     if (P3 != 0X0F) {

  514.         y = P3;
  515.         delay(10, 1);
  516.     }

  517.     switch (x) {
  518.         case 0x70:
  519.             x = 3;
  520.             break;
  521.         case 0xb0:
  522.             x = 2;
  523.             break;
  524.         case 0xd0:
  525.             x = 1;
  526.             break;
  527.         case 0xe0:
  528.             x = 0;
  529.             break;

  530.         default:
  531.             break;
  532.     }

  533.     switch (y) {
  534.         case 0x0e:
  535.             y = 0;
  536.             break;
  537.         case 0x0d:
  538.             y = 1;
  539.             break;
  540.         case 0x0b:
  541.             y = 2;
  542.             break;
  543.         case 0x07:
  544.             y = 3;
  545.             break;

  546.         default:
  547.             break;
  548.     }

  549.     return KEY_TABLE[y][x];
  550. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-7-6 02:10 , Processed in 0.085603 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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