OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5915|回复: 10

IO口作为输入使用的方法、连续按键中问题的解决;什么是static、u8?MDK5注释乱码怎么办?(第八天)

[复制链接]

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
发表于 2019-8-30 10:48:36 | 显示全部楼层 |阅读模式
本帖最后由 清夏 于 2019-8-30 20:50 编辑

       前两天在家里玩得很开心,果然还是家里好。不过回来了,就该收心去做正事了。PS:这个实验的函数耍的我团团转啊,mmp!!!
       正点原子的按键输入试验实际上是在教我们IO口作为输入使用的方法(就是通过IO口向单片机发送一些信息),那具体的操作步骤是:①使能IO口时钟
②初始化IO口模式(因为我们要输入信息,所以选择上拉或下拉输入模式
③读取IO口电平(因为我们输入的信息都是高低电平的形式,类似二战时候的电台,那么就需要翻译出来了;读取IO口有三种操作分别是:调用库函数读取、操作寄存器读取、使用位带操作读取

       好,具体步骤知道了,这只是咱们写程序要用的,接下来我们得看看整个实验是怎么进行的(我只是按照我的学习思路进行讲解,感觉正点的视频讲解有点太高,理解起来不容易):
       首先按键有松开和按下两种状态,相应的有0和1两种电平(这应该是寄存器的特性吧。。我看其他元件也是这样),然后IO口通过读取电平来判断按键是否按下。在正点原子的实验中KEY0和KEY1两个按键松开的状态是1,按下的状态是0。(注意:WK_UP按键正好相反!!松开的状态是0,按下的状态是1) 我们要它实现的是按KEY0来控制红灯,按KEY1来控制绿灯,按WK_UP翻转这两个灯的状态。我们根据这个可以写main程序,但问题来了,在写main程序之前我们怎么样写读取按键状态的函数
       这个是正点原子给的按键处理函数(mdzz,我看这个看了好长时间不懂,回去温习了一下C语言才看懂),下面我一句一句去解释一下,当然里面涉及到了static和u8新知识(下面有介绍),我建议先了解一下再看:
u8 KEY_Scan(u8 mode)             //自定义了一个KEY_Scan函数(函数名字可以自己随便取),mode是参数,可以自己进行取值        
{
   static u8 key_up=1;               //定义了一个key_up参数(当然名字可以随便取),并且让它等于1,最妙的是这个static ,一两句说不完,最下面有相关解释
   if(mode)  
      key_up=1;                         //如果你设定的mode为0(就是假),则这个语句永不执行;如果mode为1,则令key_up=1。这一句和上一条语句相辅相成,缺一不可,妙处也在最下面有解释         
   if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))                //这里面的key_up其实是key_up==1
        {
                delay_ms(10);          //这个是去抖动,因为在按键按下的时候电平并不稳定,会出现电平忽0忽1的情况,所以先等10毫秒再去测量电平
                key_up=0;               //这里让key_up=0的原因就是如果mode=0时,一会再调用函数的时候就不会符合if的条件,就不执行这条if了(是为了不支持连续按的操作)
                if(KEY0==0)         
                   return KEY0_PRES;     //这是检测到KEY0键确实按下,返回KEY0_PRES值(在头文件中有定义,可以去看)
                else if(KEY1==0)
                   return KEY1_PRES;     //这是检测到KEY1键确实按下,返回KEY1_PRES值
                else if(WK_UP==1)
                   return WKUP_PRES;    //这是检测到KE_UP键确实按下,返回KEUP_PRES值
        }
   else if(KEY0==1&&KEY1==1&&WK_UP==0)            
      key_up=1;                                     //这是检测到三个键都没有按下,令key_up=1
   return 0;                                    //如果前面那些条件都不符合,就返回0                             
}
PS:太坑了!!!这里的支持连续按的意思是按住按键不动,灯就可以不停的闪灭;不支持连续按的意思是按住按键哪怕好几秒也就只变一次!!!不是我们平常理解的连续按几次的意思,要注意啊!!!

       什么是u8?
       首先说一下什么是u8u8是unsigned char的简写(大爷的简写就简写,干嘛这么简,都看不出来了),还有相关知识的拓展u8、u16、u32都是C语言数据类型,分别代表8位、16位、32位长度的数据类型;一个字节是8位,所以u8是1个字节、u16(unsigned short)是2个字节、u32(unsigned short)是4个字节。为什么用u8定义呢?因为u8可以存放的数据足够这个程序用的了,就不用太大的存储空间了。

       再说一下static 这个东西是什么?
       我上网查了一下,static有很多很复杂的作用,但,我只是个渣渣(滑稽),只需要了解它在这个函数中有什么作用就好。static的作用是这个变量只初始化一次,退出函数之后仍然保持其值

       我之前说有两条语句很妙,那么妙在何处?
       假设我们按下了一个键,函数运行完之后key_up=0,根据main函数设定,10ms后会再次调用这个函数。正常情况下,我们再调用这个函数,key_up会再次被初始化为1(这是第二次初始化),而有了static,它就不会再初始化了(因为static的作用就是让key_up只初始化一次),而是依然保持key_up=0。那么这个函数就没有用了,也就是说我们不管按多久,只会让按键函数用一次(这就是不支持连续按键)。       那我们如果想要按着这个按键,灯就一灭一亮该怎么办呢?于是就加入了 if(mode)  key_up=1这条语句,只要我们让mode=1,那每次调用函数的时候,就可以让key_up=1了,这个函数每次都可以用了这就是支持连续按键)。玛德,妙哇!
       除此之外,我们还得将延时改长(因为10ms太短,所以灯的状态在我们看来几乎是不变的),那么我们会发现修改main函数中的延时不管用,反而是修改读取按键函数中的延时有用,这是为什么呢?
       我们如果一直按着按键,main函数在死循环中不断地读取按键函数返回的值,那么main函数中的延时就不起作用了(因为主函数是switch函数,只会选择一条路径),所以要想延时只能用按键函数中的延时。

       MDK5注释乱码怎么办?
       我在使用keil5软件的时候发现打注释老是变成乱码,后来就上网查了查资料解决了。其实非常简单,只需要打开工具栏中的Configuration(就是这个小扳手 图片3.png ,额第一次传图片,太大了。。。),将字体改为中国简体(就是Chinee GB2312(Simplilied)这个标号)就好了


       其实,学到这里,我觉得我不再像以前一样那么迷茫不知道干什么好了,知道以后的路该怎么走了。我。。。算是真正入门了吧?不过以后我还会将遇到的难题和收获通过帖子发出来,一是为了丰富自己,而是帮助他人。(呜哈哈,我真伟大,滑稽)
       前两天,我的同学们都在做电磁寻迹小车,虽然我现在只会控制红外传感器(但是我知道我就是个小天才嘿嘿),我想也该学学相关的知识了。
       说句实话,感谢正点原子,自从高考完后,我就一直在守成,老气横秋,活在自己的精神世界中,做什么都是给别人看,要的只是几句夸赞,被他人远远超过而不自知,不过自从写帖子后,我重新找到了奋斗的目标,也认清了自己的虚伪,与其在现实中为了面子做样子,不如静下心和同道中人学做事。我也终于醒悟,我只是20岁,我的巅峰不止于此!




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
 楼主| 发表于 2019-8-30 10:50:11
