找回密码
 立即注册
楼主: 飞行者

Ai8051u擎天柱学习冲哥《8051U深度入门到32位51大型实战视频》记录贴

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:88
  • 最近打卡:2025-08-04 07:30:01

2

主题

23

回帖

381

积分

中级会员

积分
381
发表于 昨天 12:02 | 显示全部楼层
11.矩阵按键

屏幕截图 2025-07-26 154436.png
io.c代码
  1. #include "io.h"
  2. u8 State1 = 0;                                        //LED1初始状态
  3. u8 State2 = 0;                                        //LED2初始状态
  4. u8 State3 = 0;                                        //LED3初始状态
  5. u16 Key_Vol = 0;                                //按键按下持续时间(几个十秒)
  6. u8 SEG_NUM[] =
  7. {
  8.         0x3F,       /*'0', 0*/
  9.     0x06,       /*'1', 1*/
  10.     0x5B,       /*'2', 2*/
  11.     0x4F,       /*'3', 3*/
  12.     0x66,       /*'4', 4*/
  13.     0x6D,       /*'5', 5*/
  14.     0x7D,       /*'6', 6*/
  15.     0x07,       /*'7', 7*/
  16.     0x7F,       /*'8', 8*/
  17.     0x6F,       /*'9', 9*/
  18.     0x77,       /*'A', 10*/
  19.     0x7C,       /*'B', 11*/
  20.     0x39,       /*'C', 12*/
  21.     0x5E,       /*'D', 13*/
  22.     0x79,       /*'E', 14*/
  23.     0x71,       /*'F', 15*/
  24.     0x40,       /*'-', 16*/
  25.     0x00,       /*' ', 17*/
  26.     0x80,       /*'.', 18*/
  27. };
  28. u8 T_NUM[8] =
  29. {
  30.         0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
  31. };
  32. void LED0_Blink(void)
  33. {
  34.         State1 = !State1;
  35.         P00 = State1;
  36. }
  37. void LED1_Blink(void)
  38. {
  39.         State2 = !State2;
  40.         P01 = State2;
  41. }
  42. void LED2_Blink(void)
  43. {
  44.         State3 = !State3;
  45.         P02 = State3;
  46. }
  47. void Key_Task(void)
  48. {
  49.                 if( P32 == 0 )
  50.                 {
  51.                         Key_Vol++;
  52.                         if(Key_Vol == 5)
  53.                         {
  54.                                 printf("按键单击\r\n");
  55.                         }       
  56.                 }
  57.                 else
  58.                 {
  59.                         Key_Vol = 0;       
  60.                 }
  61. }
  62. /*
  63. ----------行------------
  64.         #define ROW1        P06                //定义端口
  65.         #define ROW2        P07
  66. ----------列-------------
  67.         #define COL1        P00
  68.         #define COL2        P01
  69.         #define COL3        P02                                               
  70.         #define COL4        P03
  71. */
  72. //任务1:数码管显示当前的按键号
  73. u8 key_num = 0xff;                //key_num =0 给按键传递一个键值
  74. void Task_1(void)
  75. {
  76.                         //static静态变量,只有第一次进来时才赋值,key_num =0 给按键传递一个键值
  77.        
  78. //        ①第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
  79.         COL1 = 0;
  80.         COL2 = 0;
  81.         COL3 = 0;
  82.         COL4 = 0;
  83.         ROW1 = 1;
  84.         ROW2 = 1;
  85.        
  86.         if((ROW1 == 0) || (ROW2 == 0))                        //"||"或的符号,只要满足其中之一的条件(行按键按下)
  87.         {
  88.                 if((ROW1 == 0) && (ROW2 == 0))                //如果两行都有按键按下,不处理
  89.                 {
  90.                
  91.                 }
  92.                 else if ( ((ROW1 == 1)&&(ROW2 == 0)) || ((ROW1 == 0)&&(ROW2 == 1)) )        //如果有按键按下,而且只有一颗
  93.                 {
  94.                         if( ROW1 == 0 )                                        //判断哪一行,输出行开始的序号
  95.                                 key_num = 0;
  96.                         else if(ROW2 == 0)
  97.                                 key_num = 4;
  98.                        
  99.                         //②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
  100.                         COL1 = 1;
  101.                         COL2 = 1;
  102.                         COL3 = 1;
  103.                         COL4 = 1;
  104.                         ROW1 = 0;
  105.                         ROW2 = 0;
  106.                        
  107.                         //判断哪一列,叠加按键的序号
  108.                         if(COL1 ==0)               
  109.                         {
  110. //                                key_num = key_num +0;
  111.                         }
  112.                         else if( COL2 == 0)
  113.                         {
  114.                                 key_num = key_num +1;
  115.                         }
  116.                         else if( COL3 == 0)
  117.                         {
  118.                                 key_num = key_num +2;
  119.                         }
  120.                         else if( COL4 == 0)
  121.                         {
  122.                                 key_num = key_num +3;
  123.                         }
  124.                 }
  125.                 COL1 = 0;
  126.                 COL2 = 0;
  127.                 COL3 = 0;
  128.                 COL4 = 0;
  129.                 ROW1 = 1;
  130.                 ROW2 = 1;
  131.         }
  132.         else
  133.         {
  134.                 key_num =0xff;
  135.         }
  136.                                                                        
  137.         //        ③第三步:行列组合一下就可以判断出是哪个按键按下了。
  138. }
  139. void Init_595(void)
  140. {
  141.         HC595_SER  = 0;
  142.         HC595_RCK  = 0;
  143.         HC595_SCK  = 0;
  144. }
  145. void Send_595( u8 dat )
  146. {
  147.         u8 i;
  148.         for( i=0; i<8; i++ )
  149.         {
  150.                 dat <<= 1;                        //数值左移一位
  151.                 HC595_SER  = CY;        //数据写到引脚
  152.             HC595_SCK  = 1;                //输出上升沿的时钟信号
  153.         HC595_SCK  = 0;
  154.         }
  155. }
  156. void Display_Seg( u8 HC595_1,u8 HC595_2)
  157. {
  158.         Send_595(HC595_1);                //数码管段码输出        高电平点亮
  159.         Send_595(HC595_2);                //数码管位码输出        低电平点亮
  160.         HC595_RCK  = 1;                        //数据输出
  161.         HC595_RCK  = 0;
  162. }
  163. //void SEG_Task(void)
  164. //{
  165. //        if(key_num == 255)
  166. //                Display_Seg( SEG_NUM[17], ~T_NUM[0]);        //数码管段码和位码
  167. //        else
  168. //                Display_Seg( SEG_NUM[key_num], ~T_NUM[0]);        //数码管段码和位码
  169. //}       
  170. //任务二:简易密码箱
  171. u8 passward[8] = { 16,16,16,16,16,16,16,16};
  172. u8 Seg_no = 0;
  173. void SEG_Task(void)
  174. {
  175.                 u8 num = 0;
  176.         if( Seg_no ==0 )                                                                //小时十位
  177.         {
  178.        
  179.                 Display_Seg( SEG_NUM[passward[0]] , ~T_NUM[0]);                //数码管刷段码和位码
  180.         }
  181.         else if( Seg_no ==1 )                                                        //小时的个位
  182.         {
  183.                
  184.                 Display_Seg( SEG_NUM[passward[1]] , ~T_NUM[1]);                //数码管刷段码和位码
  185.         }       
  186.         else if( Seg_no ==2 )                                                        //第一个横杠
  187.         {
  188.                 Display_Seg( SEG_NUM[passward[2]] , ~T_NUM[2]);                //数码管刷段码和位码
  189.         }       
  190.         else if( Seg_no ==3 )                                                        //分钟的十位
  191.         {
  192.                
  193.                 Display_Seg( SEG_NUM[passward[3]] , ~T_NUM[3]);                //数码管刷段码和位码
  194.         }
  195.         else if( Seg_no ==4 )
  196.         {
  197.                
  198.                 Display_Seg( SEG_NUM[passward[4]] , ~T_NUM[4]);                //数码管刷段码和位码
  199.         }       
  200.         else if( Seg_no ==5 )
  201.         {
  202.                 Display_Seg( SEG_NUM[passward[5]] , ~T_NUM[5]);                //数码管刷段码和位码
  203.         }       
  204.         else if( Seg_no ==6 )
  205.         {
  206.                
  207.                 Display_Seg( SEG_NUM[passward[6]] , ~T_NUM[6]);                //数码管刷段码和位码
  208.         }
  209.         else if( Seg_no ==7 )
  210.         {
  211.                
  212.                 Display_Seg( SEG_NUM[passward[7]] , ~T_NUM[7]);                //数码管刷段码和位码
  213.         }       
  214.         else
  215.         {
  216.                
  217.         }
  218.         Seg_no ++;
  219.         if( Seg_no>7 )
  220.                 Seg_no=0;               
  221. }
  222. u8 Key_Vol3 = 0;                                                //判断按钮是否按下
  223. u8 Key_no = 0;                                                        //数码管位计数
  224. //密码输入显示
  225. void PW_write_Task(void)
  226. {
  227.         if( key_num <0xff )
  228.                 {
  229.                         Key_Vol3 ++;
  230.                         if(Key_Vol3 == 5)
  231.                         {
  232.                                 if(Key_no == 0)                        //数码管没有按下时显示“-”
  233.                                 {
  234.                                         passward[0] = 16;
  235.                                         passward[1] = 16;
  236.                                         passward[2] = 16;
  237.                                         passward[3] = 16;
  238.                                         passward[4] = 16;
  239.                                         passward[5] = 16;
  240.                                         passward[6] = 16;
  241.                                         passward[7] = 16;
  242.                                 }
  243.                                 passward[Key_no] = key_num;
  244.                                 Key_no++;
  245.                                 if( Key_no == 8 )                //密码输入到了八位
  246.                                 {
  247.                                         if((passward[0]==1)&&(passward[1]==2)&&(passward[2]==3)&&(passward[3]==4)&&(passward[4]==5)&&(passward[5]==6)&&(passward[6]==7)&&(passward[7]==8))
  248.                                         {
  249.                                                 //密码正确八位数码管显示为1
  250.                                                 passward[0] = 17;
  251.                                                 passward[1] = 17;
  252.                                                 passward[2] = 17;
  253.                                                 passward[3] = 17;
  254.                                                 passward[4] = 17;
  255.                                                 passward[5] = 17;
  256.                                                 passward[6] = 17;
  257.                                                 passward[7] = 1;
  258.                                         }
  259.                                         else                                 //密码输入错误八位数码管显示为空
  260.                                         {
  261.                                                 passward[0] = 16;
  262.                                                 passward[1] = 16;
  263.                                                 passward[2] = 16;
  264.                                                 passward[3] = 16;
  265.                                                 passward[4] = 16;
  266.                                                 passward[5] = 16;
  267.                                                 passward[6] = 16;
  268.                                                 passward[7] = 16;
  269.                                         }
  270.                                         Key_no = 0;
  271.                                 }
  272.                                        
  273.                         }       
  274.                 }
  275.                 else
  276.                 {
  277.                         Key_Vol3 = 0;       
  278.                 }
  279. }
