一、IMX6LL裸机点亮一颗LED

本文介绍了IMX6ULL裸机开发的步骤,包括学习ARM汇编基础知识,设置启动文件以进入SVC模式,分析原理图以确定LED与GPIO的连接,查阅参考手册配置IOMUXC和GPIO寄存器,以及编写代码实现LED的开关控制。通过这些步骤,读者可以掌握基本的嵌入式系统开发技能。
摘要由CSDN通过智能技术生成

IMX6ULL裸机开发

从裸机到系统
第一章 ARM汇编基础,寄存器及汇编基础指令讲解
第二章 IMX6LL裸机点亮一颗LED



前言

励志做一名合格的嵌入式Linux软件工程师,努力学习驱动和应用开发。


一、添加启动文件


启动文件一般使用汇编语言编写,对cortex-A寄存器CPSR(程序状态寄存器)进行设置,进入SVC模式,初始化栈指针,跳转到main()函数执行。
新建 start.s文件

.global _start


_start:

	mrs r0, cpsr
	bic r0, r0, #0x1f //将r0的低5bit清0
	orr r0, r0, #0x13 //使用svc模式
	msr cpsr, r0 //将r0的数据写到cpsr中
	ldr sp, =0X80200000 //设置栈指针
	b main //跳转到main函数
	

二、原理图分析

LED原理图
LED引脚连接
可以看出LED0连接在GPIO_3引脚上,同时接了一个上拉电阻将电平拉高,所以当GPIO_3拉低时,灯亮,反之灯灭。

三、查找IMX6ULL参考手册

找到第32章Chapter 32​: IOMUX Controller (IOMUXC)
32.6小节:IOMUXC Memory Map/Register Definition
IOMUXC

找到IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03此寄存器设置IO复用,此处复用为GPIO1_IO03
在这里插入图片描述

找到IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03此寄存器设置GPIO1_IO03的电气属性
1、 输出缓冲区
  当输出缓冲区使能时,引脚被配置为输出模式。在输出缓冲区中,又包含了如下的属性配置:
  • DSE 驱动能力
  DSE 可以调整芯片内部与引脚串联电阻 R0 的大小,从而改变引脚的驱动能力。例如,R0 的初始值为 260 欧姆,在 3.3V 电压下其电流驱动能力为 12.69mA,通过 DSE 可以把 R0 的值配置为原值的 1/2、1/3⋯1/7 等。
  • SRE 压摆率配置
  • SPEED 带宽配置
  • ODE 开漏输出配置
2、 输入缓冲区
  • HYS 滞后使能
  • PUS 上下拉配置
  PUS 可配置项可选为 100K 欧下拉以及 22K 欧、47K 欧及 100K 欧上拉。

• PUE 上下拉、保持器选择
  上下拉功能和保持器功能是二选一的,可以通过 PUE 来选择。
  • PKE 上下拉、保持器配置
  上下拉功能和保持器还通过 PKE 来控制是否使能。
  注意,当引脚被配置为输出模式时,不管上下拉、保持器是什么配置,它们都会被关闭。
在这里插入图片描述

在这里插入图片描述
找到具体的GPIO后,我们还得要打开时钟驱动GPIO工作
找到第18章Chapter 18​: Clock Controller Module (CCM)
第18.6小节CCM Memory Map/Register Definition
CCM

找到CCM_CCGR1 使能gpio 1 clock
在这里插入图片描述

四、代码编写

经过上面的分析,找到我们需要用到的寄存器地址:
CCM_CCGR1 0X020C406C
SW_MUX_GPIO1_IO03 0X020E0068
SW_PAD_GPIO1_IO03 0X020E02F4
GPIO1_DR 0X0209C000
GPIO1_GDIR 0X0209C004
GPIO1_PSR 0X0209C008
GPIO1_ICR1 0X0209C008
GPIO1_ICR2 0X0209C008
GPIO1_IMR 0X0209C008
GPIO1_ISR 0X0209C008
GPIO1_EDGE_SEL 0X0209C008

新建led.h定义寄存器

#ifndef _LED_H_
#define _LED_H_

/* 
* CCM 相关寄存器地址
*/
#define CCM_CCGR0 *((volatile unsigned int *)0X020C4068)
#define CCM_CCGR1 *((volatile unsigned int *)0X020C406C)
#define CCM_CCGR2 *((volatile unsigned int *)0X020C4070)
#define CCM_CCGR3 *((volatile unsigned int *)0X020C4074)
#define CCM_CCGR4 *((volatile unsigned int *)0X020C4078)
#define CCM_CCGR5 *((volatile unsigned int *)0X020C407C)
#define CCM_CCGR6 *((volatile unsigned int *)0X020C4080)

/* 
 * IOMUX 相关寄存器地址
 */
#define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)
#define SW_PAD_GPIO1_IO03 *((volatile unsigned int *)0X020E02F4)

/* 
* GPIO1 相关寄存器地址
*/
#define GPIO1_DR *((volatile unsigned int *)0X0209C000)
#define GPIO1_GDIR *((volatile unsigned int *)0X0209C004)
#define GPIO1_PSR *((volatile unsigned int *)0X0209C008)
#define GPIO1_ICR1 *((volatile unsigned int *)0X0209C00C)
#define GPIO1_ICR2 *((volatile unsigned int *)0X0209C010)
#define GPIO1_IMR *((volatile unsigned int *)0X0209C014)
#define GPIO1_ISR *((volatile unsigned int *)0X0209C018)
#define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209C01C)

#endif // !_LED_H_

新建led.c

#include "led.h"

void clk_enable(void)
{
    CCM_CCGR1 = 0xffffffff;
}

void led_init(void)
{
    //复用IO为GPIO1——IO03
    SW_MUX_GPIO1_IO03 = 0x5;

    /* 2、配置 GPIO1_IO03 的 IO 属性 
    *bit 16:0 HYS 关闭
    *bit [15:14]: 00 默认下拉
    *bit [13]: 0 kepper 功能
    *bit [12]: 1 pull/keeper 使能
    *bit [11]: 0 关闭开路输出
    *bit [7:6]: 10 速度 100Mhz
    *bit [5:3]: 110 R0/6 驱动能力
    *bit [0]: 0 低转换率
    */
   SW_PAD_GPIO1_IO03 = 0x10B0;
   
   //设置IO为输出
   GPIO1_GDIR = 0x00000008;
   
   //默认输出低电平
   GPIO1_DR = 0x0;
}

void led_on(void)
{
    //清零输出低电平
    GPIO1_DR &= ~(1<<3); 
}

void led_off(void)
{
    //置位输出高电平
    GPIO1_DR |= (1<<3);
}

void delay_short(volatile unsigned int n)
{
    while(n--){}
}

void delay(volatile unsigned int n)
{
    while (n--)
    {
        delay_short(0x7ff);
    }
    
}

int main(void)
{
    clk_enable();
    led_init();

    while (1)
    {
        /* code */
        led_off();
        delay(1000);
        led_on();
        delay(1000);
    }

    return 0;
}

新建Makefile

objs := start.o led.o

led.bin:$(objs)
	arm-linux-gnueabihf-ld -Timx6ul.lds -o led.elf $^ 
	arm-linux-gnueabihf-objcopy -O binary -S led.elf $@
	arm-linux-gnueabihf-objdump -D -m arm led.elf > led.dis

%.o:%.s
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

%.o:%.S
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

%.o:%.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

clean:
	rm -rf *.o led.bin led.elf led.dis

$^ 依赖集合
$@ 目标集合
$< 依赖集合的第一个文件

总结

裸机就是使用操作寄存器的方法,控制GPIO等外设,当然也需要启动文件。启动文件一般是汇编写的,用于设置堆栈指针等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦成大佬的第N天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值