1、实验四 GPIO 输入实验一、实验目的1、能够使用 GPIO 的输入模式读取开关信号。2、掌握 GPIO 相关寄存器的用法和设置。3、掌握用 C 语言编写程序控制 GPIO。二、实验环境PC 机 一台ADS 1.2 集成开发环境 一套EasyARM2131 教学实验平台 一套 三、实验内容1.实验通过跳线 JP8 连接 KEY1 与 P0.16,程序检测按键 KEY1 的状态,控制蜂鸣器 BEEP 的鸣叫。按下 KEY1,蜂鸣器鸣叫,松开后停止蜂鸣。 (调通实验后,改为 KEY3 键进行输入) 。 2.当检测到 KEY1 有按键输入时点亮发光二极管 LED4 并控制蜂鸣器响,软件延时后关掉发光
2、管并停止蜂鸣,然后循环这一过程直到检测按键没有输入。 (键输入改为键 KEY4,发光管改为 LED6) 。3.结合实验三,当按下按键 Key1 时,启动跑马灯程序并控制蜂鸣器响,软件延时后关掉发光管并停止蜂鸣,然后循环这一过程直到检测按键再次按下。四、实验原理当 P0 口用于 GPIO 输入时(如按键输入) ,内部无上拉电阻,需要加上拉电阻,电路图参见图 4.2。进行 GPIO 输入实验时,先要设置 IODIR 使接口线成为输入方式,然后读取 IOPIN 的值即可。图 4.2 按键电路原理图实验通过跳线 JP8 连接 KEY1_P0.16,程序检测按键 KEY1 的状态,控制蜂鸣器 BEEP
3、的鸣叫。按下 KEY1,蜂鸣器鸣叫,松开后停止蜂鸣。在这个实验中,需要将按键 KEY1 输入口 P0.16 设为输入口而蜂鸣器控制口 P0.7 设置为输出口。蜂鸣器电路如图 4.3 所示,当跳线 JP6 连接蜂鸣器时,P0.7 控制蜂鸣器,低电平时蜂鸣器鸣叫。LED 灯电路如图 4.4 所示,低电平时灯亮。图 4.3 蜂鸣器控制电路图 4.4 LED 控制电路程序首先设置管脚连接寄存器 PINSEL0 和 PINSEL1,设置 P0.16 为输入,设置 P0.7,P1.21 为输出。然后检测端口 P0.16 的电平,对 P0.7, P1.21 进行相应的控制,流程图如图 4.5 所示,实现程序
4、见程序清单 4.1。图 4.5 按键输入实验流程图5、实验步骤、源代码及调试结果内容 1实验步骤 启动 ADS1.2IDE 集成开发环境,选择 ARM Executable Image for lpc2131 工程模板建立一个工程 BEEP_key。 在 user 组里编写主程序代码 main.c。 选用 DebugInFLASH 生成目标,然后编译链接工程。 将 EasyARM 教学实验开发平台上的相应管脚跳线短接。 选择 Project-Debug,启动 AXD 进行 JLINK 仿真调试。 全速运行程序,程序将会在 main.c 的主函数中停止。如下图所示: 单击 Context Var
5、iable 图标按钮(或者选择 Processor Views-Variables)打开变量观察窗口,通过此窗口可以观察局部变量和全局变量。选择 System Views-Debugger Internals 即可打开 LPC2000 系列 ARM7 微控制器的片内外寄存器窗口。通过变量窗口可以观察变量 BEEP、KEY1 等的值和 ARM7 微控制器的片内外寄存器窗口。如下图所示: 可以单步运行程序,先按下 Key1,观察 IO0PIN 寄存器的值,然后断开Key1,观察 IO0PIN 寄存器的值。可以设置/取消断点;或者全速运行程序,停止程序运行,观察变量的值,判断蜂鸣器控制是否正确。如下
6、图所示:图 4.6 未按下 Key1 时 IO0PIN 的值 图 4.7 按下 Key1 时 IO0PIN 的值由上两图可知,当按下 Key1 时,IO0PIN 寄存器的第 16 位由 1 变为 0(F 变为E) ,key1 与 P0.16 相连,按下 Key1 时,P0.16 管脚输出电平由 1 变为 0,寄存器值变化,蜂鸣器响,说明控制是正确的。现象描述:按下 KEY1,蜂鸣器鸣叫,松开后停止蜂鸣。源代码:#include “config.h“const uint32 BEEP = 1 Debug,启动 AXD 进行 JLINK 仿真调试。 全速运行程序,程序将会在 main.c 的主函数
7、中停止。如下图所示: 单击 Context Variable 图标按钮(或者选择 Processor Views-Variables)打开变量观察窗口,通过此窗口可以观察局部变量和全局变量。选择 System Views-Debugger Internals 即可打开 LPC2000 系列 ARM7 微控制器的片内外寄存器窗口。通过变量窗口可以观察变量 BEEP、KEY1 等全局变量、 i 等本地变量和 ARM7 微控制器的片内外寄存器窗口。如下图所示:左图所示为 ARM7 微控制器的片内寄存器窗口。图 4.9 本地变量图 4.8 全局变量 可以单步运行程序,先按下 Key1,观察 IO0PI
8、N 寄存器的值,然后断开 Key1,观察 IO0PIN 寄存器的值。可以设置 /取消断点;或者全速运行程序,停止程序运行,观察变量的值,判断蜂鸣器控制是否正确。如下图所示:.图 4.10 未按下 KEY1 时 IO0PIN 的值 图 4.11 按下 KEY1 后 IO0PIN 的值对比图 4.10 和 4.11,发现按下 KEY1 后,IO0PIN 寄存器的第 16 位由 1 变为0;而 KEY1 对应管脚 P0.16,当按下时输入低电平,这说明 KEY1 的控制是正确的。上图所示为运行 “IO0CLR = BEEP”后 IO0PIN 寄存器的值,与图 4.10 对比,发现第 8 位由 1 变
9、为 0,BEEP 对应 P0.7 管脚,这说明 BEEP 的控制是对的。现象描述:当按下 KEY1 时,蜂鸣器鸣响,LED4 亮;当松开 KEY1 后,蜂鸣器静音,LED4 灭。源代码如下:#include “config.h“const uint32 BEEP = 1 Debug,启动 AXD 进行 JLINK 仿真调试。 全速运行程序,程序将会在 main.c 的主函数中停止。如下图所示: 单击 Context Variable 图标按钮(或者选择 Processor Views-Variables)打开变量观察窗口,通过此窗口可以观察局部变量和全局变量。选择 System Views-D
10、ebugger Internals 即可打开 LPC2000 系列 ARM7 微控制器的片内外寄存器窗口。通过变量窗口可以观察变量 BEEP、KEY1 等的值和 ARM7 微控制器的片内外寄存器窗口。如下图所示: 可以单步运行程序,先按下 Key1,观察 IO0PIN 寄存器的值,然后断开Key1,观察 IO0PIN 寄存器的值。可以设置/取消断点;或者全速运行程序,停止程序运行,观察变量的值,判断蜂鸣器控制是否正确。如下图所示:图 4.12 未按下 Key1 时 IO0PIN 的值 图 4.13 按下 Key1 时 IO0PIN 的值由上两图可知,当按下 Key1 时,IO0PIN 寄存器的
11、第 16 位由 1 变为 0(F 变为E) ,key1 与 P0.16 相连,按下 Key1 时,P0.16 管脚输出电平由 1 变为 0,寄存器值变化,蜂鸣器响,流水灯亮,说明控制是正确的。现象描述:当按下按键 KEY1 时,蜂鸣器鸣响,流水灯亮;松开后,蜂鸣器静音,流水灯灭。源代码如下:#include “config.h“const uint32 BEEP = 1 0; dly-) for(i=0; i50000; i+);/* 函数名称:liushuideng()* 函数功能:流水灯显示实验。* 调试说明:连接跳线 JP12 至 LED8LED1。*/* 流水灯花样,低电平点亮,注意调
12、用时候用了取反操作 */const uint32 LED_TBL =0x00, 0xFF, / 全部熄灭后,再全部点亮0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, / 依次逐个点亮0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, / 依次逐个叠加0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, / 依次逐个递减0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81, / 两个靠拢后分开0x81, 0xC3, 0xE7
13、, 0xFF, 0xFF, 0xE7, 0xC3, 0x81 / 从两边叠加后递减;int liushuideng(void) uint8 i;PINSEL1 = 0x00000000; / 设置管脚连接 GPIOIO1DIR = LEDS8; / 设置 LED 控制口为输出while (1)for (i=0; i42; i+) /* 流水灯花样显示 */IO1SET = (LED_TBLi) 18);DelayNS(20);IO1CLR = (LED_TBLi) 18);DelayNS(20);return 0;/主函数int main(void) uint32 i; PINSEL0 = 0
14、x00000000; / 所有管脚连接 GPIOPINSEL1 = 0x00000000;IO0DIR = BEEP; / 蜂鸣器控制口输出 0while (1) if (IO0PIN i1000; i+); / 软件延时IO0CLR = BEEP; / 如果 KEY 按下,蜂鸣器鸣叫liushuideng();else IO0SET = BEEP; / 松开则停止蜂鸣IO1SET= LEDS8;for(i=0; i100; i+); / 软件延时return 0;六、思考题1、如果将 P0.30 设置为 GPIO 输入模式,且管脚悬空,那么读取 P0.30得到的值是 0 还是 1?或者是不确定?当管脚悬空时,该管脚有可能是高电平也有可能是低电平。读取IO0PIN 的值并不能确定管教的值。有时管脚是高电平,读取到的不一定是高电平。2、如果需要读取当前 P0.7 的输出值(不是管脚上的电平),如何实现?将该管脚与一个 LED 连接,若 LED 亮,则输出值为 0,否则为 1.