专家您好,我最近调试TI的EK-LM4F120xl launchpad 板卡时发现,板载的两个机械按键SW1和SW2配置后,只有SW1可用!SW2无反应(不进入中断),这是什么原因呢?我的源码是:
#if BSP_KEY_EN>0 // 按键所在管脚为PF0和PF4
#define KEY_SYSCTL SYSCTL_PERIPH_GPIOF /* System control of KEY */
#define KEY_GPIO_PORT GPIO_PORTF_BASE /* IO port of KEY */
#define KEY_1_PIN GPIO_PIN_4 /* Pin number of KEY */
#define KEY_2_PIN GPIO_PIN_0 /* Pin number of KEY */
#endif
void GPIO_KEY_Init() { //配置按键 PF4-SW1 ;PF0-SW2
ROM_SysCtlPeripheralEnable(KEY_SYSCTL);
ROM_GPIOPinTypeGPIOInput(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN);
ROM_GPIOPadConfigSet(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);
ROM_GPIOIntTypeSet(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN,GPIO_FALLING_EDGE);
ROM_GPIOPinIntEnable(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN ); ROM_IntEnable(INT_GPIOF);
}
总中断在主函数也打开了 ROM_IntMasterEnable(); //开总中断
可是,按键只有SW1起到作用,SW2无反应;用示波器看, 按下SW2后有跳变电平,但是管脚PF0好像捕获不到,不进中断。换过一块新板卡也是没反应。
我查看原理图后发现,SW2除了链接到PF0管脚外,还连接到了wake唤醒管脚,难道是这个原因导致其基本按键功能无反应? 可以用软件办法解决吗?
Michael Sun:
A版本的M4芯片,PF0默认为NMI功能。
对于PF0和PD7管脚进行功能配置时,要先解锁。例如,解锁PF0:
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0xFF;
解锁后再进行相应的配置,即可实现GPIO的功能。
Michael Sun:
补充一点,实际上你可以参考Launchpad的那个qs-rgb例程。这个例程中使用SW2做按键。
安装完Tivaware后,找到C:\ti\TivaWare_C_Series-1.0\examples\boards\ek-tm4c123gxl\drivers\buttons.c文件中:
ButtonsInit函数:
// // Unlock PF0 so we can change it to a GPIO input // Once we have enabled (unlocked) the commit register then re-lock it // to prevent further changes. PF0 is muxed with NMI thus a special case. // HWREG(BUTTONS_GPIO_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY; HWREG(BUTTONS_GPIO_BASE + GPIO_O_CR) |= 0x01; HWREG(BUTTONS_GPIO_BASE + GPIO_O_LOCK) = 0;
// // Set each of the button GPIO pins as an input with a pull-up. // ROM_GPIODirModeSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, GPIO_DIR_MODE_IN); ROM_GPIOPadConfigSet(BUTTONS_GPIO_BASE, ALL_BUTTONS, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
这里宏BUTTONS_GPIO_BASE被定义为GPIO_PORTF_BASE。
Jingbing Wang:
回复 Michael Sun:
原因原来是这样啊。
不过刚刚我试过了:
void GPIO_KEY_Init(){ //配置按键 PF4-SW1 ;PF0-SW2 ROM_SysCtlPeripheralEnable(KEY_SYSCTL); //A版本的M4芯片,PF0默认为NMI功能。 //对于PF0和PD7管脚进行功能配置时,要先解锁。例如,解锁PF0 HWREG(KEY_GPIO_PORT + GPIO_O_LOCK) = GPIO_LOCK_KEY; HWREG(KEY_GPIO_PORT + GPIO_O_CR) |= 0x01; HWREG(KEY_GPIO_PORT + GPIO_O_LOCK) = 0;
ROM_GPIOPinTypeGPIOInput(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN); ROM_GPIOPadConfigSet(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); ROM_GPIOIntTypeSet(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN,GPIO_FALLING_EDGE); ROM_GPIOPinIntEnable(KEY_GPIO_PORT,KEY_1_PIN | KEY_2_PIN ); ROM_IntEnable(INT_GPIOF);}
增加了解锁配置,可还是不成功。 和先前现象一样,无反应。换过单片机,还是一样没反应。 难道是这样解锁不成功?
xianju xu:
回复 Michael Sun:
现在试了试是这样的情况,直接检查管脚PF4和GND的导通情况,按下SW1导通,这个没问题。然后写程序读PF4管脚
while(GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4)) {;}
这样写的话是直接跳出这个循环。
按道理来说应该是读到1,然后在while(1)里面循环。
然后,改成while(!GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4)) {;}
取反了读到的数,按下SW2有反应,注意是SW2! SW1还是没动静。
SW1接的wake到底是个什么鬼,不明白。解锁PF0没问题,看得懂的。
xyz549040622:
回复 xianju xu:
SW1接的是普通IO PF4,你是不是刚开始的时候没有初始化PF4呢,应该初始化为双向IO,输出高电平这样才可以的,或者直接配置为输入,读取到低电平有效,当没有按下时,读取到的应该是浮空的状态。而不是高电平。
xianju xu:
回复 xyz549040622:
初始化了 PF4,并设置PF4为输入。GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4),发送读的数据,不按SW1和SW2时一直是00, 按SW1没反应,按SW2中间出现几个值是10。一直按着SW2,中间就变成00了。
xyz549040622:
回复 xianju xu:
单纯配置PF4为输入口,当SW2不按下的时候,你觉得应该读到的是什么呢?应该继续配置PF4为弱上拉。给你个按键的例程看看
//按键实验程序解析 //头文件 #include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/sysctl.h" #include "driverlib/rom.h" #include "driverlib/gpio.h" #include "driverlib/fpu.h" #include "driverlib/pin_map.h" #include "inc/tm4c123gh6pge.h"int main (void) {//使能FPUFPUEnable();FPULazyStackingEnable();//配置系统时钟为50MHzSysCtlClockSet(SYSCTL_SYSDIV_4 |SYSCTL_USE_PLL|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);//使能外设PORTMROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);//配置PG2为输出口,PM4为输入口,且有弱上拉。ROM_GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE,GPIO_PIN_2);ROM_GPIOPinTypeGPIOInput(GPIO_PORTM_BASE,GPIO_PIN_4);ROM_GPIOPadConfigSet(GPIO_PORTM_BASE, GPIO_PIN_4,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU); while(1) {//如果不按下按键(PM4输入为高), User LED灭 if(ROM_GPIOPinRead(GPIO_PORTM_BASE,GPIO_PIN_4)&&GPIO_PIN_4) ROM_GPIOPinWrite(GPIO_PORTG_BASE,GPIO_PIN_2,0);//如果按下按键(PM4输入为低), User LED亮 elseROM_GPIOPinWrite(GPIO_PORTG_BASE,GPIO_PIN_2,GPIO_PIN_2); } }
xianju xu:
回复 xyz549040622:
没留意按键弱上拉的问题,现在问题解决了。
但是PF4为什么在不配置弱上拉的时候按下SW2会有动静。
xyz549040622:
回复 xianju xu:
应该是和这个wake的状态有关了。