首先理解CC3220 SDK源码的架构,下面是目录结构:
一共这五个文件夹,展开后:
/*!* @brief GPIO pin configuration settings** The upper 16 bits of the 32 bit PinConfig is reserved* for pin configuration settings.** The lower 16 bits are reserved for device-specific* port/pin identifications*/
typedef uint32_t GPIO_PinConfig;
一个引脚的名称、分组、GPIO配置信息都被包含在了这个32位整数GPIO_PinConfig里面了。它的高16位用于存放GPIO配置信息,而低16位用于存放引脚标识。下面分别讲解:
1、引脚标识
打开 【drivers】-->【gpio】下的GPIOCC32XX.h文件,找到下述代码:
//引脚为空
#define GPIOCC32XX_EMPTY_PIN 0x0000
//GPIO A0 port下的8个引脚
#define GPIOCC32XX_GPIO_00 0x0001
#define GPIOCC32XX_GPIO_01 0x0002
#define GPIOCC32XX_GPIO_02 0x0004
#define GPIOCC32XX_GPIO_03 0x0008
#define GPIOCC32XX_GPIO_04 0x0010
#define GPIOCC32XX_GPIO_05 0x0020
#define GPIOCC32XX_GPIO_06 0x0040
#define GPIOCC32XX_GPIO_07 0x0080
//GPIO A1 port下的8个引脚
#define GPIOCC32XX_GPIO_08 0x0101
#define GPIOCC32XX_GPIO_09 0x0102
#define GPIOCC32XX_GPIO_10 0x0104
#define GPIOCC32XX_GPIO_11 0x0108
#define GPIOCC32XX_GPIO_12 0x0110
#define GPIOCC32XX_GPIO_13 0x0120
#define GPIOCC32XX_GPIO_14 0x0140
#define GPIOCC32XX_GPIO_15 0x0180
//GPIO A2 port下的8个引脚
#define GPIOCC32XX_GPIO_16 0x0201
#define GPIOCC32XX_GPIO_17 0x0202
#define GPIOCC32XX_GPIO_18 0x0204
#define GPIOCC32XX_GPIO_19 0x0208
#define GPIOCC32XX_GPIO_20 0x0210
#define GPIOCC32XX_GPIO_21 0x0220
#define GPIOCC32XX_GPIO_22 0x0240
#define GPIOCC32XX_GPIO_23 0x0280
//GPIO A3 port下的8个引脚
#define GPIOCC32XX_GPIO_24 0x0301
#define GPIOCC32XX_GPIO_25 0x0302
#define GPIOCC32XX_GPIO_26 0x0304
#define GPIOCC32XX_GPIO_27 0x0308
#define GPIOCC32XX_GPIO_28 0x0310
#define GPIOCC32XX_GPIO_29 0x0320
#define GPIOCC32XX_GPIO_30 0x0340
#define GPIOCC32XX_GPIO_31 0x0380
可以看到32个GPIO引脚都对应有一个数字,这个数字的低8位中的每一位正好表示了这个引脚的编号。第9、10位则表示引脚所在端口。 GPIO_PinConfig的低16位存放的就是此信息。
/*!* Internally used configuration bit access macros.*/
#define GPIO_CFG_IO_MASK 0x00ff0000
#define GPIO_CFG_IO_LSB 16
#define GPIO_CFG_OUT_TYPE_MASK 0x00060000
#define GPIO_CFG_OUT_TYPE_LSB 17
#define GPIO_CFG_IN_TYPE_MASK 0x00060000
#define GPIO_CFG_IN_TYPE_LSB 17
#define GPIO_CFG_OUT_STRENGTH_MASK 0x00f00000
#define GPIO_CFG_OUT_STRENGTH_LSB 20
#define GPIO_CFG_INT_MASK 0x07000000
#define GPIO_CFG_INT_LSB 24
#define GPIO_CFG_OUT_BIT 19
/*!* defgroup GPIO_PinConfigSettings 宏,用于配置GPIO引脚* @{*/
/*GPIO_PinConfig 输出配置宏*/
#define GPIO_CFG_OUTPUT (((uint32_t) 0) << GPIO_CFG_IO_LSB) /* 输出. */
#define GPIO_CFG_OUT_STD (((uint32_t) 0) << GPIO_CFG_IO_LSB)
#define GPIO_CFG_OUT_OD_NOPULL (((uint32_t) 2) << GPIO_CFG_IO_LSB) /* 开漏 */
#define GPIO_CFG_OUT_OD_PU (((uint32_t) 4) << GPIO_CFG_IO_LSB) /* 开漏/上拉 */
#define GPIO_CFG_OUT_OD_PD (((uint32_t) 6) << GPIO_CFG_IO_LSB) /* 开漏/下拉 */#define GPIO_CFG_OUT_STR_LOW (((uint32_t) 0) << GPIO_CFG_OUT_STRENGTH_LSB) /* 驱动强度:低 */
#define GPIO_CFG_OUT_STR_MED (((uint32_t) 1) << GPIO_CFG_OUT_STRENGTH_LSB) /* 驱动强度:中 */
#define GPIO_CFG_OUT_STR_HIGH (((uint32_t) 2) << GPIO_CFG_OUT_STRENGTH_LSB) /* 驱动强度:高 */#define GPIO_CFG_OUT_HIGH (((uint32_t) 1) << GPIO_CFG_OUT_BIT) /* 输出 1 */
#define GPIO_CFG_OUT_LOW (((uint32_t) 0) << GPIO_CFG_OUT_BIT) /* 输出 0 */
/* GPIO_PinConfig 输入配置宏*/
#define GPIO_CFG_INPUT (((uint32_t) 1) << GPIO_CFG_IO_LSB) /* 输入 */
#define GPIO_CFG_IN_NOPULL (((uint32_t) 1) << GPIO_CFG_IO_LSB) /* 无内部上拉/下拉 */
#define GPIO_CFG_IN_PU (((uint32_t) 3) << GPIO_CFG_IO_LSB) /* 内部上拉 */
#define GPIO_CFG_IN_PD (((uint32_t) 5) << GPIO_CFG_IO_LSB) /* 内部下拉 */
/* GPIO_PinConfig 中断配置宏*/
#define GPIO_CFG_IN_INT_NONE (((uint32_t) 0) << GPIO_CFG_INT_LSB) /* 无中断 */
#define GPIO_CFG_IN_INT_FALLING (((uint32_t) 1) << GPIO_CFG_INT_LSB) /* 下降沿触发 */
#define GPIO_CFG_IN_INT_RISING (((uint32_t) 2) << GPIO_CFG_INT_LSB) /* 上升沿触发 */
#define GPIO_CFG_IN_INT_BOTH_EDGES (((uint32_t) 3) << GPIO_CFG_INT_LSB) /* 上升下降沿触发 */
#define GPIO_CFG_IN_INT_LOW (((uint32_t) 4) << GPIO_CFG_INT_LSB) /* 低电平触发 */
#define GPIO_CFG_IN_INT_HIGH (((uint32_t) 5) << GPIO_CFG_INT_LSB) /* 高电平触发 */
高16位存放的就是以上信息,每个位都对应有一个功能,位功能图我就不画了,了解大概原理即可。
typedef struct GPIOCC32XX_Config {GPIO_PinConfig *pinConfigs; //引脚GPIO配置GPIO_CallbackFxn *callbacks;uint32_t numberOfPinConfigs;uint32_t numberOfCallbacks;uint32_t intPriority;
} GPIOCC32XX_Config;
GPIOCC32XX_Config是更高一层的GPIO配置,注意加粗那一行,就是上面讲的32位引脚配置整数。这里再加上回调函数和中断优先级。
void GPIO_init()
{unsigned int i, j;#if DebugP_ASSERT_ENABLEDinitCalled = true;
#endiffor (i = 0; i < NUM_PORTS; i++){for (j = 0; j < NUM_PINS_PER_PORT; j++){gpioCallbackInfo[i].pinIndex[j] = CALLBACK_INDEX_NOT_CONFIGURED;}}/** Configure pins and create Hwis per static array content*/for (i = 0; i < GPIOCC32XX_config.numberOfPinConfigs; i++){if (!(GPIOCC32XX_config.pinConfigs[i] & GPIO_DO_NOT_CONFIG)){GPIO_setConfig(i, GPIOCC32XX_config.pinConfigs[i]);}if (i < GPIOCC32XX_config.numberOfCallbacks){if (GPIOCC32XX_config.callbacks[i] != NULL){/* create Hwi as necessary */GPIO_setCallback(i, GPIOCC32XX_config.callbacks[i]);}}}Power_registerNotify(&powerNotifyObj,PowerCC32XX_ENTERING_LPDS | PowerCC32XX_AWAKE_LPDS,powerNotifyFxn, (uintptr_t) NULL);
}
注意加粗的GPIO_setConfig()方法,追踪下去,代码太长,我就不贴完了,这里只贴关键几句:
/* Configure the GPIO pin */
MAP_GPIODirModeSet(portBase, pinMask, direction);
MAP_PinConfigSet(pin, strength, pinType);/* Set output value */
if (direction == GPIO_DIR_MODE_OUT)
{MAP_GPIOPinWrite(portBase, pinMask,((pinConfig & GPIO_CFG_OUT_HIGH) ? 0xFF : 0));
}
加粗部分都是上篇日志我们使用过的ROM API。
void GPIO_write(uint_least8_t index, unsigned int value)
{uintptr_t key;uint32_t output;PinConfig *config = (PinConfig *) &GPIOCC32XX_config.pinConfigs[index];DebugP_assert(initCalled && index < GPIOCC32XX_config.numberOfPinConfigs);DebugP_assert((GPIOCC32XX_config.pinConfigs[index] & GPIO_CFG_INPUT) ==GPIO_CFG_OUTPUT);key = HwiP_disable();/* Clear output from pinConfig */GPIOCC32XX_config.pinConfigs[index] &= ~GPIO_CFG_OUT_HIGH;if (value){output = config->pin;/* Set the pinConfig output bit to high */GPIOCC32XX_config.pinConfigs[index] |= GPIO_CFG_OUT_HIGH;}else{output = value;}MAP_GPIOPinWrite(getPortBase(config->port), config->pin, output);HwiP_restore(key);DebugP_log3("GPIO: port 0x%x, pin 0x%x wrote 0x%x",getPort(config->port), config->pin, value);
}
真正写GPIO那句代码我加粗了,上篇日志调用过。另外需要注意的是看源码可知,index参数表示的是对应gpio引脚在数组中的索引号。等下在写程序的时候这里需要格外注意。
GPIO_PinConfig gpioPinConfigs[] =
{/* output pins with callbacks */GPIOCC32XX_GPIO_09 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,GPIOCC32XX_GPIO_10 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,GPIOCC32XX_GPIO_11 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
};
我们看到,有两个按钮,没有我们加进去的LED灯。这里需要自己手动修改,但现在不改也不会影响到等下写的程序。
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOCC32XX.h>void delay(int temp)
{int i = 0;for (i = 0; i < temp; i++);
}int main(void)
{GPIO_init();while(1){GPIO_write(2, 0); //灭绿灯GPIO_write(0, 1); //亮红灯delay(0xfffff);GPIO_write(0, 0); //灭红灯GPIO_write(1, 1); //亮黄灯delay(0xfffff);GPIO_write(1, 0); //灭黄灯GPIO_write(2, 1); //亮绿灯delay(0xfffff);}
}
Debug程序,跑马灯亮,有了PinMux神器,写程序还是挺方便的。
这里需要注意,GPIO_write()函数中的第一个参数表示gpio口在gpioPinConfigs[]数组中的索引号;第二个参数0表示灭灯,1表示亮灯。
#ifndef __BOARD_H
#define __BOARD_H#ifdef __cplusplus
extern "C" {
#endif#include "CC3220SF_LAUNCHXL.h"#define LED_ON CC3220SF_LAUNCHXL_GPIO_LED_ON
#define LED_OFF CC3220SF_LAUNCHXL_GPIO_LED_OFF
#define RED_LED (0)
#define YELLOW_LED (1)
#define GREEN_LED (2)#ifdef __cplusplus
}
#endif#endif /* __BOARD_H */
保存。
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOCC32XX.h>
#include "Board.h"void delay(int temp)
{int i = 0;for (i = 0; i < temp; i++);
}int main(void)
{GPIO_init();while(1){GPIO_write(GREEN_LED, LED_OFF); //灭绿灯GPIO_write(RED_LED, LED_ON); //亮红灯delay(0xfffff);GPIO_write(RED_LED, LED_OFF); //灭红灯GPIO_write(YELLOW_LED, LED_ON); //亮黄灯delay(0xfffff);GPIO_write(YELLOW_LED, LED_OFF); //灭黄灯GPIO_write(GREEN_LED, LED_ON); //亮绿灯delay(0xfffff);}
}
4、现在这代码看上去就很舒服了。编译,运行,大功告成。
Board.h文件的作用为针对特定主板声明各种宏,增加程序可读性。
本文发布于:2024-01-31 19:35:53,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170670095330867.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |