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語言的基礎上的,否則是寫不出庫函數的。

相關文章
相關標籤/搜索