| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> 第2期ARM裸机篇:【6】 汇编LED驱动实验1_汇编LED代码编写 -> 正文阅读 |
|
[嵌入式]第2期ARM裸机篇:【6】 汇编LED驱动实验1_汇编LED代码编写 |
简介本章开始编写本教程第一个裸机例程——经典的点灯试验,这也是我们嵌入式 Linux 学习的第一步。万里长征第一步,祝愿大家学习愉快! 目标了解如何使用汇编语言来初始化 I.MX6U 外设寄存器、了解 I.MX6UL 最基本的 IO 输出功能。 阅读基础熟悉计算机。 环境说明
参考资料
I.MX6U GPIO 详解STM32 GPIO 回顾我们一般拿到一款全新的芯片,第一个要做的事情的就是驱动其 GPIO,控制其 GPIO 输出高低电平,我们学习 I.MX6U 也一样的,先来学习一下 I.MX6U 的 GPIO。 在学习 I.MX6U的 GPIO 之前,我们先来回顾一下 STM32 的 GPIO 初始化(如果没有学过 STM32 就不用回顾了),我们以最常见的 STM32F103 为例来看一下 STM32 的 GPIO 初始化,示例代码如下:
上述代码就是使用库函数来初始化 STM32 的一个 IO 为输出功能,可以看出上述初始化代码中重点要做的事情有一下几个:
我们现在都不知道,只有去看 I.MX6U 的数据手册和参考手册才能知道,I.MX6U 的数据手册和参考手册有I.MX6UL 和 I.MX6ULL 两种,这两种型号基本是一样的,我们以 I.MX6ULL 为例来讲解。 I.MX6ULL 的数据手册有三种,分别对应:车规级、工业级和商用级。从我们写代码的角度看,这三份数据手册一模一样的,做硬件的在选型的时候才需要注意一下,我们就用商用级的手册。 带着上面四个疑问打开这两份手册,然后就是“啃”手册 I.MX6U IO 命名STM32 中的 IO 都是 PA0~15、PB0~15 这样命名的,I.MX6U 的 IO 是怎么命名的呢? 打开I.MX6ULL 参考手册的第 32 章“Chapter 32: IOMUX Controller(IOMUXC)”,第 32 章的书签如图所示: 从上图可以看出,I.MX6ULL 的 IO 分为两类:SNVS 域的和通用的,这两类 IO 本质上都是一样的,我们就有下面的常用 IO 为例,讲解一下 I.MX6ULL 的 IO 命名方式。图中的形如“ I.MX6ULL 的 GPIO 并不像 STM32一样以 PA0~15 这样命名,他是根据某个 IO 所拥有的功能来命名的。比如我们一看到GPIO1_IO01 就知道这个肯定能做 GPIO,看到 UART1_TX_DATA 肯定就知道这个 IO 肯定能做为 UART1 的发送引脚。 “ 显然不是的, 我们知道 STM32 的很多 IO 是可以复用为其它 功 能 的 , 那 么 I.MX6ULL 的其它 IO 也 是 可 以 复 用 为 GPIO 功能。同样的, I.MX6U IO 复用以“ 从图 可以看到有个名为: GPIO1_IO00 一共可以复用为 9种功能 IO,分别对应 ALT0~ALT8,其中 ALT5 就是作为GPIO1_IO00。GPIO1_IO00 还可以作为 I2C2_SCL、GPT1_CAPTURE1、ANATOP_OTG1_ID 等。这个就是 I.MX6U 的 IO 复用,我们学习 STM32 的时候 STM32 的 GPIO 也是可以复用的。 再来看一个“ 同样的,从图可以看出,UART1_TX_DATA 可以复用为 8 种不同功能的 IO,分为ALT0~ALT5 和 ALT8、ATL9,其中 ALT5 表示 UART1_TX_DATA 可以复用为 GPIO1_IO16。 由此可见,I**.MX6U 的 GPIO 不止 GPIO1_IO00~GPIO1_IO09 这 10 个,其它的 IO 都可以复用为 GPIO 来使用**。
如果只想看每个 IO 能复用什么外设的话可以直接查阅 如果我们要编写代码,设置某个 IO 的复用功能的话就需要查阅第 32 章“ 至此我们就解决了前面的第 3 个疑问,那就是 I.MX6U 的 IO 是有复用功能的,和 STM32一样,如果某个 IO 要作为某个外设引脚使用的话,是需要配置复用寄存器的。 I.MX6U IO 配置细心的读者 应该会发现在《 I.MX6UL 参考手册》32 章“
上面两个都是跟 GPIO_IO00 有关的寄存器,名字上的区别就是红色部分,一个是“MUX”,一个是“PAD”。 从图中可以看出, 我们对照着图来详细看一下寄存器 HYS(bit16)HYS(bit16):对应图中 PUS(bit15:14)PUS(bit15:14):对应图中的 PUE(bit13)PUE(bit13):图没有给出来,当 IO 作为输入的时候,这个位用来设置 IO 使用上下拉还是状态保持器。 PKE(bit12)PKE(bit12):对应图 中的 ODE(bit11)ODE(bit11):对应图中的 SPEED(bit7:6)SPEED(bit7:6):对应图中的 DSE(bit5:3)DSE(bit5:3):对应图中的 SRE(bit0)SRE(bit0):对应图中的 如果你的产品要过 EMC 的话那就可以使用小的压摆率,因为波形缓和,如果你当前所使用的 IO做高速通信的话就可以使用高压摆率。 总结通过上面的介绍,可以看出寄存器 至此我们就解决了前面的第 2 疑问,那就是 I.MX6U 的 IO 是可以设置速度的、而且比 STM32 的设置要更多。但是我们没有看到如何设置 IO 为输入还是输出?IO 的默认电平如何设置等等,所以我们接着继续看。 I.MX6U GPIO 配置
比如 GPIO1_IO00 这个 IO可以复用为: 将其复用为 GPIO 以后还需要对其 GPIO 的功能进行配置,关于 I.MX6U 的 GPIO 请参 在 图的 左 下 角 的 IOMUXC 框 图 里 面 就 有 左上角部分的 GPIO 框图就是,当 IO 用作 GPIO 的时候需要设置的寄存器,一共有八个: DR 寄存器首先来看一下 DR 寄存器,此寄存器是数据寄存器,结构图如图所示: 此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应一个 GPIO。 当 GPIO 被配置为输出功能以后,向指定的位写入数据那么相应的 IO 就会输出相应的高低电平,比如要设置 GPIO1_IO00 输出高电平,那么就应该设置 GPIO1.DR=1。 当 GPIO被配置为输入模式以后,此寄存器就保存着对应 IO 的电平值,每个位对对应一个GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的 bit0 就是 0。 GDIR 寄存器看完 DR 寄存器,接着看 GDIR 寄存器,这是方向寄存器,用来设置某个 GPIO 的工作方 GDIR 寄存器也是 32 位的,此寄存器用来设置某个 IO 的工作方向,是输入还是输出。 同样的,每个 IO 对应一个位, PSR 寄存器接下来看 PSR 寄存器,这是 GPIO 状态寄存器,如图所示 同样的 PSR 寄存器也是一个 GPIO 对应一个位,读取相应的位即可获取对应的 GPIO 的状态,也就是 GPIO 的高低电平值。功能和输入状态下的 DR 寄存器一样。 ICR1和ICR2寄存器接下来看ICR1和ICR2这两个寄存器,都是中断控制寄存器,ICR1用于配置低16个GPIO,ICR2 用于配置高 16 个 GPIO,ICR1 寄存器如图所示: ICR1 用于 IO0~15 的配置, ICR2 用于 IO16~31 的配置。ICR1 寄存器中一个 GPIO 用两个位这两个位用来配置中断的触发方式,和 STM32 的中断很类似,可配置的选线如表所示: 以GPIO1_IO15为例,如果要设置GPIO1_IO15为上升沿触发中断,那么GPIO1.ICR1=2<<30,如果要设置 GPIO1 的 IO16~31 的话就需要设置 ICR2 寄存器了。 IMR 寄存器接下来看 IMR 寄存器,这是中断屏蔽寄存器,如图所示: IMR 寄存器也是一个 GPIO 对应一个位,IMR 寄存器用来控制 GPIO 的中断禁止和使能, ISR寄存器接下来看寄存器 ISR,ISR 是中断状态寄存器,寄存器如图所示: ISR 寄存器也是 32 位寄存器,一个 GPIO 对应一个位,只要某个 GPIO 的中断发生,那么ISR 中相应的位就会被置 1。所以,我们可以通过读取 ISR 寄存器来判断 GPIO 中断是否发生,相当于 ISR 中的这些位就是中断标志位。当我们处理完中断以后,必须清除中断标志位,清除方法就是向 ISR 中相应的位写 1,也就是写 1 清零。 EDGE_SEL 寄存器最后来看一下 EDGE_SEL 寄存器,这是边沿选择寄存器,寄存器如图所示: EDGE_SEL 寄存器用来设置边沿中断,这个寄存器会覆盖 ICR1 和 ICR2 的设置,同样是一个 GPIO 对应一个位。 如果相应的位被置 1,那么就相当与设置了对应的 GPIO 是上升沿和下降沿(双边沿)触发。例如,我们设置 GPIO1.EDGE_SEL=1,那么就表示 GPIO1_IO01 是双边沿触发中断,无论 GFPIO1_CR1的设置为多少,都是双边沿触发。 关于 GPIO 的寄存器就讲解到这里,因为 GPIO 是最常用的功能,我们详细的讲解了 GPIO的 8个寄存器。至此我们就解决了前面的第 3 个和第 4 个疑问,那就是 I.MX6U 的 IO 是需要配置和输出的、是可以设置输出高低电平,也可以读取 GPIO 对应的电平。 I.MX6U GPIO 时钟使能还有最后一个疑问,那就是 I.MX6U 的 GPIO 是否需要使能时钟? STM32 的每个外设都有一个外设时钟,GPIO 也不例外,要使用某个外设,必须要先使能对应的时钟。I.MX6U 其实也一样的,每个外设的时钟都可以独立的使能或禁止,这样可以关闭掉不使用的外设时钟,起到省电的目的。 I.MX6U 的系统时钟参考《I.MX6UL 参考手册》的第 18 章“ CMM 有 CCM_CCGR0~CCM_CCGR6 这 7 个寄存器,这 7 个寄存器控制着 I.MX6U 的所有外设时钟开关,我们以 CCM_CCGR0 为例来看一下如何禁止或使能一个外设的时钟,CCM_CCGR0 结构体如图所示: CCM_CCGR0 是个 32 位寄存器,其中每 2 位控制一个外设的时钟,比如 bit31:30 控制着GPIO2 的外设时钟,两个位就有 4 种操作方式,如表所示: 根据表中的位设置,如果我们要打开 GPIO2 的外设时钟,那么只需要设置CCM_CCGR0 的 bit31 和 bit30 都为 1 即可,也就是 CCM_CCGR0=3 << 30。反之,如果要关闭GPIO2 的 外 设 时 钟 , 那 就 设 置 CCM_CCGR0 的 bit31 和 bit30 都 为 0 即 可 。 CCM_CCGR0~CCM_CCGR6 这 7 个寄存器操作都是类似的,只是不同的寄存器对应不同的外设时钟而已, 至此我们就解决了前面的所有问题都解决了,I.MX6U 的每个外设的时钟都可以独立的禁止和使能,这个和 STM32 是一样。 总结总结一下,要将 I.MX6U 的 IO 作为 GPIO 使用,我们需要一下几步:
硬件原理分析打开 I.MX6U-ALPHA 开发板底板原理图,I.MX6U-ALPHA 开发板上有一个 LED 灯,原理图如下所示: 输出低电平(0)的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平(1)的时候发光二极管 LED0 不会导通,因此 LED0 也就不会点亮。 所以 LED0 的亮灭取决于 实验程序编写编程步骤按照前面讲的,我们需要对 GPIO1_IO03 做如下设置: 使能 GPIO1 时钟GPIO1 的时钟由 CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即可。本教程所有例程已经将 I.MX6U 的所有外设时钟都已经打开了,因此这一步可以不用做。 设置 GPIO1_IO03 的复用功能找到 GPIO1_IO03 的复用寄存器“ 配置 GPIO1_IO03找到 GPIO1_IO03 的配置寄存器“ 设置 GPIO我们已经将 GPIO1_IO03 复用为了 GPIO 功能,所以我们需要配置 GPIO。找到 GPIO3 对 本实验中 GPIO1_IO03 是作为输出功能的,因此 控制 GPIO 的输出电平经过前面几步,GPIO1_IO03 已经配置好了,只需要向 GPIO1_DR 寄存器的 bit3 写入 0 即可控制 GPIO1_IO03 输出低电平。 打开 LED,向 bit3 写入 1 可控制 GPIO1_IO03 输出高电平,关闭LED。 编写代码创建VSCode工程所有的裸机实验我们都在 Ubuntu 下完成,使用 VSCode 编辑器! 既然是实验,肯定要自己动手创建工程,新建一个名为“1_leds”的文件夹,然后在“1_leds”这个目录下新建一个名为“led.s”的汇编文件和一个名为“.vscode”的目录,创建好以后“1_leds”文件夹如图所示: 上图中
我们稍后会在 led.s 这个文件中编写汇编程序。 参考文章:第2期ARM裸机篇:【2】VSode软件的安装与使用_心飞的博客-CSDN博客 参考文章:第2期ARM裸机篇:【2】VSode软件的安装与使用_心飞的博客-个人网站 使用 VSCode 打开 1_leds 这个文件夹,打开以后如图所示: 打开led.s文件。如下图: 编写汇编代码
我们来详细的分析一下上面的汇编代码,我们以后分析代码都根据行号来分析。
其他相关资源下载i.MAX6ULL资料.rar-嵌入式文档类资源-CSDN下载 最近更新欢迎关注微信公众号 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/30 1:31:29- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |