【imx6ull学习】01使用c语言点亮led
我以前学习stm32开发时并没有学到有关uboot的知识,经过这两天的学习才知道芯片的启动还需要一系列的设置(如设置sp指针),这一部分设置还不能使用C语言 ,着实麻烦,但设置完之后就可以使用用C语言进行开发了。
点亮led步骤
- 设置处理器模式
- 设置SP指针
- 跳转到C语言
- 初始化相关GPIO
一二步使用汇编配置,
三四使用C语言。
1.设置处理器模式
6ULL有多种模式。
| 模式 | 描述 | 
|---|---|
| User | 用户模式,非特权模式,大部分程序运行的时候就处于此模式 | 
| Sys(System) | 系统模式,用于运行特权级的操作系统任务 | 
| FIQ | 快速中断模式,进入 FIQ 中断异常 | 
| IRQ | 一般中断模式 | 
| ABT(Abort) | 数据访问终止模式,用于虚拟存储以及存储保护 | 
| SVC(Supervisor) | 超级管理员模式,供操作系统使用 | 
| UND(Undef) | 未定义指令终止模式 | 
| MON(Monitor) | 用于安全扩展模式 | 
| Hyp | 用于虚拟化扩展 | 
我们设置6ULL处于SVC模式 下。设置CPSR寄存器的bit4-0,也就是M[4:0]为10011=0X13。读写状态寄存器需要用到MRS和MSR指令。MRS将CPSR寄存器数据读出到通用寄存器里面,MSR指令将通用寄存器的值写入到CPSR寄存器里面去。
2.设置SP指针
Sp可以指向内部RAM,也可以指向DDR,我们将其指向DDR。正点原子内存大小是512M的,512MB的范围0x80000000~0x9FFFFFFF。我们设置栈大小为0x200000=2MB。处理器栈增长方式,对于A7而言是向下增长的。设置sp指向0x80200000。
汇编代码:
点击查看代码
.global _start  /*全局标号*/
_start:
    /*使能所有外设时钟*/
    ldr  r0, =0x020c4068    /*CCGR0地址*/
    ldr  r1, =0xffffffff    @要向CCGR0写入的数据
    str  r1, [r0]           @将数据0xffffffff写入地址0x020c4068
    ldr  r0, =0x020c406c    /*CCGR1地址*/
    str  r1, [r0]           @CCGR1
    ldr  r0, =0x020c4070    /*CCGR1地址*/
    str  r1, [r0]           @CCGR2
    ldr  r0, =0x020c4074    /*CCGR1地址*/
    str  r1, [r0]           @CCGR3
    ldr  r0, =0x020c4078    /*CCGR1地址*/
    str  r1, [r0]           @CCGR4
    ldr  r0, =0x020c407c    /*CCGR1地址*/
    str  r1, [r0]           @CCGR5
    ldr  r0, =0x020c4080    /*CCGR1地址*/
    str  r1, [r0]           @CCGR6
    /*配置GPIO1_IO03_PIN复用为gpio功能
    *IOMUXC_SW_MUX_CLT_PAD_GPIO1_IO03=5
    *IOMUXC_SW_MUX_CLT_PAD_GPIO1_IO03的寄存器地址为0x020e0068
    */
    ldr  r0, =0x020e0068    /*CCGR0地址*/
    ldr  r1, =0x5           @要向CCGR0写入的数据
    str  r1, [r0]           @将数据0xffffffff写入地址0x020c4068
    /*配置GPIO1_IO03_PIN的电气属性,也就是寄存器
    *IOMUXC_SW_PAD_CLT_PAD_GPIO1_IO03=5
    *IOMUXC_SW_PAD_CLT_PAD_GPIO1_IO03的寄存器地址为0x020e02f4
    *bit0:    0 低速率
    *bit5:3   110 R0/6驱动能力
    *bit7:6   100M速度
    *bit11    0 关闭开路输出
    *bit12    1使能pull/keeper
    *bit13    0 kepper
    *bit15:14 00,100k下拉电阻
    *bit16    0 关闭hys
    */
    ldr  r0, =0x020e02f4    /*GPIO1_IO03电气属性寄存器地址*/
    ldr  r1, =0x10b0           @要向寄存器写入的数据
    str  r1, [r0]           @将数据写入地址0x020e02f4
    
    /*设置GPIO 
    *设置GPIO1_GDIR寄存器,设置GPIO1_IO03为输出
    *GPIO1_GDIR寄存器地址为0x0209c004,设置GPIO1_GDIR的bit3为1,
    *也就是GPIO1_IO03为输出模式
     */
     ldr  r0, =0x0209c004
     ldr  r1, =0x00000008
     str  r1, [r0]
     /* 打开LED,也就是设置 GPIO1_IO03为0
     *GPIO1_DR寄存器地址为0x0209c000
     */
     ldr  r0, =0x0209c000
     ldr  r1, =0
     str  r1, [r0]
