MX6U的IO口作为GPIO的步骤总结:
- 使能GPIO对应的时钟
- 设置寄存器IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用为 GPIO 功能。
- 设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。
- 第2步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,设置输入/输出、是否使 用中断、默认输出电平等。
总结:类似于stm32的初始化,先使能时钟,在对引脚初始化,然后设置高低电平输入输出。在MX6U的IO口复用为GPIO时的时钟使能,需要对CCM(ClockController Module)里面的寄存器做设置,开发手册上的例子就是控制GPIO的时钟在寄存器的31和30位,按手册设置就行。
GUN汇编语法知识:
- 语句有三个可选部分: label:instruction @ comment ,这里的label是标号,instruction是指令,@符号是注释。举个例子: 这里的add:就是标号,@后面为注释,中间为代码指令。
add: MOVS R0, #0X12 @设置 R0=0X12
指令 目的 源 描述 MOV R0 R1 将R1里面的数据复制到R0中 MRS
(只能用于特殊寄存器数据传给通用寄存器)
R0 CPSR 将特殊寄存器CPSR里面的数据复制到R0中 MSR
(只能用于通用寄存器的数据传给特殊寄存器)
CPSR R1 将R1里面的数据复制到特殊寄存器CPSR中 MOV R0,R1 @将寄存器 R1 中的数据传递给 R0,即 R0=R1 MOV R0, #0X12 @将立即数 0X12 传递给 R0 寄存器,即 R0=0X12
指令 描述
LDR Rd, [Rn , #offset]
从存储器 Rn+offset 的位置读取数据存放到 Rd 中。
STR Rd, [Rn, #offset]
将 Rd 中的数据写入到存储器中的 Rn+offset 位置。
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004 LDR R1, [R0] @读取地址 0X0209C004 中的数据到 R1 寄存器中
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004 LDR R1, =0X20000002 @R1 保存要写入到寄存器的值,即 R1=0X20000002 STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
指令 描述 PUSH <reg list>
将寄存器列表存入栈中。
POP <reg list>
从栈中恢复寄存器列表。
还有一种写法:PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
STMFD SP!,{R0~R3, R12} @R0~R3,R12 入栈 STMFD SP!,{LR} @LR 入栈 34 LDMFD SP!, {LR} @先恢复 LR LDMFD SP!, {R0~R3, R12} @再恢复 R0~R3, R12
指令 描述 B <label>
跳转到 label,如果跳转范围超过+/-2KB,可以指定 B.W<label>使用 32 位版本的跳转指令, 这样可以得到较大范围的跳转
BX <Rm>
间接跳转,跳转到存放于 Rm 中的地址处,并且切换指令集
BL <label>
跳转到标号地址,并将返回地址保存在 LR 中。
BLX <Rm>
结合 BX 和 BL 的特点,跳转到 Rm 指定的地址,并将返回地址保存在 LR 中,切换指令集。
_start: ldr sp,=0X80200000 @设置栈指针 b main @跳转到 main 函数
上面用bl就是C语言中的中断处理函数,还要回来继续处理执行下面的程序。push {r0, r1} @保存 r0,r1 cps #0x13 @进入 SVC 模式,允许其他中断再次进去 bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中 cps #0x12 @进入 IRQ 模式 pop {r0, r1} str r0, [r1, #0X10] @中断执行完成,写 EOIR
- 还有算数运算指令和逻辑运算指令,比较简单,用到就可以理解。
总结:看到后面发现自己对汇编这里的知识还有所不熟练,特地重新针对文档看一遍,记录一下基础的知识点
GPIO的8个寄存器介绍:
- DR寄存器:是数据寄存器,32位,控制高低电平,当GPIO被配置为输出功能,向指定位写入数据那么相应的IO就会输出相应的高低电平。
- GDIR寄存器:设置某个IO的工作方向,是输出还是输入。输入0输出1
- PSR状态寄存器:功能和输入状态下的DR寄存器一样
- ICR1和ICR2寄存器:中断控制寄存器,ICR1用于配置低16个的GPIO,ICR2用于配置高16个的GPIO,00-低电平触发;01-高电平触发;10-上升沿触发;11-下降沿触发。举个例子:如果要设置GPIO1_IO15为上升沿触发中断,那么GPIO1.ICR1=2<<30
- IMR寄存器:用来控制GPIO的中断禁止和使能
- SIR寄存器:读取中断是否发生,类似于中断标志位,处理完中断后需要清除中断标志位。
- EDGE_SEL寄存器:设置边沿中断,会覆盖ICR1和2的设置。