can使能上拉 gpio_【嵌入式Linux基础】1.裸机GPIO

2023-05-16

接下来一段时间将要使用NXP的i.mx6ull芯片来进行学习,i.MX 6ULL是一个高功效、高性价比应用处理器系列,采用单个ARM Cortex-A7内核的先进实施,运行速度高达528 MHz。

当我们学习C语言的时候,我们会写个Hello程序,那当我们写ARM程序,也该有一个简单的程序引领我们入门,这个程序就是点亮LED。怎样去点亮一个LED呢?分为三步:

1.看原理图,确定控制LED的引脚;

2.看主芯片的芯片手册,确定如何设置控制这个引脚;

3.写程序。

GPIO操作基础

首先需要先了解i.mx6ull的GPIO操作方法,下图为GPIO的控制框图。要想使能一个特定GPIO口,需要对以下模块进行配置:

CCM:Clock Controller Module(时钟控制模块) ;

IOMUXC:IOMUX Controller,IO复用控制器 ;

GPIO:General-purpose input/output,通用的输入输出口。

接下来需要确定想要操作的GPIO口,这需要查看硬件电路图,电路图中不仅提供了GPIO的端口信息还提供了GPIO操作方式。例如,此篇我希望操作GPIO点亮LED,如下图:

这个LED用到了GPIO5_3引脚。在芯片手册里,这引脚的名字是GPIO5_IO03,可以根据名字搜到对应的寄存器。 当引脚输出低电平时,对应的LED被点亮,输出高电平时,LED熄灭。

寄存器操作

1. 使能GPIO5,操作CCM_CGR1寄存器,设置[31:30]为0b11即可使能GPIO5的时钟。

2.设置GPIO5_IO03为GPIO模式,操IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3寄存器。

3.设置GPIO5_IO03为输出引脚,设置其输出电平;设置方向寄存器,把引脚设置为输出引脚,设置数据寄存器,设置引脚的输出电平。

代码分析

led.c

#include "led.h"

static volatile unsigned int *CCM_CCGR1                              ;
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
static volatile unsigned int *GPIO5_GDIR                             ;
static volatile unsigned int *GPIO5_DR                               ;


void led_init(void)
{
	unsigned int val;

	CCM_CCGR1                               = (volatile unsigned int *)(0x20C406C);
	IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = (volatile unsigned int *)(0x2290014);
	GPIO5_GDIR                              = (volatile unsigned int *)(0x020AC000 + 0x4);
	GPIO5_DR                                = (volatile unsigned int *)(0x020AC000);

	/* GPIO5_IO03 */
	/* a. 使能GPIO5
	 * set CCM to enable GPIO5
	 * CCM_CCGR1[CG15] 0x20C406C
	 * bit[31:30] = 0b11
	 */
	*CCM_CCGR1 |= (3<<30);
	
	/* b. 设置GPIO5_IO03用于GPIO
	 * set IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3
	 *      to configure GPIO5_IO03 as GPIO
	 * IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3  0x2290014
	 * bit[3:0] = 0b0101 alt5
	 */
	val = *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
	val &= ~(0xf);
	val |= (5);
	*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = val;

	/* c. 设置GPIO5_IO03作为output引脚
	 * set GPIO5_GDIR to configure GPIO5_IO03 as output
	 * GPIO5_GDIR  0x020AC000 + 0x4
	 * bit[3] = 0b1
	 */
	*GPIO5_GDIR |= (1<<3);

}


void led_ctl(int on)
{
	if (on) /* on: output 0*/
	{
		/* d. 设置GPIO5_DR输出低电平
		 * set GPIO5_DR to configure GPIO5_IO03 output 0
		 * GPIO5_DR 0x020AC000 + 0
		 * bit[3] = 0b0
		 */
		*GPIO5_DR &= ~(1<<3);
	}
	else  /* off: output 1*/
	{
		/* e. 设置GPIO5_IO3输出高电平
		 * set GPIO5_DR to configure GPIO5_IO03 output 1
		 * GPIO5_DR 0x020AC000 + 0
		 * bit[3] = 0b1
		 */ 
		*GPIO5_DR |= (1<<3);
	}
}

main.c

#include "led.h"

void delay(volatile unsigned int d)
{
	while(d--);
}


int  main()
{
	led_init();

	while(1)
	{
		led_ctl(1);
		delay(1000000);
		led_ctl(0);
		delay(1000000);
	}
					
	return 0;
}

start.s

.text
.global  _start
_start: 				

//设置栈
//将 0x80200000 赋值给寄存器 sp,即设置栈地址,因为 C 语言函数调用时,保存现场/上
//下文和传递参数需要用到栈

	ldr  sp,=0x80200000

	bl clean_bss
	
//进入 C 语言的 main()函数,并将 b halt 指令地址存储到寄存器 lr 中

	bl main

halt:
	b  halt 

clean_bss:
	/* 清除BSS段 */
	ldr r1, =__bss_start
	ldr r2, =__bss_end
	mov r3, #0
clean:
	str r3, [r1]
	add r1, r1, #4
	cmp r1, r2
	bne clean
	
	mov pc, lr

Makefile:

PREFIX=arm-linux-gnueabihf-
CC=$(PREFIX)gcc
LD=$(PREFIX)ld
AR=$(PREFIX)ar
OBJCOPY=$(PREFIX)objcopy
OBJDUMP=$(PREFIX)objdump

led.img : start.S  led.c main.c
	$(CC) -nostdlib -g -c -o start.o start.S
	$(CC) -nostdlib -g -c -o led.o led.c	
	$(CC) -nostdlib -g -c -o main.o main.c	
	
	$(LD) -T imx6ull.lds -g start.o led.o main.o -o led.elf 
	
	$(OBJCOPY) -O binary -S led.elf  led.bin
	$(OBJDUMP) -D -m arm  led.elf  > led.dis	
	./tools/mkimage -n ./tools/imximage.cfg.cfgtmp -T imximage -e 0x80100000 -d led.bin led.imx
	dd if=/dev/zero of=1k.bin bs=1024 count=1
	cat 1k.bin led.imx > led.img

clean:
	rm -f led.dis  led.bin led.elf led.imx led.img *.o

操作步骤

使用mobaxtrm登录虚拟机中,进行编译,将编译得到的可执行文件通过filezilla回传至windows端,使用烧录工具烧录至板载EMMC中进行运行。

https://www.zhihu.com/video/1243253652417740800
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

can使能上拉 gpio_【嵌入式Linux基础】1.裸机GPIO 的相关文章

随机推荐