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

为了后续使用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 的最后两点合并为了一步。

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第1张图片

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

二、寄存器设置

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

1、时钟源初始化(CCGRx)

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

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第2张图片

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第3张图片

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第4张图片

因此,我们采用另一种做法,索性初始化所有时钟源 (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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第5张图片

2、设置IO复用(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第6张图片

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

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

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第7张图片

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第8张图片

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

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第9张图片

由此可以总结得到

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第10张图片

3、初始化GPIO(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第11张图片

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

2-1:保留位

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第12张图片

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第13张图片

10-8:保留位

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

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

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

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第14张图片

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 是上升沿和下降 沿(双边沿)触发

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第15张图片

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

寄存器: GPIO1_DR
基地址: 0x209C000
初始值: 0

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

【裸机驱动LED】使用汇编代码驱动LED(一)—— 寄存器解析篇_第16张图片

你可能感兴趣的:(#,裸机开发,单片机,嵌入式硬件)