十一、S3C2440 裸机 — GPIO

发布时间:2023-07-11  

11.1 GPIO 介绍

11.1.1 GPIO 管脚

GPIO 即是输入输出端口,S3C2440A 包含了 130 个多功能输入/输出口引脚并且它们为如下显示的八个端口:

  • 端口 A(GPA):25 位输出端口

  • 端口 B(GPB):11 位输入/输出端口

  • 端口 C(GPC):16 位输入/输出端口

  • 端口 D(GPD):16 位输入/输出端口

  • 端口 E(GPE):16 位输入/输出端口

  • 端口 F(GPF):8 位输入/输出端口

  • 端口 G(GPG):16 位输入/输出端口

  • 端口 H(GPH):9 位输入/输出端口

  • 端口 J(GPJ):13 位输入/输出端口

GPIO 的功能即是用于 CPU 采集外设信号(INPUT),CPU 输出控制信号(OUTPUT),还有一种功能称为管脚复用功能,即是 GPIO 用于其他信号功能,比如地址,串口等共呢个,GPIO 属于 SOC 的内部外设。

GPIO 的使用需要寄存器配置。

11.1.2 GPIO 寄存器

  • 端口配置寄存器:GPACON --- GPJCON,即配置输入或是输出,还是配置为第三功能

  • 端口数据寄存器:GPADAT---GPJDAT,用于数据的写入或读取

  • 端口上拉寄存器:GPBUP---GPJUP,端口上拉寄存器控制每个端口组的使能/禁止上拉电阻。

    • 当相应位为 0 时使能引脚的上拉电阻。当为 1 时禁止上拉电阻。

    • 如果使能了上拉电阻,那么上拉电阻与引脚的功能设置无关(输入、输出、DATAn、EINTn 等等)

  • 杂项控制寄存器:

    • 此寄存器控制睡眠模式,USB 引脚和 CLKOUT 选择的数据端口上拉电阻。

  • 外部中断控制寄存器:

    • 24 个外部中断由各种信号方式触发。

    • EXTINT 寄存器为外部中断请求配置信号触发方式为低电平触发、高电平触发、下降沿触发、上升沿触发或双边沿触发。

    • 由于每个外部中断引脚包含一个数字滤波器,中断控制可以确认请求信号是否长于 3 个时钟。

11.2 GPIO 控制 LED 

11.2.1 原理图

  

  

  • 从原理图上可以看出,三个灯的控制是由 GPF4 - GPF6 控制的。

  • 由于 LED 由 3.3V 高电平供电,则 GPF4- GPF6 引脚必须要设置为低电平,形成压差点亮 LED

11.2.2 GPF 控制寄存器

  • GPF 主要涉及到三个寄存器:

    • GPFCON:端口配置寄存器,配置各个 I/O 管脚是输入/输出功能,还是第三功能,此寄存器的地址是 0x56000050

    • GPFDAT:数据寄存器,用于管脚发送或是接收数据,地址是 0x56000054

    • GPFUP:上拉寄存器,地址为 0x56000058,需要才用这个寄存器

  • 注意 GPF 控制器的复位值,初始化值即是此值。

  • 具体配置查看芯片手册

11.3 汇编控制 LED

  •  指令的执行时间:

    • 一般单片机指令执行时间是固定的,参考手册,而在高性能的嵌入式 SOC 中,指令执行时间与各方面的因素有关,比如:缓存,内存,硬盘上的传输开销,指令开销,所以在高性能 SOC 上讨论指令的执行时间没有意义。

    • 考虑到多发射、超标量、超流水线、乱序执行、追踪缓存等设计越来越复杂,仅评价单条指令耗时比单片机要困难得多

    • 更由意义的指标是经过统计分析的 CPI、MIPS 数据。

    • 1MHz = 1us

    • 1GHz = 1ns

  • 一般情况下,裸机中精确延时采用定时器,如果延时在 20 us 下的话,定时器不是太合适,需要汇编辅助完成

  • 如果更小的时间要求,那么表示硬件无法满足当前需求

11.4 C语言控制 LED

 makefile

 1 # 获取当前工作目录

 2 CURRDIR = $(shell pwd)

 3 

 4 # 头文件所在目录

 5 INCDIR = $(CURRDIR)

 6 

 7 # 交叉编译工具链的绝对路径

 8 CROSS_COMPILE = ~/work/s3c2440/tools/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-

 9 

10 # 编译器工具

11 AS            = $(CROSS_COMPILE)as

12 LD            = $(CROSS_COMPILE)ld

13 CC            = $(CROSS_COMPILE)gcc

14 CPP            = $(CC) -E

15 AR            = $(CROSS_COMPILE)ar

16 NM            = $(CROSS_COMPILE)nm

17 STRIP        = $(CROSS_COMPILE)strip

18 OBJCOPY        = $(CROSS_COMPILE)objcopy

19 OBJDUMP        = $(CROSS_COMPILE)objdump

20 

21 # 编译器标识位设置

22 CFLAGS :=

23 AFLAGS :=

24 LDFLAGS :=

25 CFLAGS    :=

26 AFLAGSL    :=

27 

28 # 目标文件设置

29 objs := startup.o led.o

30 

31 all: clean s3c2440.bin

32 

33 

34 # 执行编译的过程

35 s3c2440.bin: $(objs)

36     $(LD) -Ttext 0x00000000 -o s3c2440_elf $^

37     $(OBJCOPY) -O binary -S s3c2440_elf $@

38     $(OBJDUMP) -D -m arm s3c2440_elf > s3c2440.dis

39 

40 

41 %.o:%.c

42     $(CC)  -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $<

43 

44 %.o:%.S

45     $(CC)  -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding -c -o $@ $<

46 

47 clean:

48     rm -f *.bin *_elf *.dis *.o


startup.S


 1 .text

 2 .global _start

 3 

 4 _start:

 5     ldr    r0, =0x53000000         @ WATCHDOG寄存器地址

 6     mov    r1, #0x0

 7     str    r1, [r0]                @ 写入0,禁止WATCHDOG,否则CPU会不断重启

 8 

 9     ldr sp, =1024*4             @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K

10                                 @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K

11 

12     bl main                     @ 调用 C 程序的 main 函数

13 

14 halt_loop:

15     b halt_loop


led.c


 1 /**

 2  * 将0x56000050 强转为 unsigned long 型指针,并取这个地址的值

 3  * volatile 关键字:防止编译器优化,在应用层上多线程变量,在嵌入式中外设寄存器

 4  */

 5 #define GPFCON      (*(volatile unsigned long *)0x56000050)

 6 #define GPFDAT      (*(volatile unsigned long *)0x56000054)

 7 #define GPFUP       (*(volatile unsigned long *)0x56000058)

 8 

 9 /** 设置 GPFCON 的 4 5 6 引脚为输出 */

10 #define GPF4_OUT    (1 << (4 * 2))

11 #define GPF5_OUT    (1 << (5 * 2))

12 #define GPF6_OUT    (1 << (6 * 2))

13 

14 static void delay_ms(unsigned long ms);

15 

16 int main(void)

17 {

18     /** 将LED1-3对应的GPF4/5/6三个引脚设为输出 */

19     GPFCON = GPF4_OUT | GPF5_OUT | GPF6_OUT;

20 

21     unsigned long i = 0;

22     while(1){

23         delay_ms(500);

24         GPFDAT = (~(i<<4));         // 根据i的值,点亮LED1,2,4

25         if(++i == 8)

26             i = 0;

27     }

28 }

29 

30 static void delay_ms(unsigned long ms)

31 {

32     unsigned int i;

33 

34     while(ms--) {

35         for(i = 0; i < 1200; i++);

36     }

37 }


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>