IMX6ull 之 HelloWorld Led点灯

news2024/11/22 13:35:58

一 GPIO点灯,嵌入式的helloworld 

1   何为GPIO?

GPIO只是一个CPU内提供的一种功能外设CPU外部的I/O引脚会被赋予一种功能(GPIO、UART、I2C等);该功能由CPU内外设提供,具体是什么功能由IOMUX单元(I/O复用选择器)控制。

GPIO(General Purpose Input/Output)是芯片内的外设功能模块 ,每个GPIO外设连接到了外部的I/O引脚上,和GPIO外设相连的I/O引脚(I/O引脚相较于GPIO更加远离CPU) 起着通用输入输出的功能,所以被称为 GPIO 引脚。
但是,I/O引脚不仅和GPIO外设相连,还可以和芯片内部其它外设相连,比如和UART、IIC、SPI等外设相连作为通信外设的接口引脚,和定时器相连作为PWM输出引脚,等等。

嵌入式设备访问通用规则

   1 根据芯片电路手册了解设备硬件原理 及数据流走向 

   2 使能设备时钟相关寄存器

   3   设置相关寄存器工作模式 、电器属性  (这里所谓的PAD就是指芯片内部晶圆的标号,而      GPIO只是某些PAD拥有的功能,但是PAD和GPIO的序号却不是一一对应的)

   4  设置引脚数据方向 及高低电平

二 IMX6ull GPIO 

1 IMX6ull  GPIO介绍

IMX6ULL 的 IO 分为两类: SNVS 域的和通用的,IMX6ULL 的其它 IO 也是可以复用为 GPIO 功能

1 IMX有124个IO 。IO并非GPIO , GPIO只是IO的功能。IMX有5组GPIO。GPIO1组有32个IO,GPIO2有22个,GPIO3有29个,GPIO429个
GPIO5有12个。

2.跟STM32一样,IMX也需要开启GPIO时钟, 寄存器CCM_CCGR0~CCM_CCGR6控制着所有外设的时钟,不只有GPIO的时钟。

3 .ICR1,ICR2寄存器分别用于配置低16个GPIO和高16个GPIO的中断,为什么是16个?因为GPIO分为5组,每组最多32个GPIO .
每个GPIO占用2位, 2位用来设置这个GPIO到底是什么触发,上升沿触发,下降沿触发,高电平触发,低电平触发。

4.IMR寄存器32位,一位对应一个GPIO当对应位置1 , 这个GPIO就上下沿即双边沿触发中断,这个设置覆盖ICR1和ICR2.

2 GPIO操作流程

①、查寄存器手册,打开GPIO控制的时钟源 ,使能 GPIO 对应的时钟。 
②、设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能使其复用
为 GPIO 功能。
③、设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,配置GPIO的电气特性 ,设置 IO 的上下拉、速度等等。
④、第②步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,置输入/输、是否使
用中断、默认输出电平等。

1 查看原理图

首先根据 底板电路原理图 查看led位置对应芯片引脚 查找寄存器符号标记 LED0 /GPIO3

2 使能时钟 CCM 

Clock Tree CLOCKS

IMX6ull时钟频率有多种 分频原因  使能GPIO对应的时钟才能让GPIO正常工作。查找 IMX6ull参考手册 (选最大的) 找到 GPIO_3 时钟寄存器

 并使能它。
时钟有4种模式,这里需要停止模式外,所有模式都保持工作,即11

寄存器地址为:  基地址 + 偏移 

先查阅手册,找到GPIO的时钟隶属于哪一组;GPIO CLOCKS

Clock章节寻找对应的clock name:IPG_CLK_S 五组GPIO对应 CCGRX

GPIO1时钟控制寄存器为CCGR1 

 地址为  0x020C 406C

寄存器设置遵循不影响其它位通过位运算只修改操作位

3、配置GPIO复用

大部分功能强大的芯片,GPIO通常都不是作为普通的IO使用,一个GPIO有许多可选(复用)的功能,想要让GPIO作为普通IO使用,就需要配置对应的复用寄存器,选择为普通GPIO的功能。查看IX6MULL芯片的参考手册,找到对应的复用配置寄存器。

IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x20E0068 

设置复用模式 寄存器后四位 = 0101 =5 

4、配置GPIO的电气特性

设置 GPIO的基本属性,如方向(input/output)、状态(浮空、开漏、推挽、上下拉等)、速率(50Mbps,100Mpbs、200Mbps等)。
控制LED亮灭,需要控制电平,所以需要配置为输出模式,简单的灯亮灭对速率没有特别要求。状态希望默认是熄灭的状态,所以初始化的时候,可以配置为上拉,即默认输出高电平的状态,根据原理图分析可知LED0为高电平,LED熄灭。

对应寄存器

此寄存器对应的功能选项较多 根据实际需求配置

	/* 3、配置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 低转换率
     */
    ldr r0, =0X020E02F4	/*寄存器SW_PAD_GPIO1_IO03_BASE */
    ldr r1, =0X10B0
    str r1,[r0]

5 设置GPIO输出方向  GPIOX_DR 

1 设置输出方向

/* 4、设置GPIO1_IO03为输出 */
    ldr r0, =0X0209C004    /*寄存器GPIO1_GDIR */
    ldr r1, =0X0000008        
    str r1,[r0]

2 设置引脚电平点灯

/* 5、打开LED0
	 * 设置GPIO1_IO03输出低电平
	 */
	ldr r0, =0X0209C000	/*寄存器GPIO1_DR */
   ldr r1, =0		
   str r1,[r0]

三 编译及执行 

1 汇编代码(一般c开发 汇编设置C语言执行环境)

/**************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 mian.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 裸机实验1 汇编点灯
			 使用汇编来点亮开发板上的LED灯,学习和掌握如何用汇编语言来
			 完成对I.MX6U处理器的GPIO初始化和控制。
其他	   : 无
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/3 左忠凯创建
**************************************************************/

.global _start  /* 全局标号 */

/*
 * 描述:	_start函数,程序从此函数开始执行此函数完成时钟使能、
 *		  GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
 */
_start:
	/* 例程代码 */
	/* 1、使能时钟 */

	ldr r0, =0X020C406C  	/* CCGR1 */
	str r1, [r0]

	
	/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */
	ldr r0, =0X020E0068	/* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */
	ldr r1, =0X5		/* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */
	str r1,[r0]

	/* 3、配置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 低转换率
     */
    ldr r0, =0X020E02F4	/*寄存器SW_PAD_GPIO1_IO03_BASE */
    ldr r1, =0X10B0
    str r1,[r0]

	/* 4、设置GPIO1_IO03为输出 */
    ldr r0, =0X0209C004	/*寄存器GPIO1_GDIR */
    ldr r1, =0X0000008		
    str r1,[r0]

	/* 5、打开LED0
	 * 设置GPIO1_IO03输出低电平
	 */
	ldr r0, =0X0209C000	/*寄存器GPIO1_DR */
   ldr r1, =0		
   str r1,[r0]

/*
 * 描述:	loop死循环
 */
loop:
	b loop 				

	

	
	


2 编译 

1   先逐步编译

1 arm-linux-gnueabihf-gcc -g -c led.s -o led.o

上述命令就是将 led.s 编译为 led.o,其中“-g”选项是产生调试信息,GDB 能够使用这些 调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文 件名字,这里我们指定 led.s 编译完成以后的文件名字为 led.o。

2 arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf 

烧写到 SD 卡中 bin文件 自动执行上电以后  I.MX6U 的内部 boot rom 程序会将 可执行文件拷贝到链接地址处  之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 其 链接地址就是 0X87800000,这样我们统一使用 0X87800000 这个链接地址 (这是正点原子内部设计)当然我们可以连接到其它地方............? )

led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还 需要将 led.elf 文件转换为.bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具 了。

3 arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

“-O”选项指定以什么格式输出

2 简化编译 Makefile

led.bin:led.s
	arm-linux-gnueabihf-gcc -g -c led.s -o led.o
	arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
	arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
	arm-linux-gnueabihf-objdump -D led.elf > led.dis
clean:
	rm -rf *.o led.bin led.elf led.dis
	
	

通用模板  

CC=arm-linux-gnueabihf-gcc
LD=arm-linux-gnueabihf-ld
OBJCOPY=arm-linux-gnueabihf-objcopy
OBJDUMP=arm-linux-gnueabihf-objdump

ASSEMBLER=$(wildcard *.s)
SRC=$(wildcard *.c) 
OBJ=$(patsubst %.s, %.o, $(ASSEMBLER)) $(patsubst %.c, %.o, $(SRC))
INCLUDE=.
CFLAG=-Wall -nostdlib
TARGET=led.bin

all: $(TARGET)

$(TARGET): $(OBJ)
	$(LD) -Ttext 0x87800000 $^ -o led.elf
	$(OBJCOPY) -O binary -S led.elf $@
	$(OBJDUMP) -D -m arm led.elf > led.dis

%.o : %.s
	$(CC) $(CFLAG) -c $< -o $@


