【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇

news/2024/11/7 10:41:29/

为了后续使用C语言驱动LED,事先学习汇编代码驱动LED,有如下好处:

  • 熟悉一些基本的汇编语法
  • 了解驱动LED的基本流程
  • 了解驱动LED需要用到哪些寄存器
  • 作为一个初学者,可以锻炼自己阅读开发文档的能力

本文的主要目的是了解驱动LED的基本流程,以及要驱动LED需要使用哪些寄存器。


目录

一、驱动LED的基本流程

二、寄存器设置

1、时钟源初始化(CCGRx)

2、设置IO复用(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03)

3、初始化GPIO(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03)

4、GPIO 输出(GPIOx_GDIR、GPIOx_DR)


一、驱动LED的基本流程

stm32驱动LED的基本流程为:

  • 使能指定GPIO时钟
  • 设置IO复用,将其复用为GPIO。(GPIO只是IO众多功能的一种)
  • 初始化GPIO。即设置电气属性,比如设置输入还是输出、上下拉、速度等
  • 设置 GPIO 输出高电平还是低电平。

但是 imx6ull 驱动LED的过程是否也是如此呢?我们需要查看《IMX6ULL参考手册》的第28章 GPIO,虽然只有三步,这是因为把 stm32 的最后两点合并为了一步。

因此,对于 imx6ull 我们驱动 LED 可以采取和stm32一样的步骤

二、寄存器设置

接下来我们将针对每一步,详细了解寄存器的设置方法。

1、时钟源初始化(CCGRx)

led灯闪烁,说白了就是高低电平的转换,但是每隔多久转换一次,这就需要时钟来控制了。按照《IMX6ULL参考手册》的提示,我们要去第18章CCM了解时钟源的初始化。不同模块对应的时钟源是不一样的,我们可以在 18.4 找到GPIO模块对应的时钟源。

从下图我们可以看到,GPIO模块的时钟源使能由寄存器 CCGRx 控制,GPIO模块有 5 组。CCGR1 寄存器的 CG13(即第27-16 bit)控制着 GPIO1 的时钟源。(其他类似)

 现在有两种做法,一种是只初始化某一个 GPIOx 的时钟,即只初始化某一个 CCGRx 寄存器。实际上不同时钟源要改的引脚都不一样,这样很是麻烦。

因此,我们采用另一种做法,索性初始化所有时钟源 (CCGR0~6) 的所有模块(CG0~15,即引脚 0-32)。(可以在参考手册的18.6.25 找到每个时钟源CCGRx对应的基地址)

时钟源(寄存器): CCGR0
起始地址: 0x20C4068
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR1
起始地址: 0x20C406C    # 一个时钟源占32bit,即4字节(0x20C406C - 0x20C4068 = 4)
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR2
起始地址: 0x20C4070
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR3
起始地址: 0x20C4074
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR4
起始地址: 0x20C4078
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR5
起始地址: 0x20C407C
初始化值:0xFFFFFFFF时钟源(寄存器): CCGR6
起始地址: 0x20C4080
初始化值:0xFFFFFFFF

2、设置IO复用(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03

绕了这么一大圈,终于可以回到 28.4 小节了。接下来我们要指定 IO 引脚为GPIO功能,由28.4.3给的提示可以知道,要设为 GPIO 模式,我们要设置的是 IOMUXC 寄存器。所以我们要前往第32章 IOMUX。

我们可以看到第32章下有一小节为IOMUXC Memory,IOMUXC下有很多寄存器,这些寄存器分为了两类:

  • 第一类 IOMUXC_SW_MUX_CTL_PAD_<module name>:用于设置对应模块的IO复用
  • 第二类 IOMUXC_SW_PAD_CTL_PAD_<module name>:用于初始化对应模块,即设置电气属性。

我们现在要设置的是IO复用,那自然就要找跟GPIO相关的

从这里你会发现,这里只有GPIO1 可以设置IO复用,下面要确定的就是GPIO1 中的第几个引脚,连接着 LED。我们先在《imx6ull 底板原理图》上找到 LED 模块,底板上LED名称为 LED0。 

然后我们在《核心板原理图》上找一下 LED0 连到了核心板的哪个引脚。我们发现是 GPIO_3,那么这里就表示的是 GPIO1_3,即 GPIO1 的第3个引脚。

我们在第32章的IOMUX下找到后缀为 GPIO1_IO03 的寄存器,我们只需要设置 MUX_MODE 字段,设置为 0101,其他字段保持不变。

由此可以总结得到

寄存器: IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
基地址: 0x20E0068
初始化值: 0x5    # 低四位为0101,其他位不变

3、初始化GPIO(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03

上一步其实已经公布了接下来要做啥,没错,找到前缀为 IOMUXC_SW_PAD_CTL_PAD 而且跟GPIO相关的寄存器。(这个比较难找,在32.6.156,大概在1793页)接下来我们要逐一设置寄存器中的每一个字段。

0:SRE,表示电压转换速率,我们选择低转换速率,即设为 0

2-1:保留位

5-3:DSE,表示驱动能力,我们选择 R0/6,即设为 110

 7-6:SPEED,表示速度。我们选择100M,即设为10

10-8:保留位

11:ODE,表示是否关闭开路输出,这里选择关闭,设为 0

12:PKE,pull / keeper 使能,这里选择打开,设为 1

13:PUE,选择 keeper功能,设为 0

15–14:PUS,选择上下拉,默认下拉,设为 00 

16:HYS,禁用,设为 0(该字段用的比较少)

31-17:保留位

寄存器: IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
基地址: 0x020E02F4
初始值: 0x10B0

4、GPIO 输出(GPIOx_GDIR、GPIOx_DR

 我们回到第28章,GPIO一共有五组,每一组都有8个寄存器,每个寄存器对应着不同的功能(属性)。但是实际上我们只需要设置其中两个寄存器,即 GPIOx_DR 和 GPIOx_GDIR。

  • GPIOx_DR数据寄存器用于输出或者读取数据,比如GPIO设置为输出,我们就可以使用该寄存器来让引脚输出高电平或者低电平。
  • GPIOx_GDIR方向寄存器用于设置GPIO是输入还是输出。如果是输入,我们就可以从 GPIOx_DR 寄存器读取内容;如果是输出,我们就需要向 GPIOx_DR 寄存器输出内容。
  • PSRGPIO状态寄存器读取相应的位即可获取对应的 GPIO 的状态。
  • ICR1、ICR2中断寄存器用来配置中断的触发方式(上升沿触发、下降沿触发),ICR1 用于 IO0~15 的配置, ICR2 用于 IO16~31 的配置。
  • IMR:中断使能寄存器。用于控制中断的使能和禁止。
  • ISR:中断状态寄存器。
  • EDGE_SEL:设置边缘中断。这个寄存器会覆盖 ICR1 和 ICR2 的设置,同样是一 个 GPIO 对应一个位。如果相应的位被置 1,那么就相当与设置了对应的 GPIO 是上升沿和下降 沿(双边沿)触发

寄存器: GPIO1_GDIR
基地址: 0x209C004
初始值: 0x00000008    # 因为是GPIO1的第三个引脚设为输出,即第3 bit应为1(00001000)寄存器: GPIO1_DR
基地址: 0x209C000
初始值: 0

LED0输出低电平的时候,二极管导通,此时灯会亮,所以寄存器 DR 的初始值应该为 0


http://www.ppmy.cn/news/242923.html

相关文章

java线程池

一、线程池的好处 1、为什么需要使用线程池 反复创建线程开销大 &#xff08;内存和垃圾回收&#xff09;过多的线程会导致内存消耗线程池可以规避上述问题&#xff0c;它可以复用每一个线程&#xff0c;并且还可以控制线程总量&#xff0c;便于管理 3、不使用线程池会怎么样…

关于API接口的介绍及简单的API接口代码示例

API接口是指应用程序接口&#xff0c;是不同应用之间进行通讯的一种方法。它提供了一种简单的方式来交换数据和交互。通过API接口&#xff0c;不同的应用和服务可以进行互操作&#xff0c;为开发人员提供更多的开发可能性。 API接口具有许多优点。它们是通用的&#xff0c;这意…

r7 5700g对比5800x选哪个

锐龙7 5800X&#xff0c;单CCD&#xff0c;8核心16线程&#xff0c;4MB二级缓存&#xff0c;32MB三级缓存&#xff0c;基准频率3.8GHz&#xff0c;最高加速4.7GHz&#xff0c;热设计功耗为105W。 组装电脑选5800x还是R5 5700g怎么搭配更合适这些点很重要 http://www.adiannao.c…

达人评测 r7 3700x和r5 5600g选哪个好

R5 5600G配备了6核12线程&#xff0c;拥有3MB二级缓存和三级缓存16MB&#xff0c;基础频率为3.9GHz&#xff0c;最高加速 为4.4GHz&#xff0c;内置核显为Vega 7 GPU&#xff0c;核显频率为1900MHz 组装电脑选r5 5600g还是r7 3700x怎么搭配更合适这些点很重要 http://www.adian…

r7 5800h和i5 12500h哪个好

R7 5800H 为 8 核 16 线程&#xff0c;主频 3.2GHz&#xff0c;三级缓存翻倍至 16MB&#xff0c;搭载了 DDR4-3200 内存。 选R7 5800H还是i5 12500h这些点很重要!看完你就知道了 http://www.adiannao.cn/dy i5-12500h参数配置&#xff1a;其工艺也是10nm&#xff0c;2.5GHz的主…

华硕 ROG PG27UQR 电竞显示器参数 华硕 ROG PG27UQR 评测

华硕 ROG PG27UQR 电竞显示器&#xff08;27’/4K / 160Hz / HDR600 / Fast IPS / 1ms&#xff09;&#xff0c;定价 5699 元&#xff0c;首发到手价 4699 元。 华硕 ROG PG27UQR更多使用感受和评价 http://rog.jd.com 这款显示器采用了 27 英寸 Fast IPS 面板&#xff0c;拥…

Day12 性能测试详解——什么是性能测试?、性能测试分类及常用指标、性能测试流程、总结

Day12 性能测试详解——什么是性能测试?、性能测试分类及常用指标、性能测试流程、总结 文章目录 Day12 性能测试详解——什么是性能测试?、性能测试分类及常用指标、性能测试流程、总结什么是性能测试?一、为什么要学习性能测试1.1 业务需求 解决方案1.2 问题二、什么是性能…

vue3+uniapp开发小程序踩坑指南(持续更新)

小程序常见问题汇总&#xff1a; 1、TypeError: Cannot read property forceUpdate of undefined 原因&#xff1a;没有配置小程序AppID 2、define is not defined 报错一堆文件找不到&#xff0c;并且有define is not defined错误提示 原因&#xff1a;没有配置基础库或者基…