ARM的纯汇编实验(001) |
您所在的位置:网站首页 › 灯闪烁的频率 › ARM的纯汇编实验(001) |
这篇文章的内容是记录笔者学习ARM时的第一次汇编语言实验,LED闪烁 我从淘宝买了一块主控制芯片为IMX6ULL(之后简称芯片)的开发板,上面有很多外设。但我想,学习开发的第一步是点亮一个LED。 一,硬件原理分析 我首先把开发板的电路原理图打开,查看这个LED与我们的芯片是如何建立物理联系的;这样我们才能知道如何控制它。 连接LED的引脚被称为"LED0"。所以我们知道对应关系是LED0 = 0时,亮;LED0=1时,灭。 但LED0依然不是连接到芯片的引脚名,我在原理图中跟踪到,LED0又连接到了芯片的GPIO1_IO03引脚。 如此一来,芯片如何控制LED就很清楚了: GPIO1_IO03输出0,LED亮; GPIO1_IO03输出1, LED灭。 二,芯片配置分析 如何控制芯片的GPIO1_IO03引脚呢?我便又要打开《IMX6UL参考手册》。 翻到26章,查看到如下内容。这说明,要控制GPIO, 1.要配置IOMUXC寄存器组,设置引脚为GPIO工作模式。 2.配置GPIO的方向寄存器 GPIO_GDIR,对应位设置为1,才是输出模式。 3.给GPIO_DR寄存器的对应位写入1。 那么我们就按照它的步骤来。继续查阅30章:IOMUXC. 可以看到,有两个寄存器和GPIO_IO03有关。说是说寄存器,其实这里的寄存器和ARM内核的R0,R1不一样;它们有地址,赋值的时候和普通的存储器一样操作即可。 通过以上截图可知, 寄存器名 地址 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 0x020E 0068 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 0x020E 02F4 而要给什么样的值? 根据手册,IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x05 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的配置就比较麻烦,有很多含义位。干脆直接使用默认的。 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x10B0 (复位后默认值),至于这个值是什么含义,可看手册说明。
再配置GPIO_GDIR寄存器。看这手册26章:GPIO,可知 寄存器名 地址 GPIO_GDIR 0x0209 C004 然后使用鼠标点击一下上图的蓝色的超文本链接,就跳转到了寄存器含义。很明显,我们要给GPIO1_IO03配置为输出模式,那就是让GPIO1_GDIR的第3位为1 最后一步,配置GPIO1_DR,即[0x0209C000] 的第3位决定了输出电平0还是1。
所以芯片本身的参考手册《IMX6UL参考手册》实在是一个好东西。咱不用四处找教程,因为它已经说的很清楚。如果对于英文原版不习惯的同学,建议打开翻译软件,硬着头皮看下去。看得多了,也就习惯了。
三,代码编写 根据以上的分析,我们会发现,在配置芯片的过程中,存在频繁的向存储器写入数据的过程。所以干脆写成函数,方便以后使用。 //函数set_mem_value:设置存储器值 R0:存储器地址 R1:值(32 bits) set_mem_value: PUSH {R0-R4,LR} STR R1,[R0] POP {R0-R4,PC} 再写一个简单的延时函数 //函数delay:延时 delay: PUSH {R0-R4,LR} LDR R0,=0xFFFFF delay_loop: CMP R0,#0 BEQ delay_return SUB R0,#1 B delay_loop delay_return: NOP POP {R0-R4,PC}
这样,整个软件实现的流程可以概述为: 1.配置IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 2.配置IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 3.配置GPIO_GDIR 4.配置GPIO1_DR,输出1,延时 5.配置GPIO1_DR,输出0,延时 6.回到步骤4
整体代码如下: .global _start _start: //[0X020E0068] = 0x05 配置IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 LDR R0,=0X020E0068 LDR R1,=0X05 BL set_mem_value //[0X020E02F4] = 0X10B0 配置IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 LDR R0,=0X020E02F4 LDR R1,=0X10B0 BL set_mem_value //[0X0209C004] = 0X0000008 配置GPIO_GDIR LDR R0,=0X0209C004 LDR R1,=0X0000008 BL set_mem_value
LDR R0,=0x0209c000 led_flash: //LED 灭 ORR R1,R1,#0x08 BL set_mem_value BL delay //LED 亮 BIC R1,R1,#0X08 BL set_mem_value BL delay B led_flash
//函数set_mem_value:设置存储器值 R0:存储器地址 R1:值(32 bits) set_mem_value: PUSH {R0-R4,LR} STR R1,[R0] POP {R0-R4,PC} //函数delay:延时 delay: PUSH {R0-R4,LR} LDR R0,=0xFFFFF delay_loop: CMP R0,#0 BEQ delay_return SUB R0,#1 B delay_loop delay_return: NOP POP {R0-R4,PC} 四,烧录代码 1.把代码放入一个文件,命名为code.s。 2.在Linux系统下进行编译,生成.imx文件,烧录到SD卡中。 3.把SD卡插在开发板的SD插槽中,并改拨码,使得芯片从SD卡启动。 五,运行效果 给开发板上电,可以看到LED在闪烁。见黄色方框标注。 当然,这样一张图,也看不出什么闪烁效果。将就吧,至少证明代码是确实运行过的。
|
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |