嵌入式第二课-GPIO试验

1.点亮一个led

	步骤:
	1.配置GPIO为输出功能:修改con值。例:GPFCON[9:8]=0b01(0b表示二进制)→设置GPF4为输出。
	2.设置输出值,修改dat值。例:GPFDAT[4]=1 or 0;

汇编方法:

.text
.global _start
_start:     
            LDR     R0,=0x56000050      @ R0设为GPFCON寄存器。此寄存器
                                        @ 用于选择端口B各引脚的功能:
                                        @ 是输出、是输入、还是其他
            MOV     R1,#0x00000100        
            STR     R1,[R0]             @ 设置GPF4为输出口,[8:7]=0b01
            
            LDR     R0,=0x56000054      @ R0设为GPBDAT寄存器。此寄存器
                                        @ 用于读/写端口B各引脚的数据
            MOV     R1,#0x00000000      @ 此值改为0x00000010,
                                        @ 可让LED1熄灭
            STR     R1,[R0]             @ GPF4输出0,LED1点亮
MAIN_LOOP:
            B       MAIN_LOOP

C语言方法:

	**启动文件包括软件初始化和硬件初始化**
	软件初始化:
		1.设置返回地址
		2.调用main
		3.清理工作
		4.设置栈:SP栈指针指向某内存(默认SRAM,如果指向SDRAM则需要初始化SDRAM)

	硬件初始化:
		1.关闭看门狗
		2.初始化时钟(加快频率)
		3.初始化SDRAM

启动程序:

.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函数,并把返回地址放入lr寄存器
halt_loop:
            b       halt_loop			@ 清理工作

C语言程序:

#define GPFCON      (*(volatile unsigned long *)0x56000050)
#define GPFDAT      (*(volatile unsigned long *)0x56000054)

int main()
{
    GPFCON = 0x00000100;    // 设置GPF4为输出口, 位[9:8]=0b01
    GPFDAT = 0x00000000;    // GPF4输出0,LED1点亮

    return 0;
}

2.按键点亮led

	程序中注意位操作:清零用 & ,置1用 | 。

步骤:
1.配置KEYGPIO为输入功能;配置LEDGPIO为输出功能。
2.读取KEY,根据KEY值设置LED引脚输出。

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;
}

零散知识:
volatile关键字表示确保本条指令不会因编译器的优化而省略,且要求每次直接读值。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值