loop:
    b loop
3.C语言初始化led
这一部分只需要用我们的c语言对各个寄存器进行配置即可。步骤分为
①、使能 GPIO 对应的时钟。
②、设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用
为 GPIO 功能。
③、设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。
④、第②步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,设置输入/输出、是否使
用中断、默认输出电平等。
电路原理如图:可见只要将LED0,也就是GPIO1_IO3设置为低电平即可点亮

main.c代码如下:
点击查看代码
#include "main.h"
void clk_enable(void)
{
    CCCM_CCGR0 = 0XFFFFFFFF;
    CCCM_CCGR1 = 0XFFFFFFFF;
    CCCM_CCGR2 = 0XFFFFFFFF;
    CCCM_CCGR3 = 0XFFFFFFFF;
    CCCM_CCGR4 = 0XFFFFFFFF;
    CCCM_CCGR5 = 0XFFFFFFFF;
    CCCM_CCGR6 = 0XFFFFFFFF;
}
void led_int(void)
{
    SW_MUX_GPIO_IO03 = 0x5;    /* 复用为GPIO1_03 */
    SW_PAD_GPIO_IO03 = 0x10b0; /*  设置GPIO1_03电气属性*/
    /* GPIO初始化 */
    GPIO1_GDIR = 0x08; /* 设置为输出 */
    GPIO1_DR = 0x0;    /* 打开led */
}
/* 延时函数 */
void delay_short(volatile unsigned int n)
{
    while (n--)
        ;
}
/* 延时,一次循环大约1ms */
void delay(volatile unsigned int n)
{
    while (n--)
    {
        delay_short(0x7ff);
    }
}
/*打开led */
void led_on(void)
{
    GPIO1_DR &= ~(1 << 3); /* bit3清零 */
}
/* 关闭led */
void led_off(void)
{
    GPIO1_DR |= (1 << 3); /* bit3置1 */
}
int main(void)
{
    clk_enable(); /* 使能外设时钟 */
    led_int(); /* 初始化led */
    /* 设置led闪烁 */
    while (1)
    {
        led_on();
        delay(500);
        led_off();
        delay(500);
    }
    return 0;
}
main.h代码:
点击查看代码
#ifndef _MAIN_H
#define _MAIN_H
#define CCCM_CCGR0 *((volatile unsigned int *)0x020c4068)
#define CCCM_CCGR1 *((volatile unsigned int *)0x020c406c)
#define CCCM_CCGR2 *((volatile unsigned int *)0X020c4070)
#define CCCM_CCGR3 *((volatile unsigned int *)0X020c4074)
#define CCCM_CCGR4 *((volatile unsigned int *)0X020c4078)
#define CCCM_CCGR5 *((volatile unsigned int *)0X020c407c)
#define CCCM_CCGR6 *((volatile unsigned int *)0X020c4080)
/* IOMUX相关寄存器 */
#define SW_MUX_GPIO_IO03 *((volatile unsigned int *)0X020e0068)
#define SW_PAD_GPIO_IO03 *((volatile unsigned int *)0X020e02f4)
/* GPIO1相关寄存器 */
#define GPIO1_DR *((volatile unsigned int *)0X0209c000)
#define GPIO1_GDIR *((volatile unsigned int *)0X0209c004)
#define GPIO1_PSR *((volatile unsigned int *)0X0209c008)
#define GPIO1_ICR1 *((volatile unsigned int *)0X0209c00C)
#define GPIO1_ICR2 *((volatile unsigned int *)0X0209c010)
#define GPIO1_IMR *((volatile unsigned int *)0X0209c014)
#define GPIO1_ISR *((volatile unsigned int *)0X0209c018)
#define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209c01C)
#endif // !_MAIN_H
这里使用了指针直接操作寄存器,可大大减少我们编写代码工作量。
最后编译下载等工作不再多说。
插电~开机~,轻松秒杀。

 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号