找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1931|回复: 9
收起左侧

这单片机代码为什么没有定义按键端口,为什么可以使用按键,求解答

[复制链接]
ID:858009 发表于 2021-4-23 15:01 | 显示全部楼层 |阅读模式
原理图.png
  1. #ifndef _KEY_H_
  2. #define _KEY_H_

  3. //---包含头文件---//
  4. #include "Config.h"

  5. #define KEY_TIME_SHORT         20                //短按的按键去抖动延时的时间

  6. //---加入全局变量--//
  7. extern uchar KeyCode;
  8. extern uint  KeyTimeCnt[5];                        //按键去抖动延时计数器,分别对应KEY1/2/3/4/5
  9. extern uchar KeyLock[5];                                //按键触发后自锁的变量标志,分别对应KEY1/2/3/4/5

  10. //-----------------------------------------------------------------
  11. // 相关函数声明
  12. //-----------------------------------------------------------------
  13. void KeyScan();                                //按键扫描函数 放在定时中断里                        
  14. void Delay10ms();                        //延时函数
  15.                                                         
  16. #endif


  17. #include "Key.h"

  18. uchar KeyCode = 0;                                                //按键编码值

  19. //共5个独立机械按键,通过短按实现5种按键编码值
  20. uint KeyTimeCnt[5] = {0,0,0,0,0};                //按键去抖动延时计数器,分别对应KEY1/2/3/4/5
  21. uchar KeyLock[5] = {0,0,0,0,0};                        //按键触发后自锁的变量标志,分别对应KEY1/2/3/4/5

  22. //-----------------------------------------------------------------
  23. //函数名称:        void KeyScan()
  24. //函数功能:                按键扫描程序,放在定时中断里,可较快实现按键响应
  25. //调用子函数:        无
  26. //输入参数:         无
  27. //返回值:                        无,说明:返回的按键编码值保存在KeyCode变量里
  28. //-----------------------------------------------------------------
  29. void KeyScan()
  30. {
  31. //------KEY1实现-------------------------------------------------
  32.         if(KEY1 == 1)                                                        //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
  33.         {        KeyLock[0] = 0;                                        //按键自锁变量标志清零
  34.                 KeyTimeCnt[0] = 0;                  //按键去抖动延时计数器清零
  35.         }
  36.         else if(KeyLock[0] == 0)
  37.         {
  38.                  KeyTimeCnt[0]++;
  39.                  if(KeyTimeCnt[0] > KEY_TIME_SHORT)  
  40.                  {
  41.                                 KeyTimeCnt[0] = 0;
  42.                                 KeyLock[0] = 1;                  //自锁按键置位,避免一直触发
  43.                                 KeyCode = 1;
  44.                  }
  45.         }
  46.         
  47. //------KEY2实现-----------------------------------
  48.         if(KEY2 == 1)
  49.         {        KeyLock[1] = 0;
  50.                 KeyTimeCnt[1] = 0;
  51.         }
  52.         else if(KeyLock[1] == 0)
  53.         {
  54.                  KeyTimeCnt[1]++;
  55.                  if(KeyTimeCnt[1] > KEY_TIME_SHORT)         //消抖
  56.                  {        
  57.                                 KeyTimeCnt[1] = 0;                                                                 //按键去抖动延时计数器清零
  58.                                 KeyLock[1] = 1;                                                                          //自锁按键置位,避免一直触发
  59.                                 KeyCode = 2;                                                                    
  60.                  }
  61.         }

  62. //------KEY3实现-----------------------------------
  63.         if(KEY3 == 1)
  64.         {        KeyLock[2] = 0;
  65.                 KeyTimeCnt[2] = 0;               
  66.         }
  67.         else if(KeyLock[2] == 0)
  68.         {
  69.                  KeyTimeCnt[2]++;
  70.                  if(KeyTimeCnt[2] > KEY_TIME_SHORT)
  71.                  {        
  72.                                 KeyTimeCnt[2] = 0;
  73.                                 KeyLock[2] = 1;  
  74.                                 KeyCode = 3;                                                                    
  75.                  }
  76.         }

  77. //------KEY4实现-----------------------------------
  78.         if(KEY4 == 1)
  79.         {        KeyLock[3] = 0;
  80.                 KeyTimeCnt[3] = 0;               
  81.         }
  82.         else if(KeyLock[3] == 0)
  83.         {
  84.                  KeyTimeCnt[3]++;
  85.                  if(KeyTimeCnt[3] > KEY_TIME_SHORT)
  86.                  {        
  87.                                 KeyTimeCnt[3] = 0;
  88.                                 KeyLock[3] = 1;  
  89.                                 KeyCode = 4;                                                                    
  90.                  }
  91.         }
  92.         
  93. //------KEY5实现-----------------------------------
  94.         if(KEY5 == 1)
  95.         {        KeyLock[4] = 0;
  96.                 KeyTimeCnt[4] = 0;               
  97.         }
  98.         else if(KeyLock[4] == 0)
  99.         {
  100.                  KeyTimeCnt[4]++;
  101.                  if(KeyTimeCnt[4] > KEY_TIME_SHORT)
  102.                  {        
  103.                                 KeyTimeCnt[4] = 0;
  104.                                 KeyLock[4] = 1;  
  105.                                 KeyCode = 5;                                                                    
  106.                  }
  107.         }
  108. }



  109. #include "Key.h"
  110. //0~9 的共阳数码管段码,最后一个是黑屏
  111. const uchar SEG_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
  112. //输出励磁序列的频率参数{TH1,TL1}
  113. const uchar Timer[9][2]={0xDE,0xE4};//,{0xE1,0xEC},{0xE5,0xD4},{0xE9,0xBC},  //8.476 ~ 1ms
  114.                                                            // {0xEd,0xA4},{0xF1,0x8C},{0xF5,0x74},{0xF9,0x5C},{0xFC,0x18}};
  115. //步进电机正转的励磁序列
  116. const uchar FFW[] = {0x1F,0x3F,0x2F,0x6F,0x4F,0xCF,0x8F,0x9F}; //DCBAXXXX
  117. //步进电机反转的励磁序列
  118. const uchar REV[] = {0x9F,0x8F,0xCF,0x4F,0x6F,0x2F,0x3F,0x1F}; //DCBAXXXX
  119. //枚举变量--正反转标志
  120. typedef enum
  121.         {FwdRun, RevRun} RunFlag;                                                               
  122. RunFlag flag1 = FwdRun;
  123. uchar speed = 0;
  124. //函数声明
  125. void T0_Init();                                        //定时器0初始化函数声明
  126. void T1_Init();                                        //定时器1初始化函数声明
  127. void KeyService();                        //按键服务函数声明
  128. void delay_ms(uint t);        //毫秒延时函数声明
  129.         
  130. //-----------------------------------------------------------------
  131. // 主程序
  132. //-----------------------------------------------------------------
  133. void main()
  134. {        
  135.         T0_Init();                                        //定时器0初始化
  136.         T1_Init();                                        //定时器1初始化
  137.         FWD_LED = 0;                                //正转指示灯亮,默认初始化是正转
  138.         
  139.         delay_ms(500);                        //延时500ms,待各个模块上电稳定
  140.         EA = 1;                                                        //开启中断
  141.         while(1)
  142.         {        
  143.                 KeyService();                //按键服务程序
  144.         }
  145. }        
  146. //-----------------------------------------------------------------
  147. // Timer0 初始化,模式1,允许中断,1ms定时
  148. // Timer0 用于按键扫描
  149. //-----------------------------------------------------------------
  150. void T0_Init()
  151. {
  152.         TMOD &= 0xF0;
  153.         TMOD |= 0x01;                                                                                //T0工作于模式1,16位定时器
  154.         TH0 = (0xFA)/2;//(65536 - 1000) >> 8;                        //1ms定时
  155.         TL0 = (0xFA)/2;//(65536 - 1000) & 0xFF;
  156.         ET0 = 1;                                                                                                //允许T0中断
  157.         TR0 = 1;                                                                                                //启动T0
  158. }
  159. //-----------------------------------------------------------------
  160. // Timer1 初始化,模式1,允许中断
  161. // Timer1 用于改变步进电机转速
  162. //-----------------------------------------------------------------
  163. void T1_Init()
  164. {
  165.         TMOD &= 0x0F;
  166.         TMOD |= 0x10;                                                        //定时器1工作于模式1,16位定时器
  167.         TH1 = Timer[speed][0];
  168.         TL1 = Timer[speed][1];                //定时器1,定时用于步进电机转速控制
  169.         ET1 = 1;                                                                        //允许T1中断
  170.         PT1 = 1;                                                                        //定时器1优先级高
  171.         TR1 = 0;                                                                        //关闭定时器1
  172. }
  173. //-----------------------------------------------------------------
  174. // Timer0 中断服务程序
  175. //-----------------------------------------------------------------
  176. void InterruptTime0() interrupt 1
  177. {
  178.         TH0 = (65536 - 1000) >> 8;                //1ms
  179.         TL0 = (65536 - 1000) & 0xFF;
  180.         KeyScan();                                                                                //按键扫描
  181. }
  182. //-----------------------------------------------------------------
  183. // Timer1 中断服务程序
  184. //-----------------------------------------------------------------
  185. void InterruptTime1() interrupt 3
  186. {
  187.         static step1 = 0;                                                        
  188.         static step2 = 0;
  189.         TH1 = Timer[speed - 1][0];                        //根据不同的转速档位,给定时器1赋定时器值
  190.         TL1 = Timer[speed - 1][1];                        
  191.         
  192.         //按照定时器1的频率循环发送正转励磁序列的脉冲给步进电机,使其不停地转动
  193.         if(flag1 == FwdRun)//正转
  194.         {
  195.                 MotorDriver = FFW[step1++];               
  196.                 if(step1 == 8) step1 = 0;
  197.         }
  198.         
  199.          //按照定时器1的频率循环发送反转励磁序列的脉冲给步进电机,使其不停地转动
  200.         else if(flag1 == RevRun)      
  201.         {
  202.                 MotorDriver = REV[step2++];
  203.                 if(step2 == 8) step2 = 0;
  204.         }
  205. }

  206. //-----------------------------------------------------------------
  207. // 按键服务程序
  208. //-----------------------------------------------------------------
  209. void KeyService()
  210. {
  211.         switch (KeyCode)
  212.         {
  213.                 case 1:        flag1 = FwdRun;                                                                                //正转
  214.                                                 FWD_LED = 0;        REV_LED = 1;                                //正转指示灯亮
  215.                                                 KeyCode = 0;
  216.                                                 break;
  217.             delay_ms(500);               
  218.                 case 2:        flag1 = RevRun;                                                                                //反转
  219.                                                 FWD_LED = 1;        REV_LED = 0;                                //反转指示灯亮
  220.                                                 KeyCode = 0;
  221.                                                 break;
  222.                         delay_ms(500);        
  223.                 case 3:        speed++;                                                                                                        //速度加
  224.                                                 if(speed == 3) speed = 1;                                
  225.                                                 SpeedShow = SEG_CODE[speed];
  226.                                                 if(TR1 == 0) TR1 = 1;
  227.                                                 KeyCode = 0;
  228.                                                 break;
  229.                         delay_ms(500);        
  230. //                case 4:        speed--;                                                                                                        //速度减
  231. //                                                if(speed == 0 || speed == -1 ) speed = 2;
  232. //                                                SpeedShow = SEG_CODE[speed];        
  233. //                                                if(TR1 == 0) TR1 = 1;        
  234. //                                                KeyCode = 0;
  235. //                                                break;
  236.                 case 5:        TR1 = 0;                                                                                                        //停止
  237.                                                 SpeedShow = 0xFF;
  238.                                                 MotorDriver = 0x00;
  239.                                                 KeyCode = 0;
  240.                                                 break;
  241.             delay_ms(500);                                                        
  242.                 default: ;
  243.         }
  244. }

  245. //-----------------------------------------------------------------
  246. //函数名称:        void delay_ms(uint t)
  247. //函数功能:                延时ms程序(粗略)
  248. //调用子函数: 无
  249. //输入参数:         t
  250. //返回值:                        无
  251. //-----------------------------------------------------------------
  252. void delay_ms(uint t)
  253. {
  254.         uchar i; while(t--) for(i = 0; i < 125; i++);
  255. }
