其他分享
首页 > 其他分享> > 【imx6ull学习】01使用c语言点亮led

【imx6ull学习】01使用c语言点亮led

作者:互联网

我以前学习stm32开发时并没有学到有关uboot的知识,经过这两天的学习才知道芯片的启动还需要一系列的设置(如设置sp指针),这一部分设置还不能使用C语言 ,着实麻烦,但设置完之后就可以使用用C语言进行开发了。


点亮led步骤

  1. 设置处理器模式
  2. 设置SP指针
  3. 跳转到C语言
  4. 初始化相关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设置为低电平即可点亮
image

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

这里使用了指针直接操作寄存器,可大大减少我们编写代码工作量。
最后编译下载等工作不再多说。
插电~开机~,轻松秒杀。
image

标签:01,r0,int,unsigned,GPIO1,volatile,led,imx6ull,define,使用C语言
来源: https://www.cnblogs.com/seekwhale13/p/16522765.html