06-GPIO实验

GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平、或者通过它们读入引脚的状态──是高电平还是低电平。
?三星 S3C2440,有130个I/O端口,分为A-J九组,可以通过设置寄存器来确定某个引脚用于输入、输出还是特殊功能。在这里通过四个实验介绍GPIO的简单使用。
1、通过汇编语言点亮LED灯
?首先需要看原理图,知道LED与芯片引脚的关系。
????
?由原理图可知,2440引脚作为输出引脚与LED灯连接,要使LED灯点亮,配置相关寄存器为输出引脚,且将该引脚输出低电平即可点亮LED灯。查看2440芯片手册,GPB组引脚控制寄存器地址为:0x56000010,数据寄存器地址为:0x56000014。点亮LED1的汇编代码为:

.text
.global _start
_start:
        LDR     R0,=0x56000010  @ R0设为GPBCON寄存器。此寄存器用于选择端口B各引脚的功能: 是输出、是输入、还是其他
        MOV     R1,#0x00000400
        STR     R1,[R0]                    @ 设置GPB5为输出口, 位[11:10]=0b01
        LDR     R0,=0x56000014     @ R0设为GPBDAT寄存器。此寄存器用于读/写端口B各引脚的数据
        MOV     R1,#0x00000000      @ 此值改为0x00000020,可让LED1熄灭
        STR     R1,[R0]             @ GPB5输出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

编译后下载到TQ2440开发板后效果:led_1点亮

2、通过C语言点亮LED灯
?在使用C语言点亮LED灯时,首先需要进行硬件相关初始化与软件相关初始化。硬件相关有:关看门狗、初始化时钟、初始化SDRAM等,而对于点亮LED灯实验,只需要关闭看门狗即可;软件方面,需要设置返回地址,即设置栈、调用main函数等。首先,汇编代码部分:

 .text
.global _start
_start:
            ldr      r0, =0x53000000     @ WATCHDOG寄存器地址
            mov   r1, #0x0
            str      r1, [r0]                     @ 写入0,禁止WATCHDOG,否则CPU会不断重启
            ldr     sp, =1024*4         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K,nand flash中的代码在复位后会移到内部ram中,此ram只有4K
            bl      main                      @ 调用C程序中的main函数
halt_loop:
            b       halt_loop

C语言部分:

#define GPBCON      (*(volatile unsigned long *)0x56000010)
#define GPBDAT      (*(volatile unsigned long *)0x56000014)

int main()
{
    GPBCON = 0x00000400;    // 设置GPB5为输出口, 位[11:10]=0b01
    GPBDAT = 0x00000000;    // GPB5输出0,LED1点亮
    return 0;
}

Makefile代码为:

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

编译后下载到TQ2440开发板后效果:led_1点亮

3、通过按键控制LED灯点亮
?通过按键控制LED灯时,首先看原理图,了解按键与2440芯片连接的引脚关系。

?使用汇编完成相关初始化,跳转到main函数中,C程序部分通过按键实现LED灯的亮与灭。
汇编代码:

.text
.global _start
_start:
            ldr     r0, =0x53000000     @ WATCHDOG寄存器地址
            mov     r1, #0x0
            str   r1, [r0]              @ 写入0,禁止WATCHDOG,否则CPU会不断重启
            ldr     sp, =1024*4         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K,nand flash中的代码在复位后会移到内部ram中,此ram只有4K
            bl      main                @ 调用C程序中的main函数
halt_loop:
            b       halt_loop
C语言代码:
#define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT      (*(volatile unsigned long *)0x56000054)
#define GPBCON      (*(volatile unsigned long *)0x56000010)
#define GPBDAT      (*(volatile unsigned long *)0x56000014)

/*
 * LED1,LED2,LED3、LED4对应GPB5、GPB6、GPB7、GPB8
 */
#define GPB5_out    (1<<(5*2))
#define GPB6_out    (1<<(6*2))
#define GPB7_out    (1<<(7*2))
#define GPB8_out    (1<<(8*2))

#define GPB5_msk    (3<<(5*2))
#define GPB6_msk    (3<<(6*2))
#define GPB7_msk    (3<<(7*2))
#define GPB8_msk    (3<<(8*2))

/*
 * K1,K2,K3,K4对应GPF1、GPF4、GPF2、GPF0
 */
#define GPF0_in     (0<<(0*2))
#define GPF1_in     (0<<(1*2))
#define GPF2_in     (0<<(2*2))
#define GPF4_in     (0<<(4*2))

#define GPF0_msk    (3<<(0*2))
#define GPF1_msk    (3<<(1*2))
#define GPF2_msk    (3<<(2*2))
#define GPF4_msk    (3<<(4*2))

int main()
{
        unsigned long dwDat;
        // LED1,LED2,LED3,LED4对应的4根引脚设为输出
        GPBCON &= ~(GPB5_msk | GPB6_msk | GPB7_msk | GPB8_msk);
        GPBCON |= GPB5_out | GPB6_out | GPB7_out | GPB8_out;

        // K1,K2,K3,K4对应的4根引脚设为输入
        GPFCON &= ~(GPF0_msk | GPF1_msk | GPF2_msk | GPF4_msk);
        GPFCON |= GPF0_in | GPF1_in | GPF2_in | GPF4_in;

        while(1){
            //若Kn为0(表示按下),则令LEDn为0(表示点亮)
            dwDat = GPFDAT;             // 读取GPF管脚电平状态

            if (dwDat & (1<<1))        // K1没有按下
                GPBDAT |= (1<<5);       // LED1熄灭
            else
                GPBDAT &= ~(1<<5);      // LED1点亮

            if (dwDat & (1<<4))         // K2没有按下
                GPBDAT |= (1<<6);       // LED2熄灭
            else
                GPBDAT &= ~(1<<6);      // LED2点亮

            if (dwDat & (1<<2))        // K3没有按下
                GPBDAT |= (1<<7);       // LED3熄灭
            else
                GPBDAT &= ~(1<<7);      // LED3点亮

            if (dwDat & (1<<0))         // K4没有按下
                GPBDAT |= (1<<8);       // LED4熄灭
            else
                GPBDAT &= ~(1<<8);      // LED4点亮
    }

    return 0;
}

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