复制代码
io.h代码
  1. #ifndef __IO_H
  2. #define __IO_H
  3. #include "config.h"        //调用头文件
  4. //定义引脚名称
  5. #define HC595_SER         P34
  6. #define HC595_RCK         P35
  7. #define HC595_SCK         P32
  8. /*-----------定义端口-------------*/
  9. #define ROW1        P06                //定义端口
  10. #define ROW2        P07
  11. #define COL1        P00
  12. #define COL2        P01
  13. #define COL3        P02
  14. #define COL4        P03
  15. extern u8 key_num ;
  16. /*-----------函数声明-------------*/
  17. void LED0_Blink(void);
  18. void LED1_Blink(void);
  19. void LED2_Blink(void);
  20. void Key_Task(void);
  21. void Task_1(void);
  22. void SEG_Task(void);
  23. void Init_595(void);
  24. void PW_write_Task(void);
  25. #endif
复制代码
task.c代码

  1. #include "task.h"
  2. #include "io.h"
  3. //========================================================================
  4. //                               本地变量声明
  5. //========================================================================
  6. static TASK_COMPONENTS Task_Comps[]=
  7. {
  8. //状态  计数  周期  函数
  9. //        {0, 300,   300,   LED0_Blink},     /* task 1 Period: 300ms */
  10. //        {0, 600,   600,   LED1_Blink},      /* task 1 Period: 600ms */
  11. //        {0, 900,   900,   LED2_Blink},      /* task 1 Period: 900ms */
  12. //        {0, 10,    10,    Key_Task},      /* task 1 Period: 50ms */
  13.         {0, 10,     10,     Task_1},      /* task 1 Period: 10ms */
  14.         {0, 1,     1,     SEG_Task},      /* task 1 Period: 10ms */
  15.         {0, 10,    10,   PW_write_Task},      /* task 1 Period: 100ms */
  16.        
  17.        
  18. };
  19. u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
  20. //========================================================================
  21. // 函数: Task_Handler_Callback
  22. // 描述: 任务标记回调函数.
  23. // 参数: None.
  24. // 返回: None.
  25. // 版本: V1.0, 2012-10-22
  26. //========================================================================
  27. void Task_Marks_Handler_Callback(void)
  28. {
  29.     u8 i;
  30.     for(i=0; i<Tasks_Max; i++)
  31.     {
  32.         if(Task_Comps[i].TIMCount)      /* If the time is not 0 */
  33.         {
  34.             Task_Comps[i].TIMCount--;   /* Time counter decrement */
  35.             if(Task_Comps[i].TIMCount == 0) /* If time arrives */
  36.             {
  37.                 /*Resume the timer value and try again */
  38.                 Task_Comps[i].TIMCount = Task_Comps[i].TRITime;  
  39.                 Task_Comps[i].Run = 1;      /* The task can be run */
  40.             }
  41.         }
  42.     }
  43. }
  44. //========================================================================
  45. // 函数: Task_Pro_Handler_Callback
  46. // 描述: 任务处理回调函数.
  47. // 参数: None.
  48. // 返回: None.
  49. // 版本: V1.0, 2012-10-22
  50. //========================================================================
  51. void Task_Pro_Handler_Callback(void)
  52. {
  53.     u8 i;
  54.     for(i=0; i<Tasks_Max; i++)
  55.     {
  56.         if(Task_Comps[i].Run) /* If task can be run */
  57.         {
  58.             Task_Comps[i].Run = 0;      /* Flag clear 0 */
  59.             Task_Comps[i].TaskHook();   /* Run task */
  60.         }
  61.     }
  62. }
复制代码


11.矩阵按键.rar (183.66 KB, 下载次数: 0)
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-5 03:23 , Processed in 0.459457 second(s), 48 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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