复制代码
回复

使用道具 举报

ID:495628 发表于 2021-4-23 16:42 | 显示全部楼层
Key.h  这个头文件里面的内容呢?
回复

使用道具 举报

ID:858009 发表于 2021-4-23 16:44 | 显示全部楼层
Wongrui 发表于 2021-4-23 16:42
Key.h  这个头文件里面的内容呢?

1-20行
回复

使用道具 举报

ID:858009 发表于 2021-4-23 16:46 | 显示全部楼层
Wongrui 发表于 2021-4-23 16:42
Key.h  这个头文件里面的内容呢?

key.h 第1行到20行
key.c 23-119行
main.c 后面的
回复

使用道具 举报

ID:808700 发表于 2021-4-23 17:48 | 显示全部楼层
你这应该是在key.h文件里面定义了吧
回复

使用道具 举报

ID:858009 发表于 2021-4-23 17:50 | 显示全部楼层
lxbhcy 发表于 2021-4-23 17:48
你这应该是在key.h文件里面定义了吧

全部代码在这了
回复

使用道具 举报

ID:910953 发表于 2021-4-23 18:14 | 显示全部楼层
这里按键在key.h里面已经定义好了,相应的按键都使用KeyCode进行编码,在按键服务程序里面使用了5个按键,其他按键无效
回复

使用道具 举报

ID:858009 发表于 2021-4-23 18:18 | 显示全部楼层
Tracker123 发表于 2021-4-23 18:14
这里按键在key.h里面已经定义好了,相应的按键都使用KeyCode进行编码,在按键服务程序里面使用了5个按键, ...

不太明白,换其他的io口怎么不可以实现的
回复

使用道具 举报

ID:796531 发表于 2021-4-23 22:40 | 显示全部楼层
你头文件里还包含了 #include "Config.h"  ,应该是 Config.h里定义了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:894154 发表于 2021-4-24 10:57 | 显示全部楼层
我看你的程序也没有定义#define uchar unsigned char;#define uint unsigned int ,为啥也能直接用uchar uint
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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