开发者学堂课程【HaaS 物联网应用开发课程:3_6_按键与跑马灯实验】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/801/detail/13832
3_6_按键与跑马灯实验
内容介绍
一、实验设计
二、软件流程图
三、实验演示环节
一、实验设计
本节课程的主题是按键与跑马灯实验。
在本节课程中,课程安排将主要从实验设计、软件流程图以及实验演示环节三个部分进行展开,首先来看一下实验目的,这节课主要是利用前面学到的定时器中断以及 GPIO 的 API 在 Haas EDU K1 上实现跑马灯的功能,主要功能定义有两点,第一利用定时器以及 LED 实现不同频率的跑马灯效果,第二检测 Haas EDU 上的按键事件、检测到按键事件之后就调整跑马灯的频率。
实验的硬件框图可以参考下面这张图,实验中会用到三个 LED ,分别是l1l2l3,它们分别接到了 Haas 1000的p4_4、p4_3以及 p4_2这三个 GPO 上,可以通过 Haas 的API来拉高或者拉低这些 GPO,从而来控制 LED 微机的亮灭,按键则是接到 gp p2-7上,通过 gp iQOO 相关的 API 将 pp2-7设置成中断模式,在检测到 p2-7按键之后修改定时器的到期时间,在定时期到期处理函数中循环控制 LED 的亮面来达到跑马灯的效果。
二、软件流程图
接下来看一下软件流程图,先看一下中间的就是主程序的逻辑,那系统启动之后先对 led 进行初始化,让所有的 LED 闪烁一次后处于熄灭的状态,然后接下来会对定时器进行初始化,然后并把电视机开启,然后第三步是对按键中断进行初始化,也就是说把 gpop2-7设置成中断模式,之后主程序就在这个地方循环等待 gp l 按键被按下的事件,那当 GPO 按下之后会见到按键中断处理程序中,在这个程序中它会首先记录按键被按下的次数,然后接下来就发一个信号给主程序,通知主程序按键按下的时间,在主程序收到按键被按下的事件之后,它会根据按键按下的次数来调整定时器的定时周期,调整完定时器的定时周期之后会重新启动定时器,那在定时器到期之后它主要是对定时器到期事件基数进行加一,并且循环去控制 LED 的亮面,就是说关掉当前的 LED ,然后让下一个 LED 亮起,然后来达到跑马灯的效果。
三、实验演示
接下来给大家讲解一下实验的代码以及观看一下实验的一个效果,现在这个环境已经通过 ssh 的方式登陆到后台了,那这个时候我在 workspace 的 experiment 的下边用 project 这个指令创建一个 marquee_led 的这么一个工程,这个工程是在 haaseeduk1创建的,然后它是以 hello demo 为模板的创建,然后创建在当前下边,名字叫 marquee_led ,因为之前在准备这个实验的时候,已经创建了这个工程的,这边就不再重复创建了。
那先进到 marquee_led 这个目录下边,然后因为这边的代码会比较多一些,所以这次通过阿里 studio 的方式来查看代码,把刚刚的路径拷贝一下,然后把路径贴到这个 folder=的后面,这样 studio就会打开 marquee_led这个工程,它这边已经打开完成了,来看一下它现在里面有几个源文件,首先 APP demo 这个之前有说过,它就是还可以的还是定义在这个文件里面的,那 LED 相关的测试代码都是在这个 markled.c 里边的,先来看一下 markled.c 里面的一个实现是怎么样的?
先拉到最下边,最下边是这个函数的一个入口,它就是 mark LED entry,这就是主程序的一个入口了。在主程序启动之后,首先会创建一个 samfor ,这个是用来做什么呢?
它就是用来接收按键按下来这个事件的,那等下也会看一下这个 samfor 怎么样使用的?
首先创建一个 samfor ,然后对 LED 进行初始化,然后是对按键进行初始化,然后后边会对 timer 进行初始化,timer 初始化之后会启动这个,最后就是在一个 while 循环中呼叫这个函数来等待在这个 key 的一个事件,那这个就是刚刚创建的那个 timer,在这个地方传入的参数是 as wait forever 。
意思是说不需要超时,只要没有事件就一直在这里等待,然后这个函数返回之后,如果返回值是零就代表接收到了一个事件,如果返回非零的值代表函数出现异常,这样就可以直接退出。如果等待一个可以被按下的事件之后,先把当前的 tama 给停掉,然后呼叫 aos timer 这个函数,调整 timer 的一个到期时间,到期时间是在这个变量里边来定义的,定义了几种50毫秒、100毫秒、200毫秒、400毫秒和800mm。
也就是说假如当前 timer的周期是50毫秒,我们按键一次就会调成100毫秒,然后再安排一次就会调成200毫秒,然后最后调到800毫秒之后,如果再按下一次就会跳回到50毫秒,调整完 timer 的一个周期之后,然后再次呼叫aos_timer_ start 然后来重启这个,然后分别来看一下 LED 初始化里边是怎么样去做的?然后 LED 初始化的参数是 marquee 的一个数组,这个数组里面就定义了三个 LED ,第一个LED 就是刚刚看到的lp4-4,第二个就是 l two就是 p4-3,第三个是l3p4-2,那接下来看一下 LED 的初始化里面是怎么样去做的?
它里边也比较简单,它首先一个过循环,然后来循环初始化传进来的 led 的这个结构体,首先呼叫hell gp led 对GPS进行初始化,设置上 gp Pro 的模式,然后通过 help output,然后把LED 点亮,之后 sleep 一秒,然后再通过 hell gp output 把 LED 熄灭,这样 marquee _led 初始化就完成了。
接下来看一下k的初始化,先来看一下 k 传递的参数是哪一个?Marquee_key 其实也是一个 GPODAO 的一个结构体,然后它里边的 port ID 传的是EDO Ky,它定义到 了p2-7,也就是它是连接到 Haas edo 上 ky 这个按键,看一下它的初始化函数,在初始化函数中将 k 的设置成 IQ 模式,然后再呼叫 hell GPS ,这样就会把 p2-7设置成中断模式,然后再将这个 K1 上的中断模式给打开,然后触发的模式是 falling edge ,也就是说 K1 这根片上发生一个从高电频向低电频的跳变的时候,然后触发这个中断。让看一下中断处理程序里边,它是怎么去写的?中断处理程序里边首先会对 k one press counter 这个变量进行加一,它记录的就是 k one 按键被按下的次数,然后会去呼叫像k1发一个消息,刚刚看到主程序其实就是在等待这个世界,这个地方就会收到这个事件,然后执行后面的逻辑。Marquee_key 的初始化看完了,再来看一下 Marquee_timer 的初始化,Marquee_timer 的初始化就是用 aos_timer_new 来创建一个自动执行的 timer,然后设置的超时时间是500毫秒,然后会周期性的自动运行,它设置的超时处理函数是 marquee timeout ,那在这里边看一下它做了什么事情,首先在这里边会去熄灭当前的这个 LED ,这个 LED 是刚刚定义 led 里边的一个,那是控制哪个LED呢?
它是通过 int 这个变量来控制,然后它是在每次 timer 到期之后都会++,然后超过 marquee_led 数组的大小之后就会返回成零,也就是说会循环控制l1l2l3。首先它是熄灭当前的 LED,然后就是 index++,然后再打开下一个 LED ,那这样整个程序的一个处理流程就看完了,那在这个时候呢需要在一个合适的地方去呼叫 marquee_led_entry ,那你一定想到了需要到 application demo 里面的 application 算函数里面来呼叫 marquee_led_entry ,它确实也是这样做的,那为了不让输出太多的日志,所以把这个输出关掉。
刚刚就把按键以及跑马灯的一个代码讲解了一遍,接下来就来编译一下这个工程,然后看一下它的一个运行效果,首先来选择一下工程,大家可以看到这个地方其实是点不动的,因为当前打开的这个目录里面就只有这么一个工程,它没有其他的工程可以选择,所以这个地方是点不动的,它默认就是 mark led at haas edo k one 这个工程,那只需要点编译就可以了,它现在已经开始编译了。
看到现在这个工程会编译所需要的这些组件,这个地方提示 mark led at haas edo k one 编译完成了,所以点击闪电符号对板子进行一个烧肉的动作,这个地方提示烧肉完成了,来看一下它的运行的一个效果,先来看一下它的输出日志,来看一下 dev 下面的 tty,然后可以看到它现在在循环打印 marquee timeout happens ,这个就是刚刚在代码里边打印出来的日志,来看一下 marquee timeout happens 进来以后第一下就是先打一下这个日志,刚刚代码里边初始化 timer 的时候,其实是设定的是一个500毫秒的定时周期,所以大概是一秒钟两次,现在再按一下按键。
然后来看一下调整一下定时器的频率,来看一下它的一个闪烁效果,这个地方首先会打印 K1 detected, k1_press_counter=1 ,那再来看一下代码,这个就是 k1 在 handle 里面来设定的,就是在这个地方 marquee_k1_handler k 里边进来以后先打印一句话, k1_press_counter 是多少?然后接下来打印了一句话是什么呢?
它就是 change timer’s period too 200 ms ,那这个是在哪里打印的呢?
我们来看一下还是在这里打印的,因为刚刚有提到说 K1的按键被按下之后,它会发一个 signal 给主程序,主程序收到这个事件之后,它就会去调整 timer 的到期时间,然后看到收到这个事件之后,然后去调整 timer 的到期时间,然后再把打印 change timer’s period too 200 ms 这样,再来看一下它闪烁的快慢,这样闪烁的更慢一些了,400毫秒的。
然后这样就更慢了800毫秒,这样就非常快了是100毫秒。这样今天的实验也是就到这里。