%.o : %.c
	$(CC) $(CFLAG) -c $< -o $@ -I$(INCLUDE)

.PHONY: clean

clean:
	rm -f $(OBJ)
	rm -f $(TARGET)
	rm -f led.elf led.dis

3 烧写 

IMx6ull 内部 ROM 96K不对用户开放 ,但支持外置Flash 及 SD卡 启动 ,SD卡烧写位置NXP有详细规定烧写步骤

烧写工具  imxdownload

烧写命令

./imxdownload  <bin file>  <sdcard> 

./imxdownload led.bin /dev/sdd  (取决于sd卡挂载位置)

烧写完成以后会在当前工程目录下生成一个 load.imx 的文件

load.imx 这个文件就是软件 imxdownload 根据 NXP 官方启动方式介绍的内容,在 led.bin 文 件前面添加了一些数据头以后生成的。最终烧写到 SD 卡里面的就是这个 load.imx 文件,而非 led.bin。

4 设置拨 码开关为 SD 卡启动,

接下来就是将 SD 卡插到开发板的 SD 卡槽中,然后设置拨 码开关为 SD 卡启动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刷题笔记4-22

目录 1.Java&#xff1a;(a,b)>Math.abs(a-3)-Math.abs(b-3)&#xff1b; 2.字符解释 3.C语言二维数组中a[i]表示ai的地址&#xff0c;而a[i]又可以表示为*&#xff08;ai&#xff09; 4.二维数组在传参时&#xff0c;必须给定列 5.软件开发&#xff1a;观察者模式 6.建…

shell脚本控制

shell脚本编程系列 处理信号 Linux利用信号与系统中的进程进行通信&#xff0c;通过对脚本进行编程&#xff0c;使其在收到特定信号时执行某些命令&#xff0c;从而控制shell脚本的操作。 Linux信号 shell脚本编程会遇到的最常见的Linux系统信号如下表所示&#xff1a; 在默…

【ros】6.ros激光雷达SLAM(建图定位)

百行业为先 &#xff0c;万恶懒为首。——梁启超 文章目录 :smirk:1. 激光SLAM:blush:2. 二维激光SLAM:satisfied:3. 三维激光SLAM &#x1f60f;1. 激光SLAM SLAM&#xff08;同步定位与地图构建&#xff09;是一种机器人感知技术&#xff0c;用于在未知环境中同时确定机器人…

java调用webservicer的方法

对于使用 Webservicer的方式&#xff0c;一般采用 Java API调用的方式。Webservicer是一个运行在浏览器中的客户端程序&#xff0c;它可以通过 Webservicer的接口来访问服务器上的服务。 使用 Java调用 Webservicer有两种方式&#xff1a; 下面是一个简单的例子&#xff1a; 2、…

零基础,零成本,部署一个属于你的大模型

前言 看了那么多chatGPT的文章&#xff0c;作为一名不精通算法的开发&#xff0c;也对大模型心痒痒。但想要部署自己的大模型&#xff0c;且不说没有算法相关的经验了&#xff0c;光是大模型占用的算力资源&#xff0c;手头的个人电脑其实也很难独立部署。就算使用算法压缩后的…

数据结构和算法学习记录——小习题-二叉树的遍历二叉搜索树

目录 二叉树的遍历 1-1 1-2 1-3 二叉搜索树 2-1 2-2 2-3 2-4 答案区 二叉树的遍历 1-1 假定只有四个结点A、B、C、D的二叉树&#xff0c;其前序遍历序列为ABCD&#xff0c;则下面哪个序列是不可能的中序遍历序列&#xff1f; .ABCD .ACDB .DCBA .DABC 1-2 对于…

最精简:windows环境安装tensorflow-gpu-2.10.1

Tensorflow 2.10是最后一个在本地windows上支持GPU的版本 1. 通过.whl文件方式安装2.创建anaconda虚拟环境3.安装对应的cuda与cudnn版本&#xff0c;local不必装cuda和cudnn4. 测试tensorflow gpu是否可用 1. 通过.whl文件方式安装 .whl文件的下载地址&#xff1a; tensorflow…

windows下使用vite创建vue项目

windows下使用vite创建vue项目 1 下载安装配置NodeJS1.1 下载1.2 安装1.3 配置1.4 npm镜像加速配置1.6 设置环境变量 2 Vite简单介绍3 Vite创建vue项目3.1 vite创建vue项目的命令3.2 vite创建vue项目步骤 1 下载安装配置NodeJS 1.1 下载 下载地址&#xff1a;https://nodejs.…

