Contiki中通过一些简化的操作一样操作GPIO,具备输入和输出状态监测等函数,通过几个常用函数即可形成一个使用方便的GPIO操作体系来操作其他设备或者模拟接口协议。又因为使用的是c语言,兼容性好,可以移植一些常用的元器件驱动程序。
cc2538有引出一部分接口,按板型设计,原本的占用等等,引出的接口又不等化的分为0-7位。
包含头文件:
#include "contiki.h"
#include "cfs/cfs.h"
1. 初始化接口
在使用GPIO之前需要先初始化指定的接口,通过两个函数 GPIO_SOFTWARE_CONTROL和GPIO_SET_INPUT,即可完成初始化
在这里,基于官方的函数,为了简化操作流程和便于整理代码,我将函数进行二次模块化。
Port: PA:0,PB:1,PC:2,PD:3
例如我们要设置的是PB4,那么函数就是
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4));
GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4));
void pinInit(int port,int bit,int mode)
{
if(mode == OUTPUT)
{
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit));
GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit));
}
else if(mode == INPUT)
{
GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit));
GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit));
}
}
2. 输出操作
当设置为OUTPUT时,操作电平高低使用GPIO_SET_PIN和GPIO_CLR_PIN这两个函数即可完成
void pinMode(int port ,int bit,int mode)
{
if(mode == HIGH)
{
GPIO_SET_PIN(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4)); //HIGH
}
else if(mode == LOW)
{
GPIO_CLR_PIN(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4)); //LOW
}
}
3. 板载LED灯闪烁与GPIO
这里用到了自带的一个软延时函数clock_delay_usec,单位为us
void ms_delay(int ms)
{
int i,j;
for(i=0;i
for(j=0;j<5;j++)
clock_delay_usec(200);
}
使用回环结构成倍叠加形成ms级延时便于一般使用
当然这种软延时是不准确的,会随着叠加而放大误差。
大多数情况还是使用ETimer
主要线程GPIO_Control,开启LED灯和设置高电平延时1秒,下载到板块上可看到指定LED灯闪烁, 连接示波器到设定的接口可以看到方波波形。
PROCESS_THREAD(GPIO_Control,ev,data)
{
static struct etimer timer;
pinInit(1,4,OUTPUT);
while(1)
{
pinMode(1,4,HIGH); //HIGH
leds_on(4);
ms_delay(500);
pinMode(1,4,LOW) ;//low
leds_off(4);
ms_delay(500);
}
}
GPIOtest.c:
//Reference:https://sourceforge.net/p/contiki/mailman/message/33192152/ //Reference:https://github.com/contiki-os/contiki/wiki/Timers #include "contiki.h" #include "cfs/cfs.h" //#include "sys/etimer.h" //#include "dev/cc2538-sensors.h" //#include "dev/button-sensor.h" //#include "dev/sys-ctrl.h" #define INPUT 1 #define OUTPUT 2 #define HIGH 1 #define LOW 0 int gpioOut = 0; void pinMode(int port,int bit,int mode); void pinMode(int port ,int bit,int mode); void ms_delay(int ms); PROCESS(GPIO_Control, "Test multithread" ); AUTOSTART_PROCESSES(&GPIO_Control); PROCESS_THREAD(GPIO_Control,ev,data) { static struct etimer timer; pinInit(1,4,OUTPUT); while(1) { pinMode(1,4,HIGH); //HIGH leds_on(4); ms_delay(500); pinMode(1,4,LOW) ;//low leds_off(4); ms_delay(500); } } void pinInit(int port,int bit,int mode) { if(mode == OUTPUT) { GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit)); GPIO_SET_OUTPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit)); } else if(mode == INPUT) { GPIO_SOFTWARE_CONTROL(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit)); GPIO_SET_INPUT(GPIO_PORT_TO_BASE(port), GPIO_PIN_MASK(bit)); } } void pinMode(int port ,int bit,int mode) { if(mode == HIGH) { GPIO_SET_PIN(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4)); //HIGH } else if(mode == LOW) { GPIO_CLR_PIN(GPIO_PORT_TO_BASE(1), GPIO_PIN_MASK(4)); //low } } void ms_delay(int ms) { int i,j; for(i=0;i for(j=0;j<5;j++) clock_delay_usec(200); }
Makefile:
CONTIKI_PROJECT = GPIOtest all: $(CONTIKI_PROJECT) SMALL=0 CONTIKI = ../../.. include $(CONTIKI)/Makefile.include
更多详细可以参考:http://www.eistec.se/docs/contiki/a02257.html