S3C2440裸机------GPIO

发布者:以泉换泉最新更新时间:2021-10-14 来源: eefocus关键字:S3C2440  裸机  GPIO 手机看文章 扫描二维码
随时随地手机看文章

1.S3C2440GPIO简单介绍

GPIO即General-purpose input/output ,这些管脚除了可以用作输入输出外,还可以配置成一些其他的功能,例如I2C,UART等,其实就是管脚复用的思想。

所有的这些管脚主要通过下面的寄存器进行控制,


2.JZ2440原理图

        

从上面的原理图截图中我们可以看到:


1.我们的nLED_1,nLED_2,nLED_4是连接到3.3V电源上的,所以我们的管脚需要输出低电平,LED灯才会亮。


2.我们的nLED_1,nLED_2,nLED_4是连接到s3c2440的GPF4,GPF5,GPF6上面的。


另外,在原理图中还有如下知识点。

3.控制GPF管脚

我们需要控制GPF引脚控制LED灯,下面的问题就是我们怎么让GPF4输出0,


a.首先把该管脚配置为输出引脚,


b.设置它的状态。


然后我们在s3c2440的芯片手册中找到GPF引脚相关的寄存器。

我们通过设置GPFCON寄存器的[9:8]为01将GPF4配置为输出功能。把0000,0001,0000,0000=0x0100写到地址0x56000050上面。

设置PGFDAT[4]为0,则该管脚会输出低电平,此时LED点亮。把0000000=0x00写到地址0x56000054上面。


设置PGFDAT[4]为1,则该管脚会输出高电平,此时LED熄灭。把00010000=0x10写到地址0x56000054上面。


另外有一点需要注意,就是我们的CPU里面有R0,R1,.....R15,这些寄存器我们可以直接访问,而像GPFCON,GPFDAT这些寄存器我们访问的时候要通过地址去访问。


下面开始写程序点亮LED。


4.汇编语言点亮GPF4

/**************************************

*点亮LED, GPF4.

**************************************/

.text

.global _start

_start:

//把0x100写到地址0x56000050上,配置gpf4为输出引脚,

    ldr r1, =0x56000050

ldr r0,=0x100

str r0,[r1]

//把0x00写到地址0x56000054上,设置gpf4输出低电平, 

    ldr r1, =0x56000054

ldr r0,=0x00

str r0,[r1]

//死循环

halt:

    b halt

然后可以用下面的三行命令进行编译


arm-linux-gcc -c -o led_on.o led_on.S

arm-linux-ld -Ttext 0 led_on.o -o led_on.elf

arm-linux-objcopy -O binary -S  led_on.elf led_on.bin

用命令行敲容易出错,我们把上面的命令写到一个makefile里面:


all:

arm-linux-gcc -c -o led_on.o led_on.S

arm-linux-ld -Ttext 0 led_on.o -o led_on.elf

arm-linux-objcopy -O binary -S  led_on.elf led_on.bin

 

clean:

rm *.bin  *.o  *.elf

编译产生bin文件之后,打开windows的命令行,首先进入bin文件所在的目录,然后执行oflash led_on.bin,下载到开发板中即可执行。


5.C语言点亮GPF4

我们编写如下C语言代码控制LED,


int main()

{

    unsigned int *pGPFCON = 0x56000050;

unsigned int *pGPFDAT = 0x56000054;

 

/*配置GPF4为输出引脚*/

*pGPFCON = 0x100;

 

/*配置GPF4输出0*/

*pGPFDAT = 0;

}

C语言代码写完之后,存在两个问题


1.我们写出了main函数,那么谁来调用这个main函数,


2.main函数中的变量保存在内存中,这个内存地址是多少。


答:我们需要写一段汇编代码,给main函数设置内存,调用main函数。


我们编写如下汇编代码


.text

.global _start

 

_start:

 

     /*设置内存:SP栈*/

     ldr sp, =4096                /*2440设置为nand启动时,片内4K内存地址为0,我们把栈设置这4K内存的顶部,*/

     //led sp, =0x40000000 + 4096 /*nor启动时,片内4K内存的地址是0x40000000,我们同样也把栈设置在4K内存的顶部。 */

 

     /* 调用main函数*/

     bl main

 

 halt:

     b halt

然后编写makefile文件如下:


all:

arm-linux-gcc -c -o led.o led.c

arm-linux-gcc -c -o start.o start.S

arm-linux-ld -Ttext 0 led.o  start.o -o led.elf

arm-linux-objcopy -O binary -S  led.elf led.bin

arm-linux-objdump -D led.elf  > led.dis

clean:

rm *.bin  *.o  *.elf   *.dis

编译完之后下载到开发板中发现灯不亮,经查找原因是链接时文件顺序写错了,将上面makefile文件里面的


arm-linux-ld -Ttext 0 led.o  start.o -o led.elf    修改为    arm-linux-ld -Ttext 0 start.o led.o -o led.elf。


然后重新编译后程序正确。


6.循环点亮LED

