1.GPIO概念
GPIO(General-purpose input/output)即通用型输入输出,GPIO可以控制连接在其之上的引脚实现信号的输入和输出
芯片的引脚与外部设备相连,从而实现与外部硬件设备的通讯、控制及信号采集等功能
那么,IO如何实现输入输出呢?
即通过对寄存器的读与写入,从而对各种逻辑电路实现控制,再通过不同引脚的功能,以及相关的协议等,从而输入输出相关信息。
2.LED实验步骤
2.1 通过电路原理图分析LED的控制逻辑
电路图如下:
三极管:三种工作状态,截止状态、放大状态、饱和导通,故三极管可做开关,也可增大IO的驱动能力
关于三极管,可以看以下这个视频:
终于有人讲了,凭什么三极管能放大?
我们来分析这个电路,
当引脚CHG-COK为低电平0时,此时三极管基极与发射极间的电压小于导通压降,三极管截止,此时由于电阻R13的存在,而呈现高阻态(类似于开路),二极管不会点亮。
当引脚CHG-COK为高电平1时,此时三极管基极与发射极间的电压大于导通压降(0.7),三极管导通,此时基极与发射极导通,而发射极接地,从而在二极管两端形成正向压降,从而二极管点亮。
从而有以下关系:
CHG-COK | LED状态 |
---|---|
0 | 灭 |
1 | 亮 |
2.2 通过电路原理图查找LED与Exynos4412的连接关系
查看电路图,可知CHG_COK与主控板上的GPX2_7相连
2.3 通过数据手册分析GPIO中哪些寄存器可以控制LED
(1)查GPX寄存器相关信息
由上述信息可知,就是将GPX2CON[7]设置为输出,GPX2DAT[7]设置高低电平,从而实现LED的亮灭
2.4 通过程序去操控对应的寄存器完成对LED的控制
.text
_start:
MAIN:
BL LED_CINFIG
LOOP:
BL LED_ON
BL DELAY
BL LED_OFF
BL DELAY
B LOOP
LED_CINFIG:
LDR R2,=0x11000c40
LDR R1,=0x10000000
STR R1,[R2]
MOV PC,LR
LED_ON:
LDR R2,=0x11000c44
LDR R1,=0x00000080
STR R1,[R2]
MOV PC,LR
LED_OFF:
LDR R2,=0x11000c44
LDR R1,=0x00000000
STR R1,[R2]
BX LR
DELAY:
LDR R1,=100000000
L:
SUB R1,R1,#1
CMP R1,#0
BNE L
MOV PC,LR
STOP:
B STOP
.end
流水灯
FS4412芯片
我们利用C工程文件,将寄存器封装在“exynos_4412”头文件中。从而增加程序的可维护性。
在对寄存器的操作时,采用移位、取反、与运算和或运算的组合来对寄存器的某些位进行操作,而不影响其他位。
#include "exynos_4412.h"
void light_led(unsigned int a);
void init_gpio(void);
void water_light(void);
int main()
{
init_gpio();
water_light();
return 0;
}
void water_light(void)
{
int i = 0;
while(1){
for(i = 2;i <= 5;i++){
light_led(i);
}
for(i = 4;i >=3;i--)
light_led(i);
}
return;
}
void init_gpio(void)
{
GPX2.CON = GPX2.CON & (~(0xf<<28)) | (0x1<<28);
GPX1.CON = GPX1.CON & (~(0xf<<0)) | (0x1<<0);
GPF3.CON = GPF3.CON & (~(0xf<<16)) | (0x1<<16);
GPF3.CON = GPF3.CON & (~(0xf<<20)) | (0x1<<20);
return;
}
void light_led(unsigned int a)
{
switch(a)
{
case 2:
delay(1000000);
GPX2.DAT = GPX2.DAT | (1<<7); //led2点亮
delay(1000000);
GPX2.DAT = GPX2.DAT & (~(1<<7)); //熄灭
break;
case 3:
delay(1000000);
GPX1.DAT = GPX1.DAT | (1<<0); //led3点亮
delay(1000000);
GPX1.DAT = GPX1.DAT & (~(1<<0)); //熄灭
break;
case 4:
delay(1000000);
GPF3.DAT = GPF3.DAT | (1<<4); //led4点亮
delay(1000000);
GPF3.DAT = GPF3.DAT & (~(1<<4)); //熄灭
break;
case 5:
delay(1000000);
GPF3.DAT = GPF3.DAT | (1<<5); //led5点亮
delay(1000000);
GPF3.DAT = GPF3.DAT & (~(1<<5)); //熄灭
break;
default:
break;
}
return;
}