02.ARM-mini2440-GPIO操作-led_on_c

来源:互联网 发布:如何自建cdn源码 编辑:程序博客网 时间:2024/05/22 11:34

ARM-mini2440-GPIO操作-led_on_c
主要看芯片手册

这里mini2440的GPB5为例,LED灯的亮灭。

LED灯IO引脚
LED灯IO引脚

S3C2440芯片配置引脚
Port B(GPB): 11-input/out port
GPB总共有11个IO。

配置引脚由寄存器来控制。
分为控制寄存器(GPBCON)和数据寄存器(GPBDAT)
这里写图片描述

这里写图片描述

所以设置:GPBCON [11:10] = 01

这里写图片描述

当端口被配置为输入端口时,相应的位是引脚状态。当端口被配置为输出端口时,引脚状态与相应的位相同。当端口被配置为函数PIN时,将读取未定义的值。
所以设置:GPBDAT [5] = 00

这里暂时没有用到
GPBUP
0:连接到相应端口引脚的起止功能已启用。
1:拉起功能被禁用。

使用C语言编写程序
1。main函数并不特别,一样要被别人调用,执行完成也要返回。
2。启动文件,
硬件初始化
①关闭看门狗,(一定要的)√
②初始化时钟,(暂时可以不要)×
③初始化sdram,(暂时可以不要)×
软件初始化:
①设置栈,sp->内存,
②设置返回地址
③调用main
④清理工作

启动文件如下,

@******************************************************************************@ File:crt0.S@ 功能:通过它转入C程序@******************************************************************************       .text.global _start_start:            ldr     r0, =0x53000000     @ WATCHDOG寄存器地址            mov     r1, #0x0                                 str     r1, [r0]            @ 写入0,禁止WATCHDOG,否则CPU会不断重启            ldr     sp, =1024*4         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K                                        @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K            bl      main                @ 调用C程序中的main函数halt_loop:            b       halt_loop

main函数C文件

#define GPBCON      (*(volatile unsigned long *)0x56000010)#define GPBDAT      (*(volatile unsigned long *)0x56000014)int main(){    GPBCON = 0x00000400;    // 设置GPB5为输出口, 位[11:10]=0b01    GPBDAT = 0x00000000;    // GPB4输出0,LED点亮    return 0;}

Makefile文件

led_on_c.bin : crt0.S  led_on_c.c    arm-linux-gcc -g -c -o crt0.o crt0.S    arm-linux-gcc -g -c -o led_on_c.o led_on_c.c    arm-linux-ld -Ttext 0x0000000 -g  crt0.o led_on_c.o -o led_on_c_elf    arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin    arm-linux-objdump -D -m arm  led_on_c_elf > led_on_c.disclean:    rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o

①crt0.s汇编不编译,预处理-汇编-编译,得到.o文件
②led_on_c.c汇编不编译,预处理-汇编-编译,得到.o文件
③将2个文件链接到一起,“-Ttext 0x0000000”代表意思是代码段从0开始,得到led_on_c_elf
④转换成2进制文件
⑤led_on_c_elf反馈编译一下,“-D”所有的段都反馈编译。“arm”代表arm架构

下面作为参考,流水灯的c文件

#define GPFCON      (*(volatile unsigned long *)0x56000050)#define GPFDAT      (*(volatile unsigned long *)0x56000054)#define GPF4_out    (1<<(4*2))#define GPF5_out    (1<<(5*2))#define GPF6_out    (1<<(6*2))void  wait(volatile unsigned long dly){    for(; dly > 0; dly--);}int main(void){    unsigned long i = 0;    GPFCON = GPF4_out|GPF5_out|GPF6_out;        // 将LED1,2,4对应的GPF4/5/6三个引脚设为输出    while(1){        wait(30000);        GPFDAT = (~(i<<4));        // 根据i的值,点亮LED1,2,4        if(++i == 8)            i = 0;    }    return 0;}

下面作为参考,按键控制灯的c文件

#define GPFCON      (*(volatile unsigned long *)0x56000050)#define GPFDAT      (*(volatile unsigned long *)0x56000054)#define GPGCON      (*(volatile unsigned long *)0x56000060)#define GPGDAT      (*(volatile unsigned long *)0x56000064)/* * LED1,LED2,LED4对应GPF4、GPF5、GPF6 */#define GPF4_out    (1<<(4*2))#define GPF5_out    (1<<(5*2))#define GPF6_out    (1<<(6*2))#define GPF4_msk    (3<<(4*2))#define GPF5_msk    (3<<(5*2))#define GPF6_msk    (3<<(6*2))/* * S2,S3,S4对应GPF0、GPF2、GPG3 */#define GPF0_in     (0<<(0*2))#define GPF2_in     (0<<(2*2))#define GPG3_in     (0<<(3*2))#define GPF0_msk    (3<<(0*2))#define GPF2_msk    (3<<(2*2))#define GPG3_msk    (3<<(3*2))int main(){        unsigned long dwDat;        // LED1,LED2,LED4对应的3根引脚设为输出        GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);        GPFCON |= GPF4_out | GPF5_out | GPF6_out;        // S2,S3对应的2根引脚设为输入        GPFCON &= ~(GPF0_msk | GPF2_msk);        GPFCON |= GPF0_in | GPF2_in;        // S4对应的引脚设为输入        GPGCON &= ~GPG3_msk;        GPGCON |= GPG3_in;        while(1){            //若Kn为0(表示按下),则令LEDn为0(表示点亮)            dwDat = GPFDAT;             // 读取GPF管脚电平状态            if (dwDat & (1<<0))        // S2没有按下                GPFDAT |= (1<<4);       // LED1熄灭            else                    GPFDAT &= ~(1<<4);      // LED1点亮            if (dwDat & (1<<2))         // S3没有按下                GPFDAT |= (1<<5);       // LED2熄灭            else                    GPFDAT &= ~(1<<5);      // LED2点亮            dwDat = GPGDAT;             // 读取GPG管脚电平状态            if (dwDat & (1<<3))         // S4没有按下                GPFDAT |= (1<<6);       // LED3熄灭            else                    GPFDAT &= ~(1<<6);      // LED3点亮    }    return 0;}
原创粉丝点击