1.1 硬件原理图

     

   

  

  四个引脚接到LED上,跟别是GPF4,GPF5,GPF6和GPF7,前三个引脚分别控制三个LED,GPF7此引脚作为DM9000网卡的中断。

  发光二极管的正极接3.3V电源,负极接在MCU上,当MCU的对应的引脚给一个低电平的时候,电路导通,发光二极管发光。

  芯片手册,GPIO配置,如下图,控制LED的属于GPF管脚:

  

  GPF的寄存器如下图:

  

  • GPFCON:GPF管脚的控制寄存器
  • GPFDAT:GPF管脚的数据寄存器
  • GPFUP:GPF上拉使能的寄存器

  

  GPF4-GPF6对应GPFCON寄存器的13—8位。

  

1.2 LED 操作

1.2.1 点亮一个  led 灯

(1)汇编编写

  led_on.S

 @******************************************************************************
@ File:led_on.S
@ 功能:LED点灯程序,点亮LED1
@****************************************************************************** .text
.global _start
_start:
LDR R0,=0x56000050 @ R0设为GPFCON寄存器。此寄存器
@ 用于选择端口B各引脚的功能:
@ 是输出、是输入、还是其他
MOV R1,#0x00000100
STR R1,[R0] @ 设置GPF4为输出口, 位[:]=0b01
LDR R0,=0x56000054 @ R0设为GPBDAT寄存器。此寄存器
@ 用于读/写端口B各引脚的数据
MOV R1,#0x00000000 @ 此值改为0x00000010,
@ 可让LED1熄灭
STR R1,[R0] @ GPF4输出0,LED1点亮
MAIN_LOOP:
B MAIN_LOOP

  Makefile

 led_on.bin : led_on.S
arm-linux-gcc -g -c -o led_on.o led_on.S
arm-linux-ld -Ttext 0x0000000 -g led_on.o -o led_on_elf
arm-linux-objcopy -O binary -S led_on_elf led_on.bin
clean:
rm -f led_on.bin led_on_elf *.o

  make 执行编译,生成 led_on.bin。烧录到开发板

(2)用C语言编写

  一个程序编译的时候会经过下面几个步骤:预处理、编译、汇编和链接。

  编译就是将源程序编译成 .S

  汇编就是将.S 编译成 .o

  链接就是将多个 .o 链接成一个可执行程序

  • 启动文件:

    • 需要做硬件初始化

      • 关看门狗
      • 初始化时钟
      • 初始化 SDRAM,若是 SRAM(内置) 不需要初始化,若是 SDRAM(外挂的),则首先要初始化 SDRAM
    • 设置栈,即将 栈指针 sp 指向某块内存,
    • 设置 main 函数的返回地址
    • 调用 main 函数
    • 清理工作

  启动程序 crt0.S

 @******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@****************************************************************************** .text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启 ldr sp, =* @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数,bl 指令会调用 main 函数,并将返回地址保存在 lr 寄存器中 halt_loop: @ main 函数执行完之后,会返回到这里做清理工作,我们这里写的是进入死循环
b halt_loop

  led_on.c

 #define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054) int main()
{
GPFCON = 0x00000100; // 设置GPF4为输出口, 位[8:7]=0b01
GPFDAT = 0x00000000; // GPF4输出0,LED1点亮
}

  Makefile

 led_on.bin : crt0.S  led_on.c
arm-linux-gcc -g -c -o crt0.o crt0.S
arm-linux-gcc -g -c -o led_on.o led_on.c
arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on.o -o led_on_elf
arm-linux-objcopy -O binary -S led_on_elf led_on.bin
arm-linux-objdump -D -m arm led_on_elf > led_on.dis
clean:
rm -f led_on.dis led_on.bin led_on_elf *.o

1.2.2 点亮三个LED

  除了 led_on.c 不一样之外,其余的和上面的 C语言编写的程序一样

  led_on.c

 #define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPF4_out (1<<(4*2))
