概述
K64F处理器的GPIO操作,主要通过SDK中的“gpio_input_interrupt”例程进行学习,同时需要结合对应的API文档。
例程代码分析
在官方例程代码gpio_input_interrupt.c中,GPIO的操作需要首先经过配置,通过下面的代码将GPIO配置为输入或输出。
gpio_pin_config_t sw_config = {
kGPIO_DigitalInput,
0,
};
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
上述代码定义了一个输入配置和一个输出配置。
第2步,通过
PORT_SetPinInterruptConfig(GPIOA, BOARD_SW_GPIO_PIN, kPORT_InterruptFallingEdge);
语句,设置GPIO的中断为下降沿触发。
第3步,通过下面的语句
EnableIRQ(BOARD_SW_IRQ);
GPIO_PinInit(BOARD_SW_GPIO, BOARD_SW_GPIO_PIN, &sw_config);
GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config);
使能GPIO相应端口的中断,并初始化GPIO。
最后,通过
GPIO_PortToggle(BOARD_LED_GPIO, 1U << BOARD_LED_GPIO_PIN);
语句,来控制GPIO。GPIO中断会进入 PORTA_IRQHandler中断服务函数中,可以执行清中断标志和其它动作。
是不是好麻烦?
上面给出的是官方推荐代码,由于K64F可以采用MCUXpresso IDE软件开发,通过学习该IDE,会发现该IDE拥有专用的引脚配置工具,通过配置工具,就可以免去编写配置代码。最大的好处是无需学习GPIO配置流程,避免在API函数中查找相关函数。由于kinetis单片机型号太多,也没有精力去一个一个查找。只需要在IDE中的引脚配置工具点几下鼠标,就可以完成GPIO配置。
打开引脚配置工具,可以看到例程中用到了4个引脚,两个UART引脚,1个sw开关输入GPIO,1个LED输出GPIO。
我们利用该工具,对sw和led引脚进行如下图配置
为了进行对比,我们把名称改为BUTTON3和MY_LED。输入输出方向直接在下拉菜单中选择,中断形式也可以在下拉菜单中选择为下降沿触发。
在右边的问题栏
右键选择“初始化GPIOA外设”。
点击顶部的“更新源代码”,弹出对话框
点击确定后,相关代码有了变化,打开文件pin_mux.c,可以看到下面的代码
void BOARD_InitPins(void)
{
/* Port A Clock Gate Control: Clock enabled */
CLOCK_EnableClock(kCLOCK_PortA);
/* Port B Clock Gate Control: Clock enabled */
CLOCK_EnableClock(kCLOCK_PortB);
gpio_pin_config_t BUTTON3_config = {
.pinDirection = kGPIO_DigitalInput,
.outputLogic = 0U
};
/* Initialize GPIO functionality on pin PTA4 (pin 38) */
GPIO_PinInit(BOARD_INITPINS_BUTTON3_GPIO, BOARD_INITPINS_BUTTON3_PIN, &BUTTON3_config);
gpio_pin_config_t MY_LED_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 0U
};
/* Initialize GPIO functionality on pin PTB22 (pin 68) */
GPIO_PinInit(BOARD_INITPINS_MY_LED_GPIO, BOARD_INITPINS_MY_LED_PIN, &MY_LED_config);
const port_pin_config_t BUTTON3 = {/* Internal pull-up resistor is enabled */
kPORT_PullUp,
/* Fast slew rate is configured */
kPORT_FastSlewRate,
/* Passive filter is disabled */
kPORT_PassiveFilterDisable,
/* Open drain is disabled */
kPORT_OpenDrainDisable,
/* High drive strength is configured */
kPORT_HighDriveStrength,
/* Pin is configured as PTA4 */
kPORT_MuxAsGpio,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
/* PORTA4 (pin 38) is configured as PTA4 */
PORT_SetPinConfig(BOARD_INITPINS_BUTTON3_PORT, BOARD_INITPINS_BUTTON3_PIN, &BUTTON3);
/* Interrupt configuration on PORTA4 (pin 38): Interrupt on falling edge */
PORT_SetPinInterruptConfig(BOARD_INITPINS_BUTTON3_PORT, BOARD_INITPINS_BUTTON3_PIN, kPORT_InterruptFallingEdge);
/* PORTB16 (pin 62) is configured as UART0_RX */
PORT_SetPinMux(BOARD_INITPINS_DEBUG_UART_RX_PORT, BOARD_INITPINS_DEBUG_UART_RX_PIN, kPORT_MuxAlt3);
/* PORTB17 (pin 63) is configured as UART0_TX */
PORT_SetPinMux(BOARD_INITPINS_DEBUG_UART_TX_PORT, BOARD_INITPINS_DEBUG_UART_TX_PIN, kPORT_MuxAlt3);
/* PORTB22 (pin 68) is configured as PTB22 */
PORT_SetPinMux(BOARD_INITPINS_MY_LED_PORT, BOARD_INITPINS_MY_LED_PIN, kPORT_MuxAsGpio);
SIM->SOPT5 = ((SIM->SOPT5 &
/* Mask bits to zero which are setting */
(~(SIM_SOPT5_UART0TXSRC_MASK)))
/* UART 0 transmit data source select: UART0_TX pin. */
| SIM_SOPT5_UART0TXSRC(SOPT5_UART0TXSRC_UART_TX));
}
查看刚才定义的BUTTON3和MY_LED相关字段,直接从字面上就可以知道,这些字段是按照引脚配置工具的配置进行的。
同时相关宏定义
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_BUTTON3_GPIO GPIOA /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITPINS_BUTTON3_GPIO_PIN_MASK (1U << 4U) /*!<@brief GPIO pin mask */
/* Symbols to be used with PORT driver */
#define BOARD_INITPINS_BUTTON3_PORT PORTA /*!<@brief PORT peripheral base pointer */
#define BOARD_INITPINS_BUTTON3_PIN 4U /*!<@brief PORT pin number */
#define BOARD_INITPINS_BUTTON3_PIN_MASK (1U << 4U) /*!<@brief PORT pin mask */
/* @} */
/*! @name PORTB22 (number 68), D12[1]/LEDRGB_RED
@{ */
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_MY_LED_GPIO GPIOB /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITPINS_MY_LED_GPIO_PIN_MASK (1U << 22U) /*!<@brief GPIO pin mask */
/* Symbols to be used with PORT driver */
#define BOARD_INITPINS_MY_LED_PORT PORTB /*!<@brief PORT peripheral base pointer */
#define BOARD_INITPINS_MY_LED_PIN 22U /*!<@brief PORT pin number */
#define BOARD_INITPINS_MY_LED_PIN_MASK (1U << 22U) /*!<@brief PORT pin mask */
/* @} */
也发生了变化。
现在我们返回到main函数中,可以直接删除原来的配置代码,直接使用GPIO_PortToggle函数控制GPIO了。
GPIO_PortToggle(BOARD_INITPINS_MY_LED_GPIO, BOARD_INITPINS_MY_LED_GPIO_PIN_MASK);
是不是清爽多了。换句话说,我们要驱动GPIO,最少就只需要这一句话,其它的都被IDE做了,甚至API手册都没来得及翻!!
结束
可以看到,通过MCUXpresso IDE软件,可以大大提高代码开发效率,将设计人员的主要注意力放在算法和流程中,而不需要翻看厚厚的手册,查看眼花缭乱的寄存器。对于经常游走在不同型号单片机的设计人员来说,掌握了MCUXpresso IDE,就触类旁通的掌握了MCUXpresso IDE支持的所有单片机。