首先我们把之前的汇编代码进行了修改,关掉了看门狗,另外也自动的适配nand启动和nor启动,修改后的汇编代码如下。


 

.text

.global _start

 

_start:

 

/* 关闭看门狗 */

ldr r0, =0x53000000

ldr r1, =0

str r1, [r0]

 

/* 设置内存: sp 栈 */

/* 分辨是nor/nand启动

* 写0到0地址, 再读出来

* 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动

* 否则就是nor启动

*/

mov r1, #0

ldr r0, [r1] /* 读出原来的值备份 */

str r1, [r1] /* 0->[0] */ 

ldr r2, [r1] /* r2=[0] */

cmp r1, r2   /* r1==r2? 如果相等表示是NAND启动 */

ldr sp, =0x40000000+4096 /* 先假设是nor启动 */

moveq sp, #4096  /* nand启动 */

streq r0, [r1]   /* 恢复原来的值 */

 

bl main

 

halt:

b halt

c语言源文件如下


 

#include "s3c2440_soc.h"

 

void delay(volatile int d)

{

while (d--);

}

 

int main(void)

{

int val = 0;  /* val: 0b000, 0b111 */

int tmp;

 

/* 设置GPFCON让GPF4/5/6配置为输出引脚 */

GPFCON &= ~((3<<8) | (3<<10) | (3<<12));

GPFCON |=  ((1<<8) | (1<<10) | (1<<12));

 

/* 循环点亮 */

while (1)

{

tmp = ~val;

tmp &= 7;

GPFDAT &= ~(7<<4);

GPFDAT |= (tmp<<4);

delay(100000);

val++;

if (val == 8)

val =0;

}

 

return 0;

}

 

C语言头文件如下


 

#ifndef  __S3C2440_SOC_H

#define  __S3C2440_SOC_H

 

#define     __REG(x) (*(volatile unsigned int *)(x)) 

 

/*I/O port*/

#define     GPACON                   __REG(0x56000000)  //Port A control                           

#define     GPADAT                   __REG(0x56000004)  //Port A data                                      

#define     GPBCON                   __REG(0x56000010)  //Port B control                                   

#define     GPBDAT                   __REG(0x56000014)  //Port B data                                      

#define     GPBUP                    __REG(0x56000018)  //Pull-up control B                                

#define     GPCCON                   __REG(0x56000020)  //Port C control                                   

#define     GPCDAT                   __REG(0x56000024)  //Port C data                                      

#define     GPCUP                    __REG(0x56000028)  //Pull-up control C                                

#define     GPDCON                   __REG(0x56000030)  //Port D control                                   

#define     GPDDA1T                  __REG(0x56000034)  //Port D data                                      

#define     GPDUP                    __REG(0x56000038)  //Pull-up control D                                

#define     GPECON                   __REG(0x56000040)  //Port E control                                   

#define     GPEDAT                   __REG(0x56000044)  //Port E data                                      

#define     GPEUP                    __REG(0x56000048)  //Pull-up control E                                

#define     GPFCON                   __REG(0x56000050)  //Port F control                                   

#define     GPFDAT                   __REG(0x56000054)  //Port F data                                      

#define     GPFUP                    __REG(0x56000058)  //Pull-up control F                                

#define     GPGCON                   __REG(0x56000060)  //Port G control                                   

#define     GPGDAT                   __REG(0x56000064)  //Port G data                                      

#define     GPGUP                    __REG(0x56000068)  //Pull-up control G                                

#define     GPHCON                   __REG(0x56000070)  //Port H control                                   

#define     GPHDAT                   __REG(0x56000074)  //Port H data                                      

#define     GPHUP                    __REG(0x56000078)  //Pull-up control H                                

[1] [2]
关键字:S3C2440  裸机  GPIO 引用地址:S3C2440裸机------GPIO

上一篇:S3C2440框架与启动过程
下一篇:S3C2440开发板裸机程序系列01--流水灯

推荐阅读最新更新时间:2024-11-07 18:28

