历史上的今天
返回首页

历史上的今天

今天是:2024年08月30日(星期五)

正在发生

2019年08月30日 | S5PV210开发 -- GPIO

2019-08-30 来源:eefocus

上一篇文章中,想要让LED亮起来、蜂鸣器响起来,需要控制对应的引脚。但是使用程序该如何控制引脚的电平变化呢?这就是这篇要讲的内容了。


一、什么是 GPIO

GPIO 是 General Purpose Input Output的简称。即,通用输入/输出。


二、S5PV210 GPIO

查看 S5PV210 芯片手册 第 92 页


(1)概述

S5PV210包含237个多功能输入/输出端口引脚和142个存储器端口引脚。总共有34个端口组和2个内存端口组,


如下所示:

•GPA0:8个输入/输出端口 - 2xUART带流量控制

•GPA1:4个输入/输出端口 - 2xUART不带流量控制或1xUART带流量控制

•GPB:8个输入/输出端口 - 2个SPI

•GPC0:5输入/输出端口 - I2S,PCM,AC97

•GPC1:5输入/输出端口 - I2S,SPDIF,LCD_FRM

•GPD0:4个输入/输出端口 - PWM

•GPD1:6输入/输出端口 - 3xI2C,PWM,IEM

•GPE0,1:13输入/输出端口 - 摄像机I / F

•GPF0,1,2,3:30输入/输出端口 - LCD I / F

•GPG0,1,2,3:28输入/输出端口 - 4xMMC通道(通道0和2支持4位和8位模式,但通道1,而通道3只支持4位模式)

•GPH0,1,2,3:32输入/输出端口 - 键盘,外部唤醒(最多32位)。 (GPH *团体在Alive地区)

•GPI:低功耗I2S,PCM(不使用输入/输出端口),PDN配置用于断电AUDIO_SS PDN寄存器。

•GPJ0,1,2,3,4:35输入/输出端口 - 调制解调器IF,CAMIF,CFCON,小键盘,SROM ADDR [22:16]

•MP0_1,2,3:20输入/输出端口 - EBI控制信号(SROM,NF,OneNAND)

•MP0_4,5,6,7:32输入/输出存储器端口 - EBI(有关EBI配置的更多信息,请参阅第5章,和6)

•MP1_0〜8:71个DRAM1端口(不使用输入/输出端口)

•MP2_0〜8:71个DRAM2端口(不使用输入/输出端口)

•ETC0,ETC1,ETC2,ETC4:28个输入/输出ETC端口 - JTAG,工作模式,复位,时钟(ETC3是预留)



GPIO的主要功能包括:

•控制146个GPIO中断

•控制32个外部中断

•237个多功能输入/输出端口

•除了GPH0,GPH1,GPH2和GPH3(GPH *引脚是活动焊盘)之外,控制睡眠模式下的引脚状态.


GPIO由两部分组成,即活动部分和非活动部分。 在活着的部分供电睡眠模式,但在它的外部部分是不一样的。 因此,活动部分中的寄存器在睡眠模式下保持其值。


三、GPIO 寄存器

我们上篇文章讲到,控制LED的GPIO引脚。



当GPJ0_3、GPJ0_4、GPJ0_5、PWMTOUT1 为低电平时,发光二极管发光。


我们先点亮一个LED,配置GPJ0_3寄存器。


查看 S5PV210 芯片手册 第 172 页


端口组GPJ0控制寄存器,有六个控制寄存器,分别是GPJ0CON,GPJ0DAT,GPJ0PUD,GPJ0DRV,GPJ0CONPDN和端口组GPJ0控制寄存器中的GPJ0PUDPDN。


(1)GPJ0CON 寄存器  (配置寄存器) 将其配置成输出模式

GPJ0CON, R/W, Address = 0xE020_0240


GPJ0CON[15:12] 0001 = Output


设置:

GPJ0CON 地址为 0xE020_0240 ,然后要将 GPJ0CON[15:12] 进行位操作,使其变为0001,即输出模式。


位操作方法,参看:C语言再学习 -- 位操作


GPJ0CON  &= ~(0x0f<<12);    


GPJ0CON  |= 0x01<<12;

 

(2)GPJ0DAT 寄存器 (数据寄存器)LED 低电平亮,高电平灭

GPJ0DAT, R/W, Address = 0xE020_0244


当端口被配置为输入端口时,相应的位是引脚状态。 当端口被配置为输出时端口,引脚状态与相应的位相同。当端口被配置为功能引脚时,未定义值将被读取。


设置:


GPJ0DAT 的地址为 0xE020_0244,然后GPJ0DAT[3]是输出端口,低电平时LED灯亮,高电平时LED灯灭。


位操作方法:


GPJ0DAT |= 0x01<<3;          @ 高电平

GPJ0DAT &= ~(0x01<<3);   @ 低电平


(3)GPJ0PUD 寄存器(上下拉电阻控制寄存器 )

GPJ0PUD, R/W, Address = 0xE020_0248

GPJ0PUD[n] [2n+1:2n] 00 = Pull-up/ down disabled


设置:


GPJ0PUD 的地址为 0xE020_0248,我们不需要上下拉,因此 GPJ0PUD [7:6]  00 = Pull-up/ down disabled


位操作方法:


GPJ0PUD &= ~0x0c<<4;


(4)总结

主要为这三个寄存器,跟剩余是三个寄存器关系不大。

设置方式:


1、将GPJ0_3管脚设置为输出功能管脚

  GPJ0CON   0xE020_0240 

  bit[15:12]为0001,表示输出功能


 


  位操作方法:

    GPJ0CON  &= ~(0x0f<<12);    

    GPJ0CON  |= 0x01<<12;


 


2、操作GPJ0_3管脚输出高低电平

  GPJ0DAT   0xE020_0244

  bit[3] 为1:向三极管输出高电平,LED1灭

                0:向三极管输出低电平,LED1亮


 


  位操作方法:

    GPJ0DAT |= 0x01<<3;          @ 高电平

    GPJ0DAT &= ~(0x01<<3);   @ 低电平


 


3、禁用GPJ0_3管脚内部的上下电阻

  GPJ0PUD   0xE020_0248 

  bit[7:6]为00,表示禁止内部上下拉电阻


 


  位操作方法:

    GPJ0PUD &= ~(0x0c<<4);


四、编写驱动程序

此处用到关键字 volatile,参看:C语言再学习 -- 关键字volatile


和预处理器 #define,参看:C语言再学习 -- C 预处理器


#define GPJ0CON *((volatile unsigned int*)0xE0200240)

#define GPJ0DAT *((volatile unsigned int*)0xE0200244)

#define GPJ0PUD *((volatile unsigned int*)0xE0200248)

 

//延时

void delay (unsigned int);

void led_test (void)

{

//配置相应管脚输出功能 

GPJ0CON &= ~(0X0f<<12);

GPJ0CON |= 0X01<<12;

//禁止内部上拉下拉功能

GPJ0PUD &= ~(0X0c<<4);

 

while (1)

{

//LED灭

GPJ0DAT |= 0x01<<3;

    delay (0x100000);

 

//LED亮

GPJ0DAT &= ~(0x01<<3);

delay (0x100000);

}

}

 

void delay (unsigned int n )

{

unsigned int i = 0;

for (i = n; i !=0; i--);

}

五、编译

这个就要用到交叉编译器了,参看:S5PV210开发 -- 交叉编译器


下面的编译器命令选项,参看:gcc,g++-GNU工程的C和C++编译器中文手册


(1)生成led.o文件 (不要使用标准库)

arm-none-linux-gnueabi-gcc -march=armv5te -c led.c -o led.o -nostdlib


    -march=armv5te  指定生成指令的版本


    -nostdlib: 链接时不要使用标准库文件


(2)生成 led.elf 文件

arm-none-linux-gnueabi-ld -nostartfiles -nostdlib -Ttext=0xc0008000 -eled_test led.o -o led.elf

     -nostartfiles: 链接时不要添加标准启动信息

     -nostdlib: 链接时不要使用标准库文件

     -Ttext:指定代码段的起始地址

     -e:指定入口函数,默认情况下找的是_start


 


file led.elf查看文件信息


t# file led.elf 

led.elf: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped

(3)将elf格式的文件转换为纯机器指令的文件

arm-none-linux-gnueabi-objcopy -O binary led.elf led.bin


六、下载led.bin到开发板并执行

首先要设置serverip(即tftp服务器的ip)、ipaddr(单板ip)和ethaddr(单板的MAC地址)。使其与主机在同一网段且不与其他设备冲突即可。


参看:S5PV210开发 -- Nand和e-MMC区别以及系统更新


验证一下能不能ping 通。

使用 tftp 将 led.bin下载到 SDRAM 的 0xc0008000 位置


tftp工具使用,参看:Hi3516A开发--环境搭建工具


    tftp c0008000 led.bin


    go c0008000


OK,此时 led 在不停的闪动。


七、蜂鸣器响起来

详细内容我就不讲了,和上面的 led 分析一样一样的。


(1)寄存器配置

GPD0CON, R/W, Address = 0xE020_00A0

GPD0CON[2] [11:8]

  GPD0CON  &= ~(0x0f<<8);    

  GPD0CON  |= 0x01<<8;


GPD0DAT, R/W, Address = 0xE020_00A4)

GPD0DAT[3:0] [3:0]

    GPD0DAT |= 0x01<<2;          @ 高电平

    GPD0DAT &= ~(0x01<<2);   @ 低电平


GPD0PUD, R/W, Address = 0xE020_00A8

GPD0PUD[n] [2n+1:2n] 00 = Pull-up/ down disabbuzzer

    GPD0PUD &= ~(0x0c<<1);


(2)编写驱动程序

#define GPD0CON *((volatile unsigned int*)0xE02000A0)  

#define GPD0DAT *((volatile unsigned int*)0xE02000A4)  

#define GPD0PUD *((volatile unsigned int*)0xE02000A8)  

  

//延时  

void delay (unsigned int);  

void buzzer_test (void)  

{  

    //配置相应管脚输出功能   

    GPD0CON  &= ~(0x0f<<8);    

    GPD0CON  |= 0x01<<8;

 

 

    //禁止内部上拉下拉功能  

    GPD0PUD &= ~(0x0c<<1);

  

    while (1)  

    {  

        //蜂鸣器响  

        GPD0DAT |= 0x01<<2; 

        delay (0x100000);     

  

        //蜂鸣器不响亮  

        GPD0DAT &= ~(0x01<<2);  

        delay (0x100000);  

    }  

}  

  

void delay (unsigned int n )  

{  

    unsigned int i = 0;  

    for (i = n; i !=0; i--);  

}  

(3)编译

编译步骤繁琐,可以写成 Makefile 


buzzer: buzzer.o

arm-none-linux-gnueabi-ld -nostartfiles -nostdlib -Ttext=0xc0008000 -e buzzer_test -o buzzer buzzer.o

arm-none-linux-gnueabi-objcopy -O binary buzzer buzzer.bin

 

buzzer.o: buzzer.c

arm-none-linux-gnueabi-gcc -march=armv5te -nostdlib -c -o buzzer.o buzzer.c

 

clean:

rm -vf buzzer.o buzzer buzzer.bin buzzer.s

推荐阅读

史海拾趣

明微公司的发展小趣事

随着全球半导体行业向中国市场的转移,明微公司意识到拓展海外市场的重要性。为了加快海外市场拓展步伐,公司积极加强与国际知名企业的合作与交流,引进先进的技术和管理经验。同时,公司还积极参加国际展会和论坛等活动,提升品牌影响力。这些举措使明微公司在国际市场上逐渐树立起良好的口碑和形象。

COILCRAFT公司的发展小趣事

在追求产品性能的同时,COILCRAFT公司也非常注重产品质量和环保。公司采用先进的设备和工艺,确保产品的稳定性和可靠性。此外,公司还积极采取措施减少能源和资源的消耗,优化生产流程,降低废物排放。这种对质量和环保的坚持使得COILCRAFT在行业中树立了良好的形象。

EDI [Electronic devices inc.]公司的发展小趣事

在1950年代,Eclipse Magnetics公司决定将他们的磁铁涂上红色,并与马蹄形标志和公司颜色相匹配。这个简单的改变在当时看似微不足道,但却成为了一个重要的转折点。红色磁铁不仅提升了产品的视觉吸引力,还增强了品牌识别度。随着红色磁铁的广泛应用,Eclipse Magnetics开始逐渐在电子行业中崭露头角。

Datapro International Inc公司的发展小趣事

随着全球化的加速和市场竞争的加剧,Datapro International Inc公司开始加快国际化发展的步伐。他们积极拓展海外市场,并在全球范围内建立了完善的销售和服务网络。

在国际化发展的过程中,Datapro International Inc公司遇到了许多挑战和困难。然而,他们凭借坚定的信念和不懈的努力,成功克服了这些困难。他们深入了解当地市场和文化背景,并根据市场需求和客户需求不断调整产品和服务策略。这些努力使得Datapro International Inc公司在海外市场取得了显著的成果。

南京绿芯(Grenergy)公司的发展小趣事

为了进一步提升技术实力和市场竞争力,Datapro International Inc公司开始寻求与国内外知名企业的战略合作。他们与一些在数据存储和处理领域具有领先地位的企业建立了合作关系,共同研发新产品、拓展新市场。

通过战略合作,Datapro International Inc公司获得了更多的技术资源和市场机会。同时,他们也从合作伙伴身上学到了许多先进的管理理念和市场策略。这些经验和知识为Datapro International Inc公司的未来发展提供了有力的支持。

Helicomm公司的发展小趣事

为了进一步提升技术实力和市场竞争力,Datapro International Inc公司开始寻求与国内外知名企业的战略合作。他们与一些在数据存储和处理领域具有领先地位的企业建立了合作关系,共同研发新产品、拓展新市场。

通过战略合作,Datapro International Inc公司获得了更多的技术资源和市场机会。同时,他们也从合作伙伴身上学到了许多先进的管理理念和市场策略。这些经验和知识为Datapro International Inc公司的未来发展提供了有力的支持。

问答坊 | AI 解惑

数字电路非常基础的教材

数字电路非常基础的教材…

查看全部问答>

来讨论下VHDL里边的库吧

最近用VHDL编程,发现有很多时候遇到《Error (10327): VHDL error at and2.vhd(11): can\'t determine definition of operator \"\"+\"\" -- found 0 possible definitions》这样的问题,开始不知道为什么,后来在知道不同的数据类型的运算是定义在 ...…

查看全部问答>

你如何定义射频?

此前一直在说射频,但是具体到概念,心里还真有些迷糊,呵呵,网上查了查,有个概念 射频表示可以辐射到空间的电磁频率,频率范围从300KHz~30GHz之间。 在电磁波频率低于100khz时,电磁波会被地表吸收,不能形成有效的传输,但电磁波频率高于100 ...…

查看全部问答>

为什么9650预览的图像很红?

原来我的9650输出图像时30万像素的,可以正常显示图像。 可是我从代理要到了130万像素的配置后,图像发红,而且是很红。 不知道有没有遇到这种情况的?是如何解决的?…

查看全部问答>

去各位救急!!!

那位可以为小弟买到一套。44b0的散件。全部。包括电容、电阻之类的东西。不要成品。想自己动手做板子。小弟这里的市场什么都没有。只有一些电视机的配件别的一概没有啊! 谢谢!…

查看全部问答>

做一个受欢迎的提问者

要想让你的问题尽快得到解答,我想以下几条是你应该注意的: 1.首先说清楚你使用的软,硬件平台。比如:我使用wince5.0在 2440上做开发... 2.问题要尽量具体,不要问诸如:我要做一个什么项目,该怎么做?或者我要做一个什么软件,该怎么做这类的 ...…

查看全部问答>

uversion如何知道arm的程序内存占用情况

我用的uversion4,lm3s8962的芯片。 我建立一个全局变量 uchar a[9000]100]; 按道理应该超过ram的容量了,但是怎么编译后不报错呢?如何才知道内存有没有超?…

查看全部问答>

生产厂家规范的-- LED驱动电源测试报告范例

replyreload += \',\' + 1365593;这份报告是基于一个8W LED驱动电源临时做的一个基本范例,是考虑有公司商业机密的问题,略作修改: 1.不对版权负责,只供参考. 2.不对内容负责,不做解释.每家公司各不相同,难于解释不同.敬请谅解. Timson,如果您要 ...…

查看全部问答>

ad测量通过串口发出的程序,只能发出FF

我用AD采样,然后想通过串口发出,结果只能得到FF。大家帮我看看那里出现了问题,谢谢 #include  \"msp430g2553.h\" #define uchar unsigned char long temp; void uart_init(void) {         BCSCTL1 = CAL ...…

查看全部问答>