LED灯C语言的点亮方式

在上一篇进行了汇编语言的编写后,这一节采用C语言来编写,毕竟C语言才是咱们使用最多的语言。css

本节要点:linux

1)用C语言方式点亮LED灯;编程

2)分析反汇编代码;了解函数调用栈,深刻的分析代码;sass

3)编写C语言的库函数版本,方便之后开发;数据结构

首先贴出一段代码:函数

start.s学习

.text .global _start _start: /* 设置内存: sp 栈 */ ldr sp, =4096  /* nand启动 */
// ldr sp, =0x40000000+4096 /* nor启动 */

    /* 调用main */ bl main halt: b halt

LED.c:优化

int main() { unsigned int *pGPFCON = (unsigned int *)0x56000050; unsigned int *pGPFDAT = (unsigned int *)0x56000054; /* 配置GPF4为输出引脚 */
    *pGPFCON = 0x100; /* 设置GPF4输出0 */
    *pGPFDAT = 0; return 0; }

在传统的IDE开发当中,咱们只用从main函数开始写代码就好了,可是IDE隐藏了太多技术细节。ui

咱们在arm嵌入式linux开发过程当中,都须要本身来,这对初学者是不友好,可是对深刻学习却颇有帮助。spa

首先,nand flash启动,使用片内4K sram。

咱们都知道,函数调用和局部变量的存储须要使用到一种叫作栈的数据结构。

说明:s3c2440,采用默认的栈生长方式,这也是咱们最多见的方式,高地址往低地址生长。

要调用main函数,咱们须要开辟栈,这里使用片内4K内存做为栈。

看一下反汇编:

led.elf:     file format elf32-littlearm Disassembly of section .text: <_start>: 0:    e3a0da01     mov    sp, #4096    ; 0x1000
   4:    eb000000     bl    c <main>
