环境配置上次开箱已经说过了,这次尝试使用按键中断使LED灯翻转。
1、首先是LED灯和按键K的硬件:
下图是K1的硬件连接图。用按键K1模拟ADC输入,这里我们只用作按键触发中断,按键K1对应的IO如右图所示。即PB1对应K1.
LED4对应的IO口是PC5.如下图所示。
2、GPIO口配置 这里我用的是LED4灯和K1键,所以我只配置了这两个IO口。
(1)首先定义LED4和K1引脚:
#define LED4_PIN (GPIO_PC5)
#define LED4 (GPIOC_OUT(5))
#define K1_PIN (GPIO_PB1)
#define K6_IN (GPIOB_IN(1))
(2)定义一个GPIO初始化函数:GPIO_InitHardwr()
void GPIO_InitHardwr(void)
{
GPIO_SetDir(LED4_PIN, GPIO_OUTPUT);
GPIO_SetDir(K6_PIN, GPIO_INPUT);
}
3、定义一个按键扫描函数和中断函数:
void GPIO_ScanKeyAction(void)
{
if (g_scanKeyTimeCnt > 9)
{
g_scanKeyTimeCnt = 0;
if ((g_getK1CurtSts == KEY_UNDOWN) && (K1_IN == 0))
{
mdelay(20);
if (K1_IN == 0)
{
LED4=!LED4;
g_getK1CurtSts = KEY_DOWN;
}
}
else if (K1_IN == 1)
{
g_getK1CurtSts = KEY_UNDOWN;
}
}
}
void TIMER_InitHardwr(void)
{
TIMER_ConfigType timerConfig = {0};
timerConfig.loadValue = (48000000 / (1000 - 1));
timerConfig.linkMode = 0;
timerConfig.interruptEn = 1;
timerConfig.timerEn = 1;
TIMER_SetCallback(TIMER2,TIM2_IRQnCallBack);
TIMER_Init(TIMER2,&timerConfig);
}
void TIM2_IRQnCallBack(uint8_t lparam)
{
if (TIMER_GetIntFlag(TIMER2))
{
TIMER_ClrIntFlag(TIMER2);
if (g_scanKeyTimeCnt < 0xFF)
{
g_scanKeyTimeCnt++;
}
}
}
4、主函数main函数:
int main(void)
{
InitDelay();
InitDebug();
GPIO_InitHardwr();
TIMER_InitHardwr();
while(1)
{
GPIO_ScanKeyAction();
}
}
5、最终的实验效果是:按一次K1,LED4翻转一次。
6、出现的问题:
(1)程序下载到板子之后需要按一下K5才能执行,K5按键理应是复位键。
(2)用同样的方法点亮LED2和LED3时,LED2始终不亮,而LED3始终处于亮的状态,当时开箱时,没有下载程序时,LED2和LED3都是亮的,会不会是我把三极管给烧了。
(3)还有时钟方面的配置还没搞懂。到底需不需要在使用GPIO是使能时钟呢。
|