基于S3C2440嵌入式系统主板的电磁兼容性设计
作者:许凯华,董淑云,刘玉华,胡立祥 华中师范大学  随着电子设备的频率越来越高,世界各国对电子产品电磁辐射标准的执行变得越来越严格,如何保证能在有限时间很好地在设计阶段发现并解决EMI/EMC问题非常重要,而PCB往往是一个电子系统的核心构成部分,一个经仔细电磁干扰设计的PCB板,能大幅度降低阻抗不匹配、传输线问题、信号互相耦合等现象引发的信号反射、延迟等线路不稳定因素,同时也可达到降低电磁辐射发射干扰,大大提高系统的稳定性和可靠性。本文将以嵌入式系统主板为平台,运用 EMIStream仿真软件,并采用源端串联端接阻抗的方法分析了解决嵌入式高速主板存在的电磁干扰问题。 1 电磁兼容性 1.1 电磁兼容和电磁干扰
[嵌入式]
S3C2440之MMU驱动代码模板(RealView MDK)
好记心不如烂笔头,为方便以后查看代码及代码重复利用,这里贴出自己写的S3C2440 MMU代码库。使用友善MINI2440开发板,开发环境为RealView MDK 4.22。 该源码结构简单明了,原始工程下载地址: 点击打开链接 Register 0, ID code register: unsigned int MMU_ReadID(void) { unsigned int id; __asm( mrc p15, 0, id, c0, c0, 0 ); return id; } Register 0, cache type register: unsigned int
[单片机]
STM32之GPIO按键实验
实验板:带有按键的Stm32开发板一块,本人用得是Open107V实验板,型号是107的 库函数:STM32官方3.5的库 其他材料:ST-LINK、跳线若干 实验原理:按键实验和LED实验类似, GPIO点灯是向led的pin脚输出高低电平, 而按键则是向pin口输入高低电平。 对于按键有两种输入模式可以选择, 一,采用上拉输入模式,二,采用浮动浮空输入模式,上拉输入模式在没有按键按下的时候是默认是高电平。符合这个要求。原理图如下: 实验描述:PE5连接到key1,用扫描的方式查询是否有按键按下,key1按下时,LED1状态取反。 库文件:startup/start_stm32f10x_cl.s CMSIS/cor
[单片机]
ADI 推出可编程低功耗 GPIO/ 键盘控制器
北京2011年9月14日电 /美通社亚洲/ -- Analog Devices, Inc.( http://www.analog.com/zh/pr0909 ) (ADI),全球领先的高性能信号处理解决方案供应商,最近推出 GPIO(通用输入/输出)端口扩展器和键盘矩阵控制器 ADP5585 ( http://www.analog.com/zh/pr0909/adp5585 )和 ADP5589 ( http://www.analog.com/zh/pr0909/adp5589 ),适用于需要扩展 I/O 线路或最大为 QWERTY 尺寸的机械键盘的设备。在业界同类器件中,新型 GPIO/ 键盘控制器的工作功耗最低,封装最小,并且
[嵌入式]
02-JZ2440裸机学习之GPIO实验
一:汇编点亮一个LED 1看原理图 2设置寄存器,配置引脚 3代码现 @****************************************************************************** @ File:led_on.S @ 功能:LED点灯程序,点亮LED1 @****************************************************************************** .text .global _start _start: LDR R0,=0x56000050 @ R0设为G
[单片机]
02-JZ2440<font color='red'>裸机</font>学习之<font color='red'>GPIO</font>实验
嵌入式系统快速重启的研究
  前言   随着计算机技术的发展,工业技术也跟着迅猛发展起来了,而伴随着嵌入式的应用也很变得非常广泛。   ARM芯片为了保证指令运行的实时性,指令没有直接在FLASH里面运行,而是先把FLASH里面的数据拷贝到读取速度比较快的SDRAM里面,然后运行,这样就提高了运行速度。但是由于程序的固定性,在我们重新启动的时候,会再次拷贝代码。我们知道SDRAM是掉电不保存数据的,但是,如果SDRAM没有掉电,里面的数据是不会丢失的。而我们重启的时候并没有给芯片断电,而这个时候系统又要重新拷贝一次代码,造成了时间的浪费。   当然在工业上,我们的系统启动起来之后,往往重新启动的可能性较少,这样每次启动浪费的时间也就可以忽略不计了。不
[单片机]
嵌入式系统快速重启的研究
DATASHEET寄存器封装陷阱--S3C2440为例
在封装控制器寄存器的时候,一般首先看寄存器的地址是否连续,以S3C2440的NANDFLASH控制器为例 从上表可以看到,寄存器的地址是连续的,都是相隔4位,一般都会直接封装成这样子 封装完毕。 在配置某一寄存器的时候,虽然寄存器的地址是连续的,但有的寄存器是16位,有的寄存器是8位,配置的时候,使用指针需要相当注意(陷阱在此), 当寄存器是8位的时候,需要强制转换指针,如 typedef volatile unsigned char VU8 VU8 *p=(VU8 *)&NandS3C2440- NFADDR; 强制转换后才能正确配置寄存器,不然代码虽然能通过编译,但实际没法实现功能 。
[单片机]
夏普发布4.7英寸新机Aquos mini:防水防尘
    6月30日消息,在今年之前,智能手机往往“以大为尊”,大尺寸机型往往才会有着强悍的配置,而小尺寸机型往往是各种低配版,毫无人权可言。进入 2016年,苹果iPhone SE开头,刷新了小屏手机的硬件规格,一大波安卓手机厂商也及时跟进,推出了许多不错的小屏机型。近日,小尺寸智能手机市场中又多了一名成员,其来自夏普,屏幕尺寸仅有4.7英寸,命名夏普Aquos mini。 夏普Aquos mini   昨日,夏普面向本地运营商Rakuten Mobile推出了这款强悍的“小钢炮”夏普Aquos mini,型号SH-03H。其机身尺寸为126×66×9mm(略厚),很容易放进口袋,屏占比超过73%,胜于iPhone 6s(65%
[家用电子]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved