GPIO外设的配置流程
我们想要将CC1310芯片的某个引脚配置给GPIO外设使用,那么就必须确保芯片引脚与GPIO外设索引的引脚有正确的对应关系。 GPIO引脚配置的流程大致如下: 它主要分为对应引脚的初始化和对应GPIO外设的初始化。
引脚初始化
首先我们想要将CC1310的某个引脚作为GPIO引脚使用,我们必须要初始化该引脚 引脚的初始化主要可分为上图中的三个步骤。
引脚的声明
我这里说的声明并非像C语言的变量声明那样,而是CC1310的例程中,对每个引脚的物理地址都做了预定义,这个预定义我们可以再CC1310_LAUNCHPAD.h文件中看到。
注意这一步并非必须的,这样做只是方便了我们在编写程序时可以更加方便的理解程序,并且增强了代码整体的可移植性。但是如果我们使用这种引脚预定义的声明方式,那么我们必须要保证我们预定义的名称指向了我们想用的IO引脚的物理地址。
如下图所示: 这里再废话两句,为什么要添加引脚的预定义: 如果我想使用一个红色led灯作为CC1310工作状态的指示灯,并选择使用IO_0作为一个led灯的输出引脚,那么我将IO_0的物理地址预定义为CC1310_LAUNCHPAD_PIN_RLED,这样我们在编写应用程序时想要改变红色LED灯引脚电平时,就可以直接调用预定义的名称,这样会更加方便我们理解该引脚的作用。如果我们之后想用IO_6作为红色led灯的输出引脚,那么只用在这里把IO_0改为IO_6便可以了,而不需要修改我们编写的应用程序,这便增加了应用程序代码整体的可移植性。 并且如果之后想要之后再添加一个绿色led灯,来指示CC1310的另外一些工作的状态,我这里也可以提前预定义出来,并不设定实际的引脚物理地址,这样方便我们后续继续扩充程序功能。
添加引脚声明
我们在预定义了我们想要使用的引脚后,便可以在引脚初始化时使用它了。
但在引脚初始化之前,我们必须配置其相应的属性,这是在为引脚初始化时,将引脚和对应属性一起写入对应寄存器做准备。 我们可以在CC1310_LAUNCHPAD.c文件中找到下面这段代码:
#include <ti/drivers/PIN.h>
#include <ti/drivers/pin/PINCC26XX.h>
const PIN_Config BoardGpioInitTable[] = {
CC1310_LAUNCHXL_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
CC1310_LAUNCHXL_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
CC1310_LAUNCHXL_PIN_BTN1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,
CC1310_LAUNCHXL_PIN_BTN2 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS,
CC1310_LAUNCHXL_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
CC1310_LAUNCHXL_UART_RX | PIN_INPUT_EN | PIN_PULLDOWN,
CC1310_LAUNCHXL_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
CC1310_LAUNCHXL_SPI0_MOSI | PIN_INPUT_EN | PIN_PULLDOWN,
CC1310_LAUNCHXL_SPI0_MISO | PIN_INPUT_EN | PIN_PULLDOWN,
CC1310_LAUNCHXL_SPI0_CLK | PIN_INPUT_EN | PIN_PULLDOWN,
PIN_TERMINATE
};
const PINCC26XX_HWAttrs PINCC26XX_hwAttrs = {
.intPriority = ~0,
.swiPriority = 0
};
这段代码中的PIN_Config表单便是对程序中所有用到的所有引脚进行了属性配置。 如果我们想要新添加了某些引脚的预定义,便需要在改属性配置表中添加要使用的引脚名称,并为其加上我们想要其实现的引脚属性。
此外,该部分代码还规定了这些引脚产生的硬件和软件中断都是优先级最低的中断。
引脚初始化
在将要使用的引脚名称添加到引脚配置表后,便可以使用此表进行引脚的初始化过程了。
引脚的初始化时调用了PIN_init()函数完成的,在TI的例程中,该函数是在main函数中,调用Board_init函数时实现的。
我们点进去Board_init()函数,便可以发现该函数。
void CC1310_LAUNCHXL_initGeneral(void)
{
Power_init();
if (PIN_init(BoardGpioInitTable) != PIN_SUCCESS) {
while (1);
}
}
void Board_init(void)
{
CC1310_LAUNCHXL_initGeneral();
}
向PIN_init()函数中传入的PIN_Config表中的引脚都会被配置为GPIO引脚,并具有添加的引脚属性。 没有在PIN_Config表中的引脚都会被配置为输入输出都失能的状态。
注意:在同一个应用程序中,PIN_init()不可以被多次调用。
在上述的PIN初始化完成后,我们已经可以使用driver/PIN.h文件中提供的API使用这些引脚了,如果我们想要直接使用某些引脚的话可以在调用PIN_open()函数,但是在有操作系统的应用程序中并不推荐这样做,因为这并非线程安全的。
GPIO初始化
上面PIN_init函数会将引脚配置为GPIO可用的状态,但是目前这些引脚还没有被配置到GPIO外设中,我们若想要使用GPIO外设来配置或控制某些引脚,那么必须要再进行GPIO外设的初始化。
为GPIO外设添加引脚配置
下面有关GPIO配置的操作都是在CC1310_LAUNCHPAD.c文件中完成的。 有关GPIO的配置信息,都是通过GPIO_Config结构体来保存的,其实例化代码如下:
const GPIOCC26XX_Config GPIOCC26XX_config = {
.pinConfigs = (GPIO_PinConfig *)gpioPinConfigs,
.callbacks = (GPIO_CallbackFxn *)gpioCallbackFunctions,
.numberOfPinConfigs = CC1310_LAUNCHXL_GPIOCOUNT,
.numberOfCallbacks = sizeof(gpioCallbackFunctions)/sizeof(GPIO_CallbackFxn),
.intPriority = (~0)
};
在该结构体中保存了GPIO可以控制的引脚、回调、中断等信息。 我们要做的便是在对GPIO_Config结构体实话化时,配置我们想要使用的引脚、回调信息。
在gpioPinConfig数组中添加要使用的引脚
我们想要使用GPIO控制红色LED灯的电平变化,则将其添加到gpioPinConfig数组中,并加上配置信息,其他预留引脚定义配置也可以添加到数组中,配置信息为NOT_CONFIG。
GPIO_PinConfig gpioPinConfigs[] = {
GPIOCC26XX_DIO_13 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_14 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_15 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_07 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_00 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH ,
GPIOCC26XX_DIO_30 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_20 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_21 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_24 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_22 | GPIO_DO_NOT_CONFIG,
GPIOCC26XX_DIO_23 | GPIO_DO_NOT_CONFIG,
};
在gpioCallbackFunctions数组中添加要使用的回调函数
我们可以自定义某个引脚的回调函数,但该回调函数的指针需要传入GPIO_Config结构体中,在GPIO外设中注册回调函数的对应中断。
GPIO_CallbackFxn gpioCallbackFunctions[] = {
NULL,
NULL,
NULL,
NULL,
};
添加对应引脚的索引号
我们在上面在gpioPinConfig数组中添加了需要使用的引脚的名称和配置信息,但我们控制某个引脚,也就是需要索引该数组中的某个元素,则需要直到每个引脚对应的索引号,因此我们必须定义与该数组中每个引脚一一对应的索引信息。
关于引脚索引信息的定义,我们是在CC1310_LAUNCHPAD.h文件中实现的。 其代码如下:
typedef enum CC1310_LAUNCHXL_GPIOName {
CC1310_LAUNCHXL_GPIO_S1 = 0,
CC1310_LAUNCHXL_GPIO_S2,
CC1310_LAUNCHXL_SPI_MASTER_READY,
CC1310_LAUNCHXL_SPI_SLAVE_READY,
CC1310_LAUNCHXL_GPIO_LED_GREEN,
CC1310_LAUNCHXL_GPIO_LED_RED,
CC1310_LAUNCHXL_GPIO_TMP116_EN,
CC1310_LAUNCHXL_GPIO_SPI_FLASH_CS,
CC1310_LAUNCHXL_SDSPI_CS,
CC1310_LAUNCHXL_GPIO_LCD_CS,
CC1310_LAUNCHXL_GPIO_LCD_POWER,
CC1310_LAUNCHXL_GPIO_LCD_ENABLE,
CC1310_LAUNCHXL_GPIOCOUNT
} CC1310_LAUNCHXL_GPIOName;
需要注意的是,我们调用的引脚的索引号必须与该引脚存在于gpioPinConfig数组中的位置保持一致。
初始化GPIO外设
在配置完gpioPIN_Table后,便可以调用GPIO_init()函数来进行GPIO外设的初始化了。
GPIO_init()函数会将我们配置的gpioPIN_Table和中断表中的引脚名称,按照其对应的索引号一一存入到GPIO外设的相应寄存器中。
在调用了GPIO_init()函数后,便完成了GPIO的初始化工作,之后便可以调用GPIO.h文件中的API来通过GPIO配置或控制相应的引脚了。
GPIO使用注意事项
(未完待续)~
|