木子剑
生命不熄,学习不止!

以InstantContiki3.0环境的cc2538dk为例进行解剥原理》》》》

首先找到3.0\platform\cc2538dk里面有一个contiki-main.c一般不用更改,就是我们通常的main.c主函数,一切将从这里开始。

特别注意的是,3.0\cpu\cc2538这里面所有文件不用更改,因为都是作者按照芯片手册和OS制定好的。

在3.0\core\lib的sensors.c,  在3.0\core\dev的button-sensor.c不用更改, 是系统的文件改什么改。

 

哈哈,要更改的内容是,3.0\platform\cc2538dk里面的contiki-main.c必要时更改,我们重点看一下这些内容

 1 /*---------------------------------------------------------------------------*/
 2 /**
 3  * \brief Main routine for the cc2538dk platform
 4  */
 5 int
 6 main(void)
 7 {
 8   nvic_init();
 9   ioc_init();
10   sys_ctrl_init();
11   clock_init();
12   lpm_init();
13   rtimer_init();
14   gpio_init();
15 
16   leds_init();
17   fade(LEDS_YELLOW);
18 
19   process_init();
20 
21   watchdog_init();
22   button_sensor_init();

这个是平台的初始化部份,很重要!你看button_sensor_init()出现了。

 

在\3.0\platform\cc2538dk\dev里面有button-sensor.c,这是我们要更改的,和3.0\core\dev的button-sensor.c名字一样,

这种搞法在IAR里面,肯定会报文件重名错误,看来linux很自由  也很不严瑾。移植到WINDOWS平台IAR,注定要头大了!!!

  1 /*
  2  * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/
  3  * All rights reserved.
  4  *
  5  * Redistribution and use in source and binary forms, with or without
  6  * modification, are permitted provided that the following conditions
  7  * are met:
  8  * 1. Redistributions of source code must retain the above copyright
  9  *    notice, this list of conditions and the following disclaimer.
 10  * 2. Redistributions in binary form must reproduce the above copyright
 11  *    notice, this list of conditions and the following disclaimer in the
 12  *    documentation and/or other materials provided with the distribution.
 13  *
 14  * 3. Neither the name of the copyright holder nor the names of its
 15  *    contributors may be used to endorse or promote products derived
 16  *    from this software without specific prior written permission.
 17  *
 18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 29  * OF THE POSSIBILITY OF SUCH DAMAGE.
 30  */
 31 /**
 32  * \addtogroup cc2538dk-button-sensor
 33  * @{
 34  *
 35  * \file
 36  *  Driver for the SmartRF06EB buttons
 37  */
 38 #include "contiki.h"
 39 #include "dev/nvic.h"
 40 #include "dev/ioc.h"
 41 #include "dev/gpio.h"
 42 #include "dev/button-sensor.h"
 43 #include "sys/timer.h"
 44 
 45 #include <stdint.h>
 46 #include <string.h>
 47 
 48 #define BUTTON_LEFT_PORT_BASE    GPIO_PORT_TO_BASE(BUTTON_LEFT_PORT)
 49 #define BUTTON_LEFT_PIN_MASK     GPIO_PIN_MASK(BUTTON_LEFT_PIN)
 50 
 51 
 52 /*---------------------------------------------------------------------------*/
 53 static struct timer debouncetimer;//*这个结构用于声明一个计时器。
 54                                   //必须设置计时器在使用timer_set()之前。                                  
 55 /*---------------------------------------------------------------------------*/
 56 /**
 57  * \brief Common initialiser for all buttons
 58  * \param port_base GPIO port's register offset
 59  * \param pin_mask Pin mask corresponding to the button's pin
 60  */
 61 static void
 62 config(uint32_t port_base, uint32_t pin_mask)
 63 {
 64   /* Software controlled */
 65   GPIO_SOFTWARE_CONTROL(port_base, pin_mask);
 66 
 67   /* Set pin to input */
 68   GPIO_SET_INPUT(port_base, pin_mask);
 69 
 70   /* Enable edge detection */
 71   GPIO_DETECT_EDGE(port_base, pin_mask);
 72 
 73   /* Single edge */
 74   GPIO_TRIGGER_SINGLE_EDGE(port_base, pin_mask);
 75 
 76   /* Trigger interrupt on Falling edge */
 77   GPIO_DETECT_RISING(port_base, pin_mask);
 78 
 79   GPIO_ENABLE_INTERRUPT(port_base, pin_mask);
 80 }
 81 /*---------------------------------------------------------------------------*/
 82 /**
 83  * \brief Callback registered with the GPIO module. Gets fired with a button
 84  * port/pin generates an interrupt
 85  * \param port The port number that generated the interrupt
 86  * \param pin The pin number that generated the interrupt. This is the pin
 87  * absolute number (i.e. 0, 1, ..., 7), not a mask
 88  */
 89 static void
 90 btn_callback(uint8_t port, uint8_t pin)
 91 {
 92   if(!timer_expired(&debouncetimer)) {
 93     return;//检查计时器是否过期并返回。
 94   }
 95 
 96   //这个函数用于设置将来某个时间的计时器。
 97   //计时器过期后,函数timer_expired()的值将为true。
 98   timer_set(&debouncetimer, CLOCK_SECOND / 8);
 99   
100   if((port == BUTTON_LEFT_PORT) && (pin == BUTTON_LEFT_PIN)) { //先确认按键
101     sensors_changed(&button_left_sensor); //再启动对应的按键传感器事件
102 
103   } 
104 }
105 
106 /*---------------------------------------------------------------------------*/
107 /**
108  * \brief Init function for the left button.
109  *
110  * Parameters are ignored. They have been included because the prototype is
111  * dictated by the core sensor api. The return value is also not required by
112  * the API but otherwise ignored.
113  *
114  * \param type ignored
115  * \param value ignored
116  * \return ignored
117  */
118 static int
119 config_left(int type, int value)
120 {
121   config(BUTTON_LEFT_PORT_BASE, BUTTON_LEFT_PIN_MASK);
122 
123   ioc_set_over(BUTTON_LEFT_PORT, BUTTON_LEFT_PIN, IOC_OVERRIDE_PUE);
124 
125   NVIC_EnableIRQ(BUTTON_LEFT_VECTOR);
126 
127   gpio_register_callback(btn_callback, BUTTON_LEFT_PORT, BUTTON_LEFT_PIN);
128   return 1;
129 }
130 //以上是SENSORS_SENSOR的参数,先定义再导入
131 
132 
133 /*---------------------------------------------------------------------------*/
134 void//通用初始化所有SmartRF按钮
135 button_sensor_init()
136 {
137   timer_set(&debouncetimer, 0);//设置计时器
138 }
139 /*---------------------------------------------------------------------------*/
140 SENSORS_SENSOR(button_left_sensor, BUTTON_SENSOR, NULL, config_left, NULL);
141 
142 SENSORS(&button_left_sensor);
143 /** @} */

 

 

我进行测试的,只有一个left按键,button_sensor_init()SENSORS_SENSOR,SENSORS这三个是重点(为什么?),继续分析一下发现。

重中之重是SENSORS_SENSOR的config_left这个参数,因为由它最终poll一个process_poll(&sensors_process)传感器事件,

 1 /*---------------------------------------------------------------------------*/
 2 /**
 3  * \brief Callback registered with the GPIO module. Gets fired with a button
 4  * port/pin generates an interrupt
 5  * \param port The port number that generated the interrupt
 6  * \param pin The pin number that generated the interrupt. This is the pin
 7  * absolute number (i.e. 0, 1, ..., 7), not a mask
 8  */
 9 static void
10 btn_callback(uint8_t port, uint8_t pin)
11 {
12   if(!timer_expired(&debouncetimer)) {
13     return;//检查计时器是否过期并返回。
14   }
15 
16   //这个函数用于设置将来某个时间的计时器。
17   //计时器过期后,函数timer_expired()的值将为true。
18   timer_set(&debouncetimer, CLOCK_SECOND / 8);
19   
20   if((port == BUTTON_LEFT_PORT) && (pin == BUTTON_LEFT_PIN)) { //先确认按键
21     sensors_changed(&button_left_sensor); //再启动对应的按键传感器事件
22 
23   } 
24 }

 

 

在button_sensor_init()中,只是设定了一个定时器,不是很明白作者的用意,CLOCK_SECOND就是1000ms,1000/8=125ms。

是按键去抖处理   还是按键超时处理,前面先判断,有可能会return返回。

最后更改好examples\cc2538dk的cc2538-demo.c的代码,进行测试发现成功了:

 

 1 #include "contiki.h"
 2 #include "dev/cc2538-sensors.h"
 3 #include "dev/button-sensor.h"
 4 #include "dev/leds.h"
 5 
 6 
 7 #include <stdio.h>
 8 #include <stdint.h>
 9 
10 /*---------------------------------------------------------------------------*/
11 PROCESS(cc2538_demo_process, "cc2538 demo process");
12 AUTOSTART_PROCESSES(&cc2538_demo_process);
13 
14 /*---------------------------------------------------------------------------*/
15 PROCESS_THREAD(cc2538_demo_process, ev, data)
16 {
17   PROCESS_BEGIN();
18   leds_on(LEDS_ALL);//ON就是OFF,硬件反了
19   while(1) {
20 
21     PROCESS_YIELD();
22     if(ev == sensors_event) {//是传感器事件,并且是按键left产生的,可执行闪灯功能
23         if(data == &button_left_sensor)leds_toggle(LEDS_RED);       
24     }
25   }
26   PROCESS_END();
27 }

 使用InstantContiki3.0,进make,把*.HEX烧进cc2538芯片里面去,按一次KEY=PC4.    灯就亮 LED=PC0,功能测试正常

 这一次学习,是在原来的3.0\examples\cc2538dk的cc2538-demo.c进行测试的,经过这次记录加深并理解sensor这方面的应用。

 

posted on 2020-07-06 08:57  木子剑  阅读(538)  评论(0)    收藏  举报