但是我想问一下,虽然理论上我懂了,可实际操作上,我把main函数里的延时改了没有什么用,反而是将按键读取函数里的延时改了才出现了按着按键连续闪烁的现象,这是为什么?想不通想不通哇
支持 反对

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
 楼主| 发表于 2019-8-30 11:07:02
我懂了,已进行修改
支持 反对

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
 楼主| 发表于 2019-8-30 20:50:55 | 显示全部楼层
本帖最后由 清夏 于 2019-8-30 21:01 编辑

我说呢。。。原来一直是当成草稿保存起来了。。。
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2019-11-8
在线时间
12 小时
发表于 2019-11-27 15:09:22 | 显示全部楼层
你太厉害了 我是你的粉丝
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2019-11-8
在线时间
12 小时
发表于 2019-11-27 15:25:49 | 显示全部楼层
我还是有个问题不明白 在我执行一次keyscan之后keyup等于0了 那么函数就无效了那我岂不是只能按一次啊 以后都不能触发keyscan这个函数了 我代码理解的不太清楚可以指点一下吗
回复 支持 反对

使用道具 举报

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
 楼主| 发表于 2019-11-28 12:44:36 | 显示全部楼层
里奥 发表于 2019-11-27 15:25
我还是有个问题不明白 在我执行一次keyscan之后keyup等于0了 那么函数就无效了那我岂不是只能按一次啊 以后 ...

谢谢,这个函数是在死循环的(你要看一下main函数),只要执行完一次还会重新来一遍,就又会回到一开始的mode(至于static的作用帖子里有哦),当你让mode=0时,他就不会让keyup=1,也就是说你说的函数从现在就无效了,就像正点视频里说的按一次灯就只亮或灭一次,当你让mode=1时,他就会让keyup=1,这样就能不断地执行函数,就会出现按着键不松开就会看到灯不停的亮灭的状态了,希望能解决你的疑惑
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2019-11-8
在线时间
12 小时
发表于 2019-11-28 23:07:28 | 显示全部楼层
清夏 发表于 2019-11-28 12:44
谢谢,这个函数是在死循环的(你要看一下main函数),只要执行完一次还会重新来一遍,就又会回到一开始的 ...

我想明白了感谢你
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2019-11-14
在线时间
14 小时
发表于 2019-12-12 20:42:48 | 显示全部楼层
写得太好了!
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2020-6-23
在线时间
51 小时
发表于 2020-7-15 15:01:36 | 显示全部楼层
谢谢兄弟,正发愁呢。
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2020-6-23
在线时间
51 小时
发表于 2020-7-15 15:39:45 | 显示全部楼层
为什么有的函数需要u8,有的只需要VOID
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2021-4-13
在线时间
7 小时
发表于 2021-4-17 20:13:34 | 显示全部楼层
刚刚在学按键输入实验的时候,有一行代码不明白:if(mode)key_up=1; 就这个,把我搞蒙了,看了你的文章,代码分行写的,瞬间明白了,哈哈哈,谢谢分享
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-27 23:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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