编译后下载到TQ2440开发板后效果:
? ? ?

4、通过延时循环点亮LED灯
?与使用点亮一盏LED灯类似,通过循环与延时函数即可完成另LED循环闪烁的效果。

实验源码

原文地址:http://blog.51cto.com/yinsuifeng/2058789

时间: 2024-11-15 00:39:27

06-GPIO实验的相关文章

Beaglebone Back学习四(GPIO实验)

GPIO Beaglebone Back开发板引出了92个引脚,其中只有65个GPIO口可通过配置使用,由于引脚具有"复用"的特性,大约每个引脚有8种工作模式(Beagle System Reference Manual),默认情况下,设为Mode7.由于P8扩展部分的引脚功能相对简单,复用不多,故项目功能复杂时,最好选择P8上的GPIO口. 对GPIO口的操作,主要有三个步骤 1 选择GPIO口根据以下两表,确定使用那个GPIO口,该表也可以在BBB_SRM文件中找到. (1)拉电流

02-JZ2440裸机学习之GPIO实验【转】

本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/54910717 版权声明:本文为博主原创文章,转载请注明http://blog.csdn.net/fengyuwuzu0519. 一:汇编点亮一个LED 1看原理图 2设置寄存器,配置引脚 3代码现 [cpp] view plain copy print? @*************************************************************

JZ2440开发板之GPIO实验,遇到的链接语句的问题

自己写的 crt0.s , led.c , Makefile 文件,下到开发板上后始终无法运行,但是将led.c文件拷贝到光盘提供的对应程序中编译,结果可以运行.推测是 crt0.s 或者 Makefile的问题. 通过比对crt0.s发现没有问题.应该是Makefile的问题. 发现自己写的Makefile中的链接语句是: 1 arm-linux-ld -Ttext 0x00000000 -g led.o crt0.o -o led_elf 光盘中对应的语句是: 1 arm-linux-ld

JZ2440开发板之GPIO实验

(1)Makefile 文件 命令中有一个参数是: Text 00000000      .引申出了2440的两种启动方式:NAND启动和NOR启动 NOR Flash属于内存类期间,它可以像内存一样读,但是不能像内存一样写,要写的话必须经过复杂的步骤 NAND Flash不属于内存类设备,没有地址线. NOR启动时,0地址在NOR上 NAND启动时,0地址在片内SRAM上,

Java实验四(待补充)

课程:Java程序设计          班级: 1351 姓名:王玮怡                学号:20135116 成绩:             指导教师:娄嘉鹏       实验日期:2015.06.03 实验密级:         预习程度:             实验时间:14:00~20:00 仪器组次:        必修/选修:选修       实验序号:3 实验名称:敏捷开发与XP实践 实验目的与要求: 1.没有Linux基础的同学建议先学习<Linux基础入门(新

20135239益西拉姆第四次实验报告

北京电子科技学院(BESTI) 实验报告 课程:JAVA第四次实验报告 班 级: 1352 姓 名:益西拉姆 学 号:20135239 成 绩: / 指导教师: 娄嘉鹏 实验日期: 2015.06.09 实验密级: / 预习程度: / 实验时间:15:00--18:00 仪器组次:39 必须/选修: 选修 实验序号:04 实验名称: 第四次实验 实验仪器: 名称 型号 数量 PC机 DELL 1 实验内容: 1:编写网络通信程序.(基于TCP) 2:对通信内容使用对称加密算法进行加密. 3:使用

实验三 Java猜数字游戏开发

课程:Java实验   班级:201352     姓名:程涵  学号:20135210 成绩:             指导教师:娄佳鹏   实验日期:15.06.03 实验密级:         预习程度:             实验时间: 仪器组次:          必修/选修:选修          实验序号:3 实验名称:     Java猜数字游戏开发 (姬梦馨.程涵小组) 一.实验目的与要求: 通过编写Java的应用系统综合实例——猜数字游戏,总结.回顾和实践面向对象的编程思想

DSP5509的GPIO学习-第5篇

1. 目前已经不局限于仅仅把实验搞清楚了,要深入去探究内部的原理,本章看下GPIO实验 2. 在CCS启动的时候,提示,这个问题是什么,XDAIS是什么?XDAIS (eXpress DSP Algorithm Interoperability Standard) See details below... Unrecognized product of type 'com.ti.rtsc.XDAIS' is required by project '5509gpio' - please inst

MDK,关于 STM32F4 配置失败, GPIO, USART 写入值没反应

需要先将RCC->AHB1ENR寄存器的对应时钟打开! 下面做个测试: 配置GPIO实验 没有打开时钟使能,配置无反应: 打开时钟使能后,可以成功写入数据: 配置USART实验 RCC 未开启时钟: RCC 开启时钟后: 发现TC标志位置1,说明成功写入. 原文地址:https://www.cnblogs.com/qiyuexin/p/8214550.html

Adding an On/Off switch to your Raspberry Pi

http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi#article_f5 Which Switch? Aaron Shaw Pulling the plug on your Pi without an orderly shutdown can corrupt the SD card. Also, many users prefer a convenient sw