现在试试用按钮操控LED灯……让LED在一个按钮按下时亮起;弹起时灭掉。
首要意图是学习GPIO的输入及中止。
一、 电路
图中的J39-n是几个跳线插座,方位在开发板LCD邻近,往下进行前要先保证跳线是接通的。
能够看到,当按钮按下时,引脚接地。即若引脚接个上拉电阻,则在按钮弹起状况下,引脚处于高电平状况;而在按钮按下时,则处于低电平状况。
这次运用的按钮是BP3,即PA20引脚;LED为蓝色LED,即PA0。
二、 最简略的方法
在开发版重置时,一切的引脚就默许接了上拉电阻。
所以,直接运用一根杜邦线将PA20和PA0短接,就能够用BP3操控蓝色LED了。
三、 略微有技术含量的思路
假定,身边不存在杜邦线……
那么很直接的思路便是依据按钮引脚的电平,来操控LED灯引脚的电平。能够挑选经过不断查询来获取按钮引脚的电平状况,但咱们现在运用更高档的兵器:中止。
咱们让按钮引脚在电平改换时发生一个中止,然后在中止服务函数中操控LED引脚电平。
四、 LED引脚的装备
这个装备现已做过屡次了……
五、 输入引脚的装备
1. 启用PIO操控器的时钟。启用中止、获取引脚电平需求敞开相应PIO操控器的时钟。
1PMC->PMC_PCER0 = (1 << ID_PIOA);
2. 引脚装备为仅做输入用处
#define BUTTON_PIO PIO_PA20
/* 运用PIO操控器操控引脚 */
PIOA->PIO_PER = BUTTON_PIO;
/* 禁用引脚输出,即按钮引脚仅做为输入引脚 */
PIOA->PIO_ODR = BUTTON_PIO;
3. 启用上拉电阻。默许情况下无需做此设置。但装备时需求留意,在启用上拉电阻前需求禁用下拉电阻。
/* 启用上拉电阻(不过重置时便是默许启用的) */
PIOA->PIO_PPDDR = BUTTON_PIO;
PIOA->PIO_PUER = BUTTON_PIO;
4. 启用中止。
/* 启用中止 */
PIOA->PIO_IER = BUTTON_PIO;
/* 不运用额定中止操控形式 */
PIOA->PIO_AIMDR = BUTTON_PIO;
/* NVIC中启用中止 */
NVIC_ClearPendingIRQ(PIOA_IRQn);
NVIC_SetPriority(PIOA_IRQn, 0);
NV%&&&&&%_EnableIRQ(PIOA_IRQn);
这样,该引脚就会在输入电平的上升沿及下降沿,即按钮弹起及按下时,发生中止了。
六、 过错的的中止装备
GPIO能够挑选一些额定的中止操控形式:上升沿触发,下降沿触发,低电平触发,高电平触发。为使引脚在检测到上升沿或下降沿时均触发中止,做了以下装备:
/* 注:这是过错的做法 */
/* 启用额定中止操控形式 */
PIOA->PIO_AIMER = BUTTON_PIO;
/* 挑选边缘触发 */
PIOA->PIO_ESR = BUTTON_PIO;
/* 上升和下降沿 */
PIOA->PIO_REHLSR = BUTTON_PIO;
PIOA->PIO_FELLSR = BUTTON_PIO;
这样做的结果是,只会在下降沿触发中止。原因是,上面说到的几种中止形式中,只能运用一种——即最终的句子装备的“下降沿/低电平”触发中止。
而在不启用额定中止操控时,则会在两种边缘都会触发中止。
七、 中止服务函数
有这样几个寄存器:
PIO_ELSR——用来表明触发中止的是电平仍是边缘
PIO_FRLHSR——用来表明触发中止的是下降沿或低电平,仍是上升沿或高电平
很惋惜,在不运用额定中止操控形式下,这些寄存器都是无作用的。
但能够经过读取PIO_PDSR寄存器来直接确认引脚的电平。需求留意,运用这个寄存器时,需求先敞开PIO操控器的时钟。
代码逻辑比较简略:
#define LED_PIO PIO_PA0
void PIOA_Handler()
{
/* 获取中止的状况,一起拉低中止 */
uint32_t status = PIOA->PIO_ISR;
/* 先确认是否是由按钮引脚触发的中止 */
if ((status & BUTTON_PIO) != 0)
{
if (PIOA->PIO_PDSR & BUTTON_PIO)
{
/* 高电平,按钮弹起 */
PIOA->PIO_SODR = LED_PIO;
}
else
{
/* 低电平,按钮按下 */
PIOA->PIO_CODR = LED_PIO;
}
}
}