#define GPF5_out (1<<(5*2))
#define GPF6_out (1<<(6*2)) void delay_ms(unsigned int val); int main()
{
int i = ;
GPFCON = GPF4_out|GPF5_out|GPF6_out; // 将LED1,2,4对应的GPF4/5/6三个引脚设为输出 while()
{
delay_ms();
GPFDAT = (~(i<<)); // 根据i的值,点亮LED1,2,4
if(++i == )
i = ;
} return ;
} /* 对于12M 晶振来说的 */
void delay_ms(unsigned int val)
{
unsigned int i; while(val > )
{
for(i = ; i < ; ++i)
asm("nop"); val--;
}
}

1.2.3 用按键控制LED

  按键的原理图如下所示:

      

  

  

  EINT0 和 EINT2 分别在 GPF0 和 GPF2 引脚上, EINT11 在 GPG3 引脚上

  按键引脚需要去读,按键按下形成回路,所以按键的引脚设置为输入,当按键按下的时候,由于按键接地,则按键的引脚处为低电平0,弹起后被拉高为1

 #define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPGCON (*(volatile unsigned long *)0x56000060)
#define GPGDAT (*(volatile unsigned long *)0x56000064) /*
* LED1,LED2,LED4对应GPF4、GPF5、GPF6
*/
#define GPF4_out (1<<(4*2))
#define GPF5_out (1<<(5*2))
#define GPF6_out (1<<(6*2)) #define GPF4_msk (3<<(4*2))
#define GPF5_msk (3<<(5*2))
#define GPF6_msk (3<<(6*2)) /*
* S2,S3,S4对应GPF0、GPF2、GPG3
*/
#define GPF0_in (0<<(0*2))
#define GPF2_in (0<<(2*2))
#define GPG3_in (0<<(3*2)) #define GPF0_msk (3<<(0*2))
#define GPF2_msk (3<<(2*2))
#define GPG3_msk (3<<(3*2)) int main()
{
unsigned long dwDat;
// LED1,LED2,LED4对应的3根引脚设为输出
GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
GPFCON |= GPF4_out | GPF5_out | GPF6_out; // S2,S3对应的2根引脚设为输入
GPFCON &= ~(GPF0_msk | GPF2_msk);
GPFCON |= GPF0_in | GPF2_in; // S4对应的引脚设为输入
GPGCON &= ~GPG3_msk;
GPGCON |= GPG3_in; while(){
//若Kn为0(表示按下),则令LEDn为0(表示点亮)
dwDat = GPFDAT; // 读取GPF管脚电平状态 if (dwDat & (<<)) // S2没有按下
GPFDAT |= (<<); // LED1熄灭
else
GPFDAT &= ~(<<); // LED1点亮 if (dwDat & (<<)) // S3没有按下
GPFDAT |= (<<); // LED2熄灭
else
GPFDAT &= ~(<<); // LED2点亮 dwDat = GPGDAT; // 读取GPG管脚电平状态 if (dwDat & (<<)) // S4没有按下
GPFDAT |= (<<); // LED3熄灭
else
GPFDAT &= ~(<<); // LED3点亮
} return ;
}

  

  

  

  

一、GPIO操作的更多相关文章

  1. linux 标准 GPIO 操作

    Linux 提供了GPIO 操作的 API,具体初始化及注册函数在 driver/gpio/lib_gpio.c 中实现.   #include    int gpio_request(unsigne ...

  2. STM32标准库GPIO操作

    STM32标准库GPIO操作 STM32任何外围设备的使用都分为两部分:初始化和使用.体现在代码上就是:(1)有一个初始化函数(2)main函数中的使用 1.初始化GPIO 初始化GPIO函数代码: ...

  3. RK3399/NanoPC-T4开发板使用/sys/class/gpio操作外接GPIO设备-【申嵌视频-RK3399篇】

    实验2:RK3399/NanoPC-T4开发板使用/sys/class/gpio操作外接GPIO设备,比如外接一个LED模块,通过GPIO1_A0管脚 1 介绍   LED模块   Matrix-LE ...

  4. esp32的GPIO操作

    对于任何一款芯片,GPIO接口是其最基本的组成部分,也是一款芯片入门的最基本操作,下面论述下 关于esp32开发版的GPIO操作,本文中重点讲解下 关于如何创建eclipse工程,并通过eclipse ...

  5. 通过数组和枚举简化GPIO操作编码(转)

    源: 通过数组和枚举简化GPIO操作编码

  6. sys下gpio操作

    gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射 * 控制GPIO的目录位于/sys/class/gpio * /sys/class/gpio/export文 ...

  7. 通过数组和枚举简化GPIO操作编码

    在工作中,经常遇到大量使用GPIO作为数字量输入输出来控制设备或采集状态,每次定义操作不同的GPIO针脚既麻烦又容易出错,于是就想要简化操作过程.对于数字量输入来说就是采集对应针脚的状态:而输出则是根 ...

  8. 树莓派高级GPIO库,wiringpi2 for python使用笔记(三)GPIO操作

    GPIO库的核心功能,当然就是操作GPIO了,GPIO就是"通用输入/输出"接口,比如点亮一个LED.继电器等,或者通过iic spi 1-wire等协议,读取.写入数据,这都是G ...

  9. S3C6410 GPIO操作接口

    在后面的驱动学习中,需要对GPIO进行一系列的操作,了解这些引脚操作有助于编码的效率. 一.配置GPIO S3C6410要使用其引脚时,需要对其进行配置,如配置为输入/输出/中断等功能,根据芯片手册来 ...

  10. 基于STM8的GPIO操作---STM8-第一章

    1. 综诉 也许单片机在你看来是一件不太容易的事,但据我所知,单片机,无非就是控制它的GPIO口,所以可以看出,学会如何操作控制GPIO口对使用单片机来说是很重要的一件事. 在装载STM8的单片机中, ...

随机推荐

  1. hive外部表

    创建外部表.数据从HDFS获取  只是建立了链接,hdfs中的数据丢失,表中数据也丢失;hdfs数据增加,表中数据也增加 上传文件 创建外部表 删除文件 执行查询语句,发现少了

  2. codeforces586B

    Laurenty and Shop CodeForces - 586B A little boy Laurenty has been playing his favourite game Nota f ...

  3. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

    题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...

  4. day14 装饰器

    装饰器 本质上就是函数,功能是为其他函数添加附加功能 原则:不修改被修饰函数的源代码,以及调用方式,即完全不能有任何改变 装饰器 = 高阶函数+ 函数嵌套+ 闭包 高阶函数:函数作为参数或者返回一个函 ...

  5. 删除linux下的指定文件

    要求:删除linux下2天前的指定文件 find 文件问题:在 tmp 目录下有大量包含 picture_* 的临时文件,每天晚上 2:00 对一天前的文件进行清理.之前在 crontab 下跑如下脚 ...

  6. 【题解】 bzoj3894: 文理分科 (网络流/最小割)

    bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...

  7. 【BZOJ1814】Ural 1519 Formula 1 (插头dp)

    [BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...

  8. [luogu4264][USACO18FEB]Teleportation

    题解 先吐槽一波题目:便便传送门,出题人还真的有一点厉害的滑稽. 废话不多说. 首先问题的本质就是求如果当这个传送门的端点位于\(y\)的时候,最小的求出总代价,我们设为函数\(f(y)\). 因为这 ...

  9. cf1063A Oh Those Palindromes (贪心)

    给一些字符 求它们能拼成的字符串 的回文子串的个数最大值 对应的那个字符串 就是把相同的都放一起是最优的,排下序就行了... #include<bits/stdc++.h> #define ...

  10. MQTT——取消订阅报文和断开连接报文

    笔者已经把连接报文,订阅报文,发布报文都讲解了完了.而接下来就是取消订阅报文和断开连接报文.和其他的报文比较的话,他们显示非常简单.甚至笔者觉得可以不必要拿出来讲.只要看一下MQTT文档就没有什么不清 ...