<halt>: 8:    eafffffe     b    8 <halt> 0000000c <main>: c: e1a0c00d mov ip, sp 10:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} 14:    e24cb004     sub    fp, ip, #4    ; 0x4
  18:    e24dd008     sub    sp, sp, #8    ; 0x8 1c: e3a03456 mov r3, #1442840576    ; 0x56000000
  20:    e2833050     add    r3, r3, #80    ; 0x50
  24:    e50b3010     str    r3, [fp, #-16] 28:    e3a03456     mov    r3, #1442840576    ; 0x56000000 2c: e2833054 add r3, r3, #84    ; 0x54
  30:    e50b3014     str    r3, [fp, #-20] 34:    e51b2010     ldr    r2, [fp, #-16] 38:    e3a03c01     mov    r3, #256    ; 0x100 3c: e5823000 str r3, [r2] 40:    e51b2014     ldr    r2, [fp, #-20] 44:    e3a03000     mov    r3, #0    ; 0x0
  48: e5823000 str r3, [r2] 4c: e3a03000 mov r3, #0    ; 0x0
  50: e1a00003 mov r0, r3 54:    e24bd00c     sub    sp, fp, #12    ; 0xc
  58: e89da800 ldmia sp, {fp, sp, pc} Disassembly of section .comment: <.comment>: 0:    43434700     cmpmi    r3, #0    ; 0x0
   4: 4728203a undefined 8:    2029554e     eorcs    r5, r9, lr, asr #10 c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} 10:    Address 0x10 is out of bounds.

说明:

<.comment>:在上面的反汇编当中,它不是汇编代码的一部分,是注解,给咱们一些提示,便于咱们阅读、理解的。在讲解这个汇编以前,咱们须要先看一个arm寄存器的别名表。

如今开始分析,其中最重要的也是新出现的两个指令:

stmdb,ldmia

简单说明,db表示事先递减方式,ia表示过后递增方式。

 详细介绍能够参见 arm嵌入式系统开发P58。

先对反汇编进行注解:

led.elf:     file format elf32-littlearm Disassembly of section .text: <_start>: 0:    e3a0da01     mov    sp, #4096 ; 赋值4096给sp堆栈寄存器 4:    eb000000     bl    c <main> ;跳转到main函数,同时保存main函数返回地址到lr寄存器,返回地址为下一条指令的地址,这里lr应为8 <halt>: 8:    eafffffe     b    8 <halt>;死循环 0000000c <main>: c: e1a0c00d mov ip, sp;备份sp寄存器的值到ip,ip是r12寄存器的别名
10:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} ; 这条指令须要重点讲解,首先,fp,ip,lr,pc分别对应寄存器:r11,r12,r14,r15 ; stm指令多寄存器操做的时候,后面的寄存器从编号高的先开始存储,把后面几个寄存器的值写入sp所对应的内存块中,(注意和但寄存器操做区分开来)后缀db表示 先减后存储 ; sp后面加了一个感叹号!,表示sp最后的值等于最后被修改的值,不加感叹号就算操做使sp更改过,sp也等于最初的值 ; 首先操做r15,即pc,sp先减,sp=sp-4,此时sp=4092,pc等于当前指令地址加8,即此时pc=0x10+8=0x18,至关于把0x18写入sram地址4092 ; 同理操做r14,即lr,sp=sp-4,lr=8,至关于把0x8写入4088地址 ; r12,ip是等于4096的,上面的move指令,r11,fp的值此时未定
14:    e24cb004     sub    fp, ip, #4    ; fp=ip-4=4092
  18:    e24dd008     sub    sp, sp, #8    ; sp=sp-8=4072
  1c:    e3a03456     mov    r3, #1442840576    ;#1442840576等于十六机制0x56000000,把这个数存放在r3中
  20:    e2833050     add    r3, r3, #80    ;r3=r3+80=0x56000050
  24:    e50b3010     str    r3, [fp, #-16];fp-16=4076,把0x56000050放入内存4076中
  28:    e3a03456     mov    r3, #1442840576    ; 0x56000000
  2c:    e2833054     add    r3, r3, #84    ; r3=0x56000054
  30:    e50b3014     str    r3, [fp, #-20];fp=fp-20=4072,把0x56000054放入内存4072中
  34:    e51b2010     ldr    r2, [fp, #-16];r2=[fp-16=4076]=0x56000050
  38:    e3a03c01     mov    r3, #256; r3==256=0x100
  3c:    e5823000     str    r3, [r2];把0x100存入[0x56000050]
  40:    e51b2014     ldr    r2, [fp, #-20];r2=[fp-20=4072]=0x56000054
  44:    e3a03000     mov    r3, #0    ; r3=0=0x0
  48:    e5823000     str    r3, [r2];把0x0存入0x56000054内存中
  4c:    e3a03000     mov    r3, #0    ; r3=0x0
  50:    e1a00003     mov    r0, r3;r0=r3=0x0,这里编译器有点笨,能够直接r0给0的,这里对应return 0.
  54:    e24bd00c     sub    sp, fp, #12    ; sp=fp-12=4080

  

58: e89da800 ldmia sp, {fp, sp, pc} ;恢复保存的现场,ldmia,过后增长,从sp所对应内存块中取出数据存放到后面的寄存器,高编号的寄存器放在高地址,低编号的寄存器 ;放在低地址,此时sp=4080,从低地址往高地址开始恢复,这也符合ia后缀 ;先恢复fp,此时4080地址存放的值,注意是值不是地址,等于4092,刚好就是等于fp,即一顿操做以后,fp仍是等于原来的fp ;再恢复sp,sp=sp+4=4084,内存4084对应的值是4096,即一顿操做以后,sp又等于4096了; ;最后恢复pc,sp=sp+4=4088,内存4088对应的值是8,即一段操做以后,pc=8了,pc等于8意味着什么?意味着函数从main函数返回了,将去执行那个死循环halt

为了更好的理解函数入栈,让咱们深刻理解C语言底层汇编,画出内存示意图:

你可能会说。0-4096不是4097了吗?这样问很是好,不放过任何有疑问的细节,可是,4096,能够是4096的开始,也能够是4095的结尾,这里表示的是4095的结尾,由于4096咱们一来是要先减4的。上图的4096是没用使用到真正属于4096地址后扩4字节的,而是在恰好到达4096时,以前的内存。

到这里,终于完成了一大半,咱们知道了函数入栈以后,彷佛函数调用的参数传递,也要用到栈啊,那么咱们继续挖掘汇编。这里又须要补充几点arm方面的知识。

如今编写汇编代码, 传递一个参数:

.text .global _start _start: /* 设置内存: sp 栈 */ ldr sp, =4096  /* nand启动 */
// ldr sp, =0x40000000+4096 /* nor启动 */
 mov r0, #4 bl led_on ldr r0, =100000 bl delay mov r0, #5 bl led_on halt: b halt
void delay(volatile int d) { while (d--); } int led_on(int which) { unsigned int *pGPFCON = (unsigned int *)0x56000050; unsigned int *pGPFDAT = (unsigned int *)0x56000054; if (which == 4) { /* 配置GPF4为输出引脚 */
        *pGPFCON = 0x100; } else if (which == 5) { /* 配置GPF5为输出引脚 */
        *pGPFCON = 0x400; } /* 设置GPF4/5输出0 */
    *pGPFDAT = 0; return 0; }

上面汇编中,只对应一个参数,因此只用r0就能够达到函数参数传递的效果,汇编比较简单就不赘述了。

这个例子是为了让咱们了解汇编经过寄存器传递函数参数,前提是必须先设置sp寄存器。

甚至没必要编写main函数,固然不建议这样作,这样示例是为让你明白一点,main函数也是由于启动代码去调用了它,咱们经过改写启动代码,能够没有main函数。

 终于到了咱们最熟悉的阶段了,编写C语言应用程序,通常来讲,复杂的和可复用性更高的代码咱们确定是用C语言编写,全用汇编编写代码真是很慢并且麻烦,更不用说机器码编程了,可是了解它们对咱们深刻学习又十分有用,这或许就是arm对初学者不友好的缘由吧,由于如今为止咱们尚未大型项目须要编写复杂的Makefile,后面还有不少技能须要get,这也是在买了板子大半年了才真的开始上手的缘由,须要花时间补习其余知识。

言归正传,如上面的C语言程序,虽然完成了要求,但是复用性太差,既然你以为你C语言最熟悉,那么就请封装一个复用性高的代码出来看看吧。

我想使用复用性很是强的C代码,能够方便移植,快速开发,例以下面编写的mylib库函数:

#include "s3c2440_gpio.h"
int main(void) { Reset_gpio(OUT, GPIOF,GPIO_PinSource4); Set_gpio(OUT, GPIOF,GPIO_PinSource5); Reset_gpio(OUT, GPIOF,GPIO_PinSource6); return 0; }

就是这样的代码,能够调用一个函数,达到指定IO输出高低电平或者设置模式。

s3c2440_gpio.c:

#include "s3c2440_gpio.h"

void Set_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { if(new==OUT) { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/
        //DAT复位值udf
        GPIO_InitStruct->DAT |=(1<<GPIO_PinSource);/*对应位清零,输出1*/ } else if(new==IN) { //CON复位值为0,配置为输入
        GPIO_InitStruct->CON &=(3<<GPIO_PinSource*2);/*乘法优先级高于左移*/ } else { /*预留*/ } } void Reset_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { if(new==OUT) { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/ GPIO_InitStruct->DAT &=~(1<<GPIO_PinSource);/*对应位清零,输出0,低电平*/ } }

s3c2440_gpio.h:

#ifndef _S3C2440_GPIO_H_ #define _S3C2440_GPIO_H_ typedef unsigned char uint8_t; typedef unsigned short     int uint16_t; typedef unsigned int uint32_t; #define __IO  volatile typedef struct { __IO uint32_t CON; __IO uint32_t DAT; __IO uint32_t UP; __IO uint32_t Reserved; } GPIO_TypeDef; typedef enum { IN = 0, OUT = 1, EINT=2 } IOState; #define GPIO_PinSource0            ((uint8_t)0x00)
#define GPIO_PinSource1            ((uint8_t)0x01)
#define GPIO_PinSource2            ((uint8_t)0x02)
#define GPIO_PinSource3            ((uint8_t)0x03)
#define GPIO_PinSource4            ((uint8_t)0x04)
#define GPIO_PinSource5            ((uint8_t)0x05)
#define GPIO_PinSource6            ((uint8_t)0x06)
#define GPIO_PinSource7            ((uint8_t)0x07)

#define GPIOA_BASE            (0x56000000)
#define GPIOB_BASE            (0x56000010)
#define GPIOC_BASE            (0x56000020)
#define GPIOD_BASE            (0x56000030)
#define GPIOE_BASE            (0x56000040)
#define GPIOF_BASE            (0x56000050)
#define GPIOG_BASE            (0x56000060)
#define GPIOH_BASE            (0x56000070)
#define GPIOJ_BASE            (0x560000d0)

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH               ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOJ               ((GPIO_TypeDef *) GPIOJ_BASE)

void Set_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource); void Reset_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource); #endif /*s3c2440_gpio.h*/

编写出这样的库函数须要有过库函数编程经验而且具有必定的C语言基础和思惟。

再看看加了-g选项也就是调试信息的反汇编:

 

led.elf:     file format elf32-littlearm Disassembly of section .text: <_start>: .global _start _start: ldr sp,=4096 //nandflash启动,设置栈
   0:    e3a0da01     mov    sp, #4096    ; 0x1000
    //调用main函数
 bl main 4:    eb000000     bl    c <main>
<halt>: halt: b halt 8:    eafffffe     b    8 <halt> 0000000c <main>: #include "s3c2440_gpio.h"
int main(void) { c: e1a0c00d mov ip, sp 10:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} 14:    e24cb004     sub    fp, ip, #4    ; 0x4 Reset_gpio(OUT, GPIOF,GPIO_PinSource4); 18:    e3a00001     mov    r0, #1    ; 0x1 1c: e3a01456 mov r1, #1442840576    ; 0x56000000
  20:    e2811050     add    r1, r1, #80    ; 0x50
  24:    e3a02004     mov    r2, #4    ; 0x4
  28:    eb000042     bl    138 <Reset_gpio> Set_gpio(OUT, GPIOF,GPIO_PinSource5); 2c: e3a00001 mov r0, #1    ; 0x1
  30:    e3a01456     mov    r1, #1442840576    ; 0x56000000
  34:    e2811050     add    r1, r1, #80    ; 0x50
  38:    e3a02005     mov    r2, #5    ; 0x5 3c: eb000007 bl 60 <Set_gpio> Reset_gpio(OUT, GPIOF,GPIO_PinSource6); 40:    e3a00001     mov    r0, #1    ; 0x1
  44:    e3a01456     mov    r1, #1442840576    ; 0x56000000
  48:    e2811050     add    r1, r1, #80    ; 0x50 4c: e3a02006 mov r2, #6    ; 0x6
  50:    eb000038     bl    138 <Reset_gpio>
    return 0; 54:    e3a03000     mov    r3, #0    ; 0x0 } 58: e1a00003 mov r0, r3 5c: e89da800 ldmia sp, {fp, sp, pc} <Set_gpio>: #include "s3c2440_gpio.h"

void Set_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { 60: e1a0c00d mov ip, sp 64:    e92dd800     stmdb    sp!, {fp, ip, lr, pc} 68:    e24cb004     sub    fp, ip, #4    ; 0x4 6c: e24dd00c sub sp, sp, #12    ; 0xc
  70:    e50b0010     str    r0, [fp, #-16] 74:    e50b1014     str    r1, [fp, #-20] 78: e1a03002 mov r3, r2 7c: e54b3016 strb r3, [fp, #-22] 80:    e1a03443     mov    r3, r3, asr #8
  84:    e54b3015     strb    r3, [fp, #-21] if(new==OUT) 88:    e51b3010     ldr    r3, [fp, #-16] 8c: e3530001 cmp r3, #1    ; 0x1
  90:    1a000017     bne    f4 <Set_gpio+0x94> { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/
  94:    e51b0014     ldr    r0, [fp, #-20] 98:    e51b1014     ldr    r1, [fp, #-20] 9c: e24b3016 sub r3, fp, #22    ; 0x16 a0: e5d32000 ldrb r2, [r3] a4: e5d33001 ldrb r3, [r3, #1] a8: e1823403 orr r3, r2, r3, lsl #8 ac: e1a02083 mov r2, r3, lsl #1 b0: e3a03001 mov r3, #1    ; 0x1 b4: e1a02213 mov r2, r3, lsl r2 b8: e5913000 ldr r3, [r1] bc: e1833002 orr r3, r3, r2 c0: e5803000 str r3, [r0] //DAT复位值udf
        GPIO_InitStruct->DAT |=(1<<GPIO_PinSource);/*对应位清零,输出1*/ c4: e51b1014 ldr r1, [fp, #-20] c8: e51b0014 ldr r0, [fp, #-20] cc: e24b3016 sub r3, fp, #22    ; 0x16 d0: e5d32000 ldrb r2, [r3] d4: e5d33001 ldrb r3, [r3, #1] d8: e1822403 orr r2, r2, r3, lsl #8 dc: e3a03001 mov r3, #1    ; 0x1 e0: e1a02213 mov r2, r3, lsl r2 e4: e5903004 ldr r3, [r0, #4] e8: e1833002 orr r3, r3, r2 ec: e5813004 str r3, [r1, #4] f0: ea00000e b 130 <Set_gpio+0xd0> } else if(new==IN) f4: e51b3010 ldr r3, [fp, #-16] f8: e3530000 cmp r3, #0    ; 0x0 fc: 1a00000b bne 130 <Set_gpio+0xd0> { //CON复位值为0,配置为输入
        GPIO_InitStruct->CON &=(3<<GPIO_PinSource*2);/*乘法优先级高于左移*/
 100:    e51b0014     ldr    r0, [fp, #-20] 104:    e51b1014     ldr    r1, [fp, #-20] 108:    e24b3016     sub    r3, fp, #22    ; 0x16 10c: e5d32000 ldrb r2, [r3] 110:    e5d33001     ldrb    r3, [r3, #1] 114:    e1823403     orr    r3, r2, r3, lsl #8
 118:    e1a02083     mov    r2, r3, lsl #1 11c: e3a03003 mov r3, #3    ; 0x3
 120: e1a02213 mov r2, r3, lsl r2 124: e5913000 ldr r3, [r1] 128: e0033002 and r3, r3, r2 12c: e5803000 str r3, [r0] } else { /*预留*/ } } 130:    e24bd00c     sub    sp, fp, #12    ; 0xc
 134: e89da800 ldmia sp, {fp, sp, pc} <Reset_gpio>: void Reset_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { 138: e1a0c00d mov ip, sp 13c: e92dd800 stmdb sp!, {fp, ip, lr, pc} 140:    e24cb004     sub    fp, ip, #4    ; 0x4
 144:    e24dd00c     sub    sp, sp, #12    ; 0xc
 148:    e50b0010     str    r0, [fp, #-16] 14c: e50b1014 str r1, [fp, #-20] 150: e1a03002 mov r3, r2 154:    e54b3016     strb    r3, [fp, #-22] 158:    e1a03443     mov    r3, r3, asr #8 15c: e54b3015 strb r3, [fp, #-21] if(new==OUT) 160:    e51b3010     ldr    r3, [fp, #-16] 164:    e3530001     cmp    r3, #1    ; 0x1
 168:    1a000017     bne    1cc <Reset_gpio+0x94> { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/ 16c: e51b0014 ldr r0, [fp, #-20] 170:    e51b1014     ldr    r1, [fp, #-20] 174:    e24b3016     sub    r3, fp, #22    ; 0x16
 178: e5d32000 ldrb r2, [r3] 17c: e5d33001 ldrb r3, [r3, #1] 180:    e1823403     orr    r3, r2, r3, lsl #8
 184:    e1a02083     mov    r2, r3, lsl #1
 188:    e3a03001     mov    r3, #1    ; 0x1 18c: e1a02213 mov r2, r3, lsl r2 190: e5913000 ldr r3, [r1] 194: e1833002 orr r3, r3, r2 198: e5803000 str r3, [r0] GPIO_InitStruct->DAT &=~(1<<GPIO_PinSource);/*对应位清零,输出0,低电平*/ 19c: e51b0014 ldr r0, [fp, #-20] 1a0: e51b1014 ldr r1, [fp, #-20] 1a4: e24b3016 sub r3, fp, #22    ; 0x16 1a8: e5d32000 ldrb r2, [r3] 1ac: e5d33001 ldrb r3, [r3, #1] 1b0: e1822403 orr r2, r2, r3, lsl #8 1b4: e3a03001 mov r3, #1    ; 0x1 1b8: e1a03213 mov r3, r3, lsl r2 1bc: e1e02003 mvn r2, r3 1c0: e5913004 ldr r3, [r1, #4] 1c4: e0033002 and r3, r3, r2 1c8: e5803004 str r3, [r0, #4] } } 1cc: e24bd00c sub sp, fp, #12    ; 0xc 1d0: e89da800 ldmia sp, {fp, sp, pc} Disassembly of section .comment: <.comment>: 0:    43434700     cmpmi    r3, #0    ; 0x0
   4: 4728203a undefined 8:    2029554e     eorcs    r5, r9, lr, asr #10 c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} 10:    47000035 smladxmi r0, r5, r0, r0 14:    203a4343     eorcss    r4, sl, r3, asr #6
  18:    554e4728     strplb    r4, [lr, #-1832] 1c: 2e332029 cdpcs 0, 3, cr2, cr3, cr9, {1} 20: 00352e34 eoreqs r2, r5, r4, lsr lr Disassembly of section .debug_aranges: <.debug_aranges>: 0: 0000001c andeq r0, r0, ip, lsl r0 4:    00000002 andeq r0, r0, r2 8:    00040000 andeq r0, r4, r0 ... 14: 0000000c andeq r0, r0, ip ... 20: 0000001c andeq r0, r0, ip, lsl r0 24: 003a0002 eoreqs r0, sl, r2 28:    00040000 andeq r0, r4, r0 2c: 00000000 andeq r0, r0, r0 30: 0000000c andeq r0, r0, ip 34:    00000054 andeq r0, r0, r4, asr r0 ... 40: 0000001c andeq r0, r0, ip, lsl r0 44: 00c90002 sbceq r0, r9, r2 48:    00040000 andeq r0, r4, r0 4c: 00000000 andeq r0, r0, r0 50:    00000060 andeq r0, r0, r0, rrx 54:    00000174 andeq r0, r0, r4, ror r1 ... Disassembly of section .debug_pubnames: <.debug_pubnames>: 0:    00000017 andeq r0, r0, r7, lsl r0 4: 003a0002 eoreqs r0, sl, r2 8: 008f0000 addeq r0, pc, r0 c: 006f0000 rsbeq r0, pc, r0 10: 616d0000 cmnvs sp, r0 14:    00006e69     andeq    r6, r0, r9, ror #28
  18:    2a000000     bcs    20 <main+0x14> 1c: 02000000     andeq    r0, r0, #0    ; 0x0
  20:    0000c900     andeq    ip, r0, r0, lsl #18
  24:    0001c100     andeq    ip, r1, r0, lsl #2
  28:    00012e00     andeq    r2, r1, r0, lsl #28 2c: 74655300     strvcbt    r5, [r5], #-768
  30:    6970675f     ldmvsdb    r0!, {r0, r1, r2, r3, r4, r6, r8, r9, sl, sp, lr}^
  34: 017b006f cmneq fp, pc, rrx 38:    65520000 ldrvsb r0, [r2] 3c: 5f746573 swipl 0x00746573
  40:    6f697067     swivs    0x00697067
  44:    00000000 andeq r0, r0, r0 ... Disassembly of section .debug_info: <.debug_info>: 0:    00000036 andeq r0, r0, r6, lsr r0 4:    00000002 andeq r0, r0, r2 8:    01040000 tsteq r4, r0 ... 14: 0000000c andeq r0, r0, ip 18:    72617473     rsbvc    r7, r1, #1929379840    ; 0x73000000 1c: 00532e74 subeqs r2, r3, r4, ror lr 20:    6d6f682f     stcvsl    8, cr6, [pc, #-188]!
  24:    68732f65     ldmvsda    r3!, {r0, r2, r5, r6, r8, r9, sl, fp, sp}^
  28:    00657261     rsbeq    r7, r5, r1, ror #4 2c: 20554e47 subcss r4, r5, r7, asr #28
  30:    32205341     eorcc    r5, r0, #67108865    ; 0x4000001
  34:    0035312e     eoreqs    r3, r5, lr, lsr #2
  38: 008b8001 addeq r8, fp, r1 3c: 00020000 andeq r0, r2, r0 40:    00000014 andeq r0, r0, r4, lsl r0 44:    00360104     eoreqs    r0, r6, r4, lsl #2
  48:    00600000 rsbeq r0, r0, r0 4c: 000c0000 andeq r0, ip, r0 50:    4e470000     cdpmi    0, 4, cr0, cr7, cr0, {0} 54:    20432055 subcs r2, r3, r5, asr r0 58:    2e342e33     mrccs    14, 1, r2, cr4, cr3, {1} 5c: 6d010035 stcvs 0, cr0, [r1, #-212] 60:    2e6e6961     cdpcs    9, 6, cr6, cr14, cr1, {3} 64:    682f0063     stmvsda    pc!, {r0, r1, r5, r6} 68:    2f656d6f     swics    0x00656d6f 6c: 72616873     rsbvc    r6, r1, #7536640    ; 0x730000
  70:    75020065     strvc    r0, [r2, #-101] 74:    6769736e     strvsb    r7, [r9, -lr, ror #6]!
  78:    2064656e     rsbcs    r6, r4, lr, ror #10 7c: 72616863     rsbvc    r6, r1, #6488064    ; 0x630000
  80:    02080100     andeq    r0, r8, #0    ; 0x0
  84:    726f6873     rsbvc    r6, pc, #7536640    ; 0x730000
  88:    6e752074     mrcvs    0, 3, r2, cr5, cr4, {3} 8c: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} 90:    69206465     stmvsdb    r0!, {r0, r2, r5, r6, sl, sp, lr} 94:    0200746e     andeq    r7, r0, #1845493760    ; 0x6e000000
  98:    6e750207     cdpvs    2, 7, cr0, cr5, cr7, {0} 9c: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} a0: 69206465     stmvsdb    r0!, {r0, r2, r5, r6, sl, sp, lr} a4: 0400746e streq r7, [r0], #-1134 a8: 6d010307 stcvs 3, cr0, [r1, #-28] ac: 006e6961 rsbeq r6, lr, r1, ror #18 b0: 87010301     strhi    r0, [r1, -r1, lsl #6] b4: 0c000000 stceq 0, cr0, [r0], {0} b8: 60000000 andvs r0, r0, r0 bc: 01000000 tsteq r0, r0 c0: 6e69025b mcrvs 2, 3, r0, cr9, cr11, {2} c4: 05040074     streq    r0, [r4, #-116] c8: 0001bd00 andeq fp, r1, r0, lsl #26 cc: 4a000200 bmi 8d4 <Reset_gpio+0x79c> d0: 04000000 streq r0, [r0] d4: 00006c01 andeq r6, r0, r1, lsl #24 d8: 0001d400 andeq sp, r1, r0, lsl #8 dc: 00006000 andeq r6, r0, r0 e0: 554e4700 strplb r4, [lr, #-1792] e4: 33204320     teqcc    r0, #-2147483648    ; 0x80000000 e8: 352e342e strcc r3, [lr, #-1070]! ec: 33730100     cmncc    r3, #0    ; 0x0 f0: 34343263     ldrcct    r3, [r4], #-611 f4: 70675f30 rsbvc r5, r7, r0, lsr pc f8: 632e6f69 teqvs lr, #420    ; 0x1a4 fc: 6f682f00 swivs 0x00682f00
 100:    732f656d     teqvc    pc, #457179136    ; 0x1b400000
 104:    65726168     ldrvsb    r6, [r2, #-360]!
 108:    6e750200     cdpvs    2, 7, cr0, cr5, cr0, {0} 10c: 6e676973 mcrvs 9, 3, r6, cr7, cr3, {3} 110:    63206465     teqvs    r0, #1694498816    ; 0x65000000
 114:    00726168     rsbeqs    r6, r2, r8, ror #2
 118:    75030801     strvc    r0, [r3, #-2049] 11c: 31746e69 cmncc r4, r9, ror #28
 120: 00745f36 rsbeqs r5, r4, r6, lsr pc 124:    00610402     rsbeq    r0, r1, r2, lsl #8
 128:    73020000     tstvc    r2, #0    ; 0x0 12c: 74726f68 ldrvcbt r6, [r2], #-3944
 130:    736e7520     cmnvc    lr, #134217728    ; 0x8000000
 134:    656e6769     strvsb    r6, [lr, #-1897]!
 138:    6e692064     cdpvs    0, 6, cr2, cr9, cr4, {3} 13c: 07020074 smlsdxeq r2, r4, r0, r0 140:    6e697503     cdpvs    5, 6, cr7, cr9, cr3, {0} 144:    5f323374     swipl    0x00323374
 148:    05020074     streq    r0, [r2, #-116] 14c: 00000087     andeq    r0, r0, r7, lsl #1
 150:    736e7502     cmnvc    lr, #8388608    ; 0x800000
 154:    656e6769     strvsb    r6, [lr, #-1897]!
 158:    6e692064     cdpvs    0, 6, cr2, cr9, cr4, {3} 15c: 07040074 smlsdxeq r4, r4, r0, r0 160:    0000dc04     andeq    sp, r0, r4, lsl #24
 164:    0d021000     stceq    0, cr1, [r2] 168:    4e4f4305     cdpmi    3, 4, cr4, cr15, cr5, {0} 16c: dc090200 sfmle f0, 4, [r9], {0} 170:    02000000     andeq    r0, r0, #0    ; 0x0
 174:    44050023     strmi    r0, [r5], #-35
 178:    02005441     andeq    r5, r0, #1090519040    ; 0x41000000 17c: 0000e10a andeq lr, r0, sl, lsl #2
 180:    04230200     streqt    r0, [r3], #-512
 184:    00505505     subeqs    r5, r0, r5, lsl #10
 188:    00e60b02     rsceq    r0, r6, r2, lsl #22 18c: 23020000     tstcs    r2, #0    ; 0x0
 190:    65520508     ldrvsb    r0, [r2, #-1288] 194:    76726573 undefined 198:    02006465     andeq    r6, r0, #1694498816    ; 0x65000000 19c: 0000eb0c andeq lr, r0, ip, lsl #22 1a0: 0c230200 sfmeq f0, 4, [r3] 1a4: 00770600     rsbeqs    r0, r7, r0, lsl #12 1a8: 77060000     strvc    r0, [r6, -r0] 1ac: 06000000     streq    r0, [r0], -r0 1b0: 00000077 andeq r0, r0, r7, ror r0 1b4: 00007706     andeq    r7, r0, r6, lsl #14 1b8: 50470300     subpl    r0, r7, r0, lsl #6 1bc: 545f4f49 ldrplb r4, [pc], #3913    ; 1c4 <Reset_gpio+0x8c> 1c0: 44657079     strmibt    r7, [r5], #-121 1c4: 02006665     andeq    r6, r0, #105906176    ; 0x6500000 1c8: 0000970d andeq r9, r0, sp, lsl #14 1cc: 011f0700 tsteq pc, r0, lsl #14 1d0: 02040000     andeq    r0, r4, #0    ; 0x0 1d4: 4e490810 mcrmi 8, 2, r0, cr9, cr0, {0} 1d8: 4f080000 swimi 0x00080000 1dc: 01005455 tsteq r0, r5, asr r4 1e0: 4e494508 cdpmi 5, 4, cr4, cr9, cr8, {0} 1e4: 00020054 andeq r0, r2, r4, asr r0 1e8: 534f4903 cmppl pc, #49152    ; 0xc000 1ec: 65746174     ldrvsb    r6, [r4, #-372]! 1f0: 04140200     ldreq    r0, [r4], #-512 1f4: 09000001 stmeqdb r0, {r0} 1f8: 00000175 andeq r0, r0, r5, ror r1 1fc: 74655301     strvcbt    r5, [r5], #-769
 200:    6970675f     ldmvsdb    r0!, {r0, r1, r2, r3, r4, r6, r8, r9, sl, sp, lr}^
 204:    0401006f     streq    r0, [r1], #-111
 208:    00006001 andeq r6, r0, r1 20c: 00013800     andeq    r3, r1, r0, lsl #16
 210:    0a5b0100     beq    16c0618 <__bss_end__+0x16b8444>
 214:    0077656e     rsbeqs    r6, r7, lr, ror #10
 218:    011f0301     tsteq    pc, r1, lsl #6 21c: 91020000 tstls r2, r0 220: 000f0b70 andeq r0, pc, r0, ror fp 224:    03010000     tsteq    r1, #0    ; 0x0
 228:    00000175 andeq r0, r0, r5, ror r1 22c: 0b6c9102 bleq 1b2463c <__bss_end__+0x1b1c468>
 230:    00000000 andeq r0, r0, r0 234:    00510301     subeqs    r0, r1, r1, lsl #6
 238:    91020000 tstls r2, r0 23c: 040c006a streq r0, [ip], #-106
 240:    000000f0     streqd    r0, [r0], -r0 244:    6552010d     ldrvsb    r0, [r2, #-269] 248:    5f746573     swipl    0x00746573 24c: 6f697067 swivs 0x00697067
 250:    01180100     tsteq    r8, r0, lsl #2
 254:    00000138 andeq r0, r0, r8, lsr r1 258:    000001d4     ldreqd    r0, [r0], -r4 25c: 6e0a5b01 fmacdvs d5, d10, d1 260:    01007765     tsteq    r0, r5, ror #14
 264: 00011f17 andeq r1, r1, r7, lsl pc 268:    70910200     addvcs    r0, r1, r0, lsl #4 26c: 00000f0b andeq r0, r0, fp, lsl #30
 270:    75170100     ldrvc    r0, [r7, #-256] 274:    02000001     andeq    r0, r0, #1    ; 0x1
 278: 000b6c91 muleq fp, r1, ip 27c: 01000000 tsteq r0, r0 280:    00005117 andeq r5, r0, r7, lsl r1 284:    6a910200     bvs    fe440a8c <__bss_end__+0xfe4388b8> ... Disassembly of section .debug_abbrev: <.debug_abbrev>: 0:    10001101     andne    r1, r0, r1, lsl #2
   4:    12011106     andne    r1, r1, #-2147483647    ; 0x80000001
   8:    1b080301     blne    200c14 <__bss_end__+0x1f8a40> c: 13082508     tstne    r8, #33554432    ; 0x2000000
  10:    00000005 andeq r0, r0, r5 14:    10011101     andne    r1, r1, r1, lsl #2
  18:    11011206     tstne    r1, r6, lsl #4 1c: 13082501     tstne    r8, #4194304    ; 0x400000
  20:    1b08030b     blne    200c54 <__bss_end__+0x1f8a80>
  24:    02000008     andeq    r0, r0, #8    ; 0x8
  28:    08030024 stmeqda r3, {r2, r5} 2c: 0b3e0b0b bleq f82c60 <__bss_end__+0xf7aa8c>
  30:    2e030000     cdpcs    0, 0, cr0, cr3, cr0, {0} 34:    030c3f00     tsteq    ip, #0    ; 0x0
  38:    3b0b3a08     blcc    2ce860 <__bss_end__+0x2c668c> 3c: 490c270b stmmidb ip, {r0, r1, r3, r8, r9, sl, sp} 40:    12011113     andne    r1, r1, #-1073741820    ; 0xc0000004
  44: 000a4001 andeq r4, sl, r1 48:    11010000 tstne r1, r0 4c: 12061001     andne    r1, r6, #1    ; 0x1
  50:    25011101     strcs    r1, [r1, #-257] 54:    030b1308     tsteq    fp, #536870912    ; 0x20000000
  58:    00081b08     andeq    r1, r8, r8, lsl #22 5c: 00240200     eoreq    r0, r4, r0, lsl #4
  60:    0b0b0803     bleq    2c2074 <__bss_end__+0x2b9ea0>
  64: 00000b3e andeq r0, r0, lr, lsr fp 68:    03001603     tsteq    r0, #3145728    ; 0x300000 6c: 3b0b3a08 blcc 2ce894 <__bss_end__+0x2c66c0>
  70:    0013490b     andeqs    r4, r3, fp, lsl #18
  74:    01130400     tsteq    r3, r0, lsl #8
  78:    0b0b1301     bleq    2c4c84 <__bss_end__+0x2bcab0> 7c: 0b3b0b3a bleq ec2d6c <__bss_end__+0xebab98>
  80:    0d050000     stceq    0, cr0, [r5] 84:    3a080300     bcc    200c8c <__bss_end__+0x1f8ab8>
  88: 490b3b0b stmmidb fp, {r0, r1, r3, r8, r9, fp, ip, sp} 8c: 000a3813 andeq r3, sl, r3, lsl r8 90:    00350600     eoreqs    r0, r5, r0, lsl #12
  94:    00001349     andeq    r1, r0, r9, asr #6
  98:    01010407     tsteq    r1, r7, lsl #8 9c: 3a0b0b13 bcc 2c2cf0 <__bss_end__+0x2bab1c> a0: 000b3b0b andeq r3, fp, fp, lsl #22 a4: 00280800     eoreq    r0, r8, r0, lsl #16 a8: 0d1c0803 ldceq 8, cr0, [ip, #-12] ac: 2e090000 cdpcs 0, 0, cr0, cr9, cr0, {0} b0: 3f130101 swicc 0x00130101 b4: 3a08030c bcc 200cec <__bss_end__+0x1f8b18> b8: 270b3b0b strcs r3, [fp, -fp, lsl #22] bc: 1201110c andne r1, r1, #3    ; 0x3 c0: 000a4001 andeq r4, sl, r1 c4: 00050a00 andeq r0, r5, r0, lsl #20 c8: 0b3a0803 bleq e820dc <__bss_end__+0xe79f08> cc: 13490b3b cmpne r9, #60416    ; 0xec00 d0: 00000a02 andeq r0, r0, r2, lsl #20 d4: 0300050b tsteq r0, #46137344    ; 0x2c00000 d8: 3b0b3a0e blcc 2ce918 <__bss_end__+0x2c6744> dc: 0213490b andeqs r4, r3, #180224    ; 0x2c000 e0: 0c00000a stceq 0, cr0, [r0], {10} e4: 0b0b000f bleq 2c0128 <__bss_end__+0x2b7f54> e8: 00001349     andeq    r1, r0, r9, asr #6 ec: 3f012e0d swicc 0x00012e0d f0: 3a08030c bcc 200d28 <__bss_end__+0x1f8b54> f4: 270b3b0b strcs r3, [fp, -fp, lsl #22] f8: 1201110c andne r1, r1, #3    ; 0x3 fc: 000a4001 andeq r4, sl, r1 ... Disassembly of section .debug_line: <.debug_line>: 0:    00000032 andeq r0, r0, r2, lsr r0 4: 001b0002 andeqs r0, fp, r2 8:    01020000 tsteq r2, r0 c: 000a0efb streqd r0, [sl], -fp 10:    01010101     tsteq    r1, r1, lsl #2
  14:    01000000 tsteq r0, r0 18:    61747300     cmnvs    r4, r0, lsl #6 1c: 532e7472 teqpl lr, #1912602624    ; 0x72000000
  20:    00000000 andeq r0, r0, r0 24:    02050000     andeq    r0, r5, #0    ; 0x0
  28:    00000000 andeq r0, r0, r0 2c: 2d010903 stccs 9, cr0, [r1, #-12] 30:    0002022e     andeq    r0, r2, lr, lsr #4
  34:    00320101     eoreqs    r0, r2, r1, lsl #2
  38:    00020000 andeq r0, r2, r0 3c: 0000001a andeq r0, r0, sl, lsl r0 40:    0efb0102     cdpeq    1, 15, cr0, cr11, cr2, {0} 44: 0101000a tsteq r1, sl 48:    00000101     andeq    r0, r0, r1, lsl #2 4c: 6d000100 stfvss f0, [r0] 50:    2e6e6961     cdpcs    9, 6, cr6, cr14, cr1, {3} 54:    00000063 andeq r0, r0, r3, rrx 58:    05000000 streq r0, [r0] 5c: 00000c02 andeq r0, r0, r2, lsl #24
  60: 9c651100 stflse f1, [r5] 64:    022c9c9c     eoreq    r9, ip, #39936    ; 0x9c00
  68:    01010004 tsteq r1, r4 6c: 00000059 andeq r0, r0, r9, asr r0 70:    00340002 eoreqs r0, r4, r2 74:    01020000 tsteq r2, r0 78:    000a0efb     streqd    r0, [sl], -fp 7c: 01010101     tsteq    r1, r1, lsl #2
  80:    01000000 tsteq r0, r0 84:    63337300     teqvs    r3, #0    ; 0x0
  88:    30343432 eorccs r3, r4, r2, lsr r4 8c: 6970675f ldmvsdb r0!, {r0, r1, r2, r3, r4, r6, r8, r9, sl, sp, lr}^
  90:    00632e6f     rsbeq    r2, r3, pc, ror #28
  94:    73000000     tstvc    r0, #0    ; 0x0
  98:    34326333     ldrcct    r6, [r2], #-819 9c: 675f3034 smmlarvs pc, r4, r0, r3 a0: 2e6f6970 mcrcs 9, 3, r6, cr15, cr0, {3} a4: 00000068 andeq r0, r0, r8, rrx a8: 05000000 streq r0, [r0] ac: 00006002 andeq r6, r0, r2 b0: 3a081200 bcc 2048b8 <__bss_end__+0x1fc6e4> b4: 08730866     ldmeqda    r3!, {r1, r2, r5, r6, fp}^ b8: 77086673 smlsdxvc r8, r3, r6, r6 bc: 663a084a ldrvst r0, [sl], -sl, asr #16 c0: 73087208     tstvc    r8, #-2147483648    ; 0x80000000 c4: 01000402     tsteq    r0, r2, lsl #8 c8: Address 0xc8 is out of bounds. Disassembly of section .debug_frame: <.debug_frame>: 0: 0000000c andeq r0, r0, ip 4:    ffffffff     swinv    0x00ffffff
   8:    7c010001     stcvc    0, cr0, [r1], {1} c: 000d0c0e andeq r0, sp, lr, lsl #24
  10: 0000001c andeq r0, r0, ip, lsl r0 14:    00000000 andeq r0, r0, r0 18: 0000000c andeq r0, r0, ip 1c: 00000054 andeq r0, r0, r4, asr r0 20:    440c0d44     strmi    r0, [ip], #-3396
  24:    038d028e     orreq    r0, sp, #-536870904    ; 0xe0000008
  28:    0c44048b     cfstrdeq    mvd0, [r4], {139} 2c: 0000040b andeq r0, r0, fp, lsl #8
  30: 0000000c andeq r0, r0, ip 34:    ffffffff     swinv    0x00ffffff
  38:    7c010001     stcvc    0, cr0, [r1], {1} 3c: 000d0c0e andeq r0, sp, lr, lsl #24
  40: 0000001c andeq r0, r0, ip, lsl r0 44:    00000030 andeq r0, r0, r0, lsr r0 48:    00000060 andeq r0, r0, r0, rrx 4c: 000000d8 ldreqd r0, [r0], -r8 50:    440c0d44     strmi    r0, [ip], #-3396
  54:    038d028e     orreq    r0, sp, #-536870904    ; 0xe0000008
  58:    0c44048b     cfstrdeq    mvd0, [r4], {139} 5c: 0000040b andeq r0, r0, fp, lsl #8
  60: 0000001c andeq r0, r0, ip, lsl r0 64:    00000030 andeq r0, r0, r0, lsr r0 68:    00000138 andeq r0, r0, r8, lsr r1 6c: 0000009c muleq r0, ip, r0 70:    440c0d44     strmi    r0, [ip], #-3396
  74:    038d028e     orreq    r0, sp, #-536870904    ; 0xe0000008
  78:    0c44048b     cfstrdeq    mvd0, [r4], {139} 7c: 0000040b andeq r0, r0, fp, lsl #8 Disassembly of section .debug_str: <.debug_str>: 0:    4f495047     swimi    0x00495047
   4:    6e69505f     mcrvs    0, 3, r5, cr9, cr15, {2} 8:    72756f53     rsbvcs    r6, r5, #332    ; 0x14c c: 47006563     strmi    r6, [r0, -r3, ror #10] 10:    5f4f4950     swipl    0x004f4950
  14:    74696e49     strvcbt    r6, [r9], #-3657
  18:    75727453     ldrvcb    r7, [r2, #-1107]! 1c: Address 0x1c is out of bounds.

Makefile以下:

all: arm-linux-gcc -c -g -o s3c2440_gpio.o s3c2440_gpio.c arm-linux-gcc -c -g -o main.o main.c arm-linux-gcc -c -g -o start.o start.S arm-linux-ld -Ttext 0 start.o main.o s3c2440_gpio.o -o led.elf arm-linux-objcopy -O binary -S led.elf led.bin arm-linux-objdump -S -D led.elf > led.dis clean: rm *.bin *.o *.elf *.dis

这个程序烧录进单板是能够点亮4和6的,可是这还存在一个潜在问题,看cpu手册:

 

 看门狗默认是打开的,因此程序运行一段时间会复位,可是上面没有加入LED闪烁,因此看不出来,如今更改启动文件的汇编,把看门狗关闭:

上面的库函数还须要根据寄存器不断配置优化,我只是作出一个模子,这样给你们一个参考,就是经过一个通用的函数,给不一样的引脚就让处理器作不一样的事。

 如今给出最终版(固然,库函数须要根据学习得深刻不断优化):

包括关闭看门狗,本身写的输入输出设置库函数以及读取输入引脚库函数,这是根据之前STM32库函数开发经验,本身写库应用在s3c2440上。

启动汇编如上图所示,这里贴出c代码:

头文件:

#ifndef _S3C2440_GPIO_H_ #define _S3C2440_GPIO_H_ typedef unsigned char uint8_t; typedef unsigned short     int uint16_t; typedef unsigned int uint32_t; #define __IO  volatile typedef struct { __IO uint32_t CON; __IO uint32_t DAT; __IO uint32_t UP; __IO uint32_t Reserved; } GPIO_TypeDef; typedef enum { IN = 0, OUT = 1, EINT=2 } IOState; typedef enum { Bit_RESET = 0, Bit_SET }BitAction; #define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */

#define GPIO_PinSource0            ((uint8_t)0x00)
#define GPIO_PinSource1            ((uint8_t)0x01)
#define GPIO_PinSource2            ((uint8_t)0x02)
#define GPIO_PinSource3            ((uint8_t)0x03)
#define GPIO_PinSource4            ((uint8_t)0x04)
#define GPIO_PinSource5            ((uint8_t)0x05)
#define GPIO_PinSource6            ((uint8_t)0x06)
#define GPIO_PinSource7            ((uint8_t)0x07)

#define GPIOA_BASE            (0x56000000)
#define GPIOB_BASE            (0x56000010)
#define GPIOC_BASE            (0x56000020)
#define GPIOD_BASE            (0x56000030)
#define GPIOE_BASE            (0x56000040)
#define GPIOF_BASE            (0x56000050)
#define GPIOG_BASE            (0x56000060)
#define GPIOH_BASE            (0x56000070)
#define GPIOJ_BASE            (0x560000d0)

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOH               ((GPIO_TypeDef *) GPIOH_BASE)
#define GPIOJ               ((GPIO_TypeDef *) GPIOJ_BASE)

void Set_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource); void Reset_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource); uint8_t ReadInput_gpio(GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_Pin); #endif /*s3c2440_gpio.h*/

这里要分清楚GPIO是Pin仍是PinSource。

源文件(增长读取输入电平)

#include "s3c2440_gpio.h"

/*设置输入输出属性,默认输出高电平 *new:out,in分别表明输出,输入 *GPIO_InitStruct:GPIO A-J *GPIO_PinSource:0-7 *以上参数的宏定义可根据手册完善 */
void Set_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { if(new==OUT) { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/
        //DAT复位值udf
        GPIO_InitStruct->DAT |=(1<<GPIO_PinSource);/*对应位清零,输出1*/ } else if(new==IN) { //CON复位值为0,配置为输入
        GPIO_InitStruct->CON &=(3<<GPIO_PinSource*2);/*乘法优先级高于左移*/ } else { /*预留*/ } } /* *设置输出引脚输出低电平 */
void Reset_gpio(IOState new,GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_PinSource) { if(new==OUT) { //CON复位值为0,配置为输出
        GPIO_InitStruct->CON |=1<<GPIO_PinSource*2;/*乘法优先级高于左移*/ GPIO_InitStruct->DAT &=~(1<<GPIO_PinSource);/*对应位清零,输出0,低电平*/ } } /* *读取输入引脚的电平,返回值为0或者1,0表明低电平,1表明高电平 *该函数本能够增长一个参数完成输入输出的读取,可是考虑到STM32也是分开的,故这里也分开实现 *输出引脚的电平读取库函数暂时没写,由于目前只用到输入引脚读取,后面须要时就完善,其原理是同样的, */ uint8_t ReadInput_gpio(GPIO_TypeDef* GPIO_InitStruct,uint16_t GPIO_Pin) { uint8_t bitstatus = 0x00; if((GPIO_InitStruct->DAT & GPIO_Pin )!=(uint32_t)Bit_RESET) { bitstatus=(uint8_t)Bit_SET; } else { bitstatus = (uint8_t)Bit_RESET; } return bitstatus; }
#include "s3c2440_gpio.h"

void Delay(uint32_t count) { while(count--); } int main(void) { //配置GPIOF 0,2,GPIOG 3为输入模式
 Set_gpio(IN, GPIOF,GPIO_PinSource0); Set_gpio(IN, GPIOF,GPIO_PinSource2); Set_gpio(IN, GPIOG,GPIO_PinSource3); //点亮LED1而后熄灭
 Reset_gpio(OUT, GPIOF,GPIO_PinSource4); Delay(100000); Set_gpio(OUT, GPIOF,GPIO_PinSource4); Delay(100000); //点亮LED2而后熄灭
 Reset_gpio(OUT, GPIOF,GPIO_PinSource5); Delay(100000); Set_gpio(OUT, GPIOF,GPIO_PinSource5); Delay(100000); //点亮LED3而后熄灭
 Reset_gpio(OUT, GPIOF,GPIO_PinSource6); Delay(100000); Set_gpio(OUT, GPIOF,GPIO_PinSource6); Delay(100000); //熄灭三盏LED灯
 Set_gpio(OUT, GPIOF,GPIO_PinSource5); Set_gpio(OUT, GPIOF,GPIO_PinSource4); while (1) { //若是按键3按下,则为低电平,就点亮LED3
        if(ReadInput_gpio(GPIOF,GPIO_Pin_0)) { Set_gpio(OUT, GPIOF,GPIO_PinSource6); } else { Reset_gpio(OUT, GPIOF,GPIO_PinSource6); } //若是按键2按下,则为低电平,就点亮LED2
        if(ReadInput_gpio(GPIOF,GPIO_Pin_2)) { Set_gpio(OUT, GPIOF,GPIO_PinSource5); } else { Reset_gpio(OUT, GPIOF,GPIO_PinSource5); } //若是按键1按下,则为低电平,就点亮LED1
        if(ReadInput_gpio(GPIOG,GPIO_Pin_3)) { Set_gpio(OUT, GPIOF,GPIO_PinSource4); } else { Reset_gpio(OUT, GPIOF,GPIO_PinSource4); } } return 0; }

原理图:

 

 外部电源上拉:

EINT0->对应引脚GPF0

EINT2->对应引脚GPF2

EINT11->对应引脚GPG3

即,默认高电平,按键按下就低电平。

Makefile和以前同样,ok,这样是否是以为方便多了?固然,这是创建在你熟练运用C语言的基础上的,否则是写不出库函数的。

相关文章
相关标签/搜索