全注解下的SpringIoc 续2-bean的生命周期

spring中bean的生命周期 上一个小节梳理了一下Spring Boot的依赖注入的基本知识&#xff0c;今天来梳理一下spring中bean的生命周期。 下面&#xff0c;让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分&#xff1a; #mermaid-svg-GFXNEU…

数据分类分级 数据识别-识别日期类型数据

前面针对数据安全-数据分类分级方案设计做了分析讲解,具体内容可点击数据安全-数据分类分级方案设计,不再做赘述 上面图片是AI创作生成!如需咒语可私戳哦! 目录 前言需求日期格式代码日期类型数据对应正则表达式前言 要做数据分类分级,重要的是分类分级模版的合理性和数…

一致性 Hash 算法 及Java TreeMap 实现

1、一致性 Hash 算法原理 一致性 Hash 算法通过构建环状的 Hash 空间替线性 Hash 空间的方法解决了这个问题&#xff0c;整个 Hash 空间被构建成一个首位相接的环。 其具体的构造过程为&#xff1a; 先构造一个长度为 2^32 的一致性 Hash 环计算每个缓存服务器的 Hash 值&…

「C/C++」C++对已有的类进行扩充

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 相关术语一、 继承二、组合 相关术语 继承&#xff1a;继承父类后可以拥有父类对应的属性和方法。 组合&#xff1a;将类作为成员对象&#xff0c;基类可以直接调用派生类对应的属性和方法。 一…

MySQL_第08章_聚合函数

第08章_聚合函数 讲师&#xff1a;尚硅谷 - 宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a; http://www.atguigu.com 我们上一章讲到了 SQL 单行函数。实际上 SQL 函数还有一类&#xff0c;叫做聚合&#xff08;或聚集、分组&#xff09;函…

59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境

文章目录 59 openEuler 22.03-LTS 搭建MySQL数据库服务器-软件介绍和配置环境59.1 软件介绍59.2 配置环境59.2.1 关闭防火墙并取消开机自启动59.2.2 修改SELINUX为disabled59.2.3 创建组和用户59.2.4 创建数据盘59.2.4.1 方法一&#xff1a;在root权限下使用fdisk进行磁盘管理5…

JVM笔记 —— 垃圾回收(GC)详解

一、垃圾回收的分类 针对HotSpot JVM的实现&#xff0c;它里面的GC其实准确分类只有两大种: Partial GC&#xff1a;部分收集模式 Young GC&#xff1a;只收集年轻代的GCOld GC&#xff1a;只收集老年代的GC。只有CMS中有这个模式。Mixed GC&#xff1a;收集整个年轻代以及部分…

mybatis的基本使用和理解

mybatis的基本使用和理解 Lombok的使用(使用注解的方式将实体类中的get、set、构造函数代替&#xff09; Lombok是一个Java库&#xff0c;能自动插入编辑器并且构建工具&#xff0c;简化Java开发。通过添加注解的方式&#xff0c;不需要为类编写getter或equals方法&#xff0…

Vue3 + TS4.8踩坑之配置husky问题env: sh\r: No such file or directory

一、基本情况&#xff1a; 硬件环境&#xff1a;MacOS 10.14.6 背景&#xff1a;用vue3官方npm init vuelatest初始化创建的vue3 ts4.8项目。 二、问题和解决方案&#xff1a; 问题1&#xff1a;git commit的时候提示&#xff1a;env: sh\r: No such file or directory 原…

0121 进程管理

1.在Linux中&#xff0c;每个执行的程序都称为一个进程。每一个进程都分配一个ID号&#xff08;pid进程号&#xff09; 2.每个进程都可能以两种方式存在&#xff0c;前台和后台。前台进程即用户当前屏幕上可进行的操作&#xff0c;后台进程即实际操作&#xff0c;由于屏幕上无…

Java中源文件声明规则,以及java包,import关键字的使用

Java中源文件声明规则&#xff0c;以及java包&#xff0c;import关键字的使用。 1. 源文件声明规则 当在一个源文件中定义多个类&#xff0c;并且还有import语句和package语句时&#xff0c;要特别注意以下规则&#xff1a; a. 一个源文件中只能有一个 public 类。 b. 一个源…

LC电路是如何产生振荡的

电容和电感是两个储能元件&#xff0c;当电源给电容充电完成后&#xff0c; 将开关切到电感&#xff0c;电电感两端的电压是一个正弦波&#xff0c;正弦波频率是: 这时我们称电感和电容产生了振荡。 当然由于电感和电容都是有损耗的&#xff0c;所以这种振荡会慢慢的衰减&…