以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这方面的应用。
浙公网安备 33010602011771号