0
点赞
收藏
分享

微信扫一扫

I.MX6U 裸机开发7. NXP官方SDK部分寄存器定义移植



I.MX6U 裸机开发6. NXP官方SDK部分寄存器定义移植

  • 一、NXP官方SDK说明
  • 二、移植过程
  • 1. 安装
  • 2. 创建工程
  • 3. 新建 cc.h
  • 4. 需要移植的文件
  • MCIMX6Y2.h
  • fsl_common.h
  • fsl_iomuxc.h
  • 5. 文件修改
  • 三、 主体程序编写
  • 1. main.c
  • 2. Makefile编写
  • 3. 启动文件
  • 四、GPIO函数
  • 1. `IOMUXC_SetPinMux`
  • 2. `IOMUXC_SetPinConfig`
  • 3. 宏 `IOMUXC_GPIO1_IO03_GPIO1_IO03`


一、NXP官方SDK说明

I.MX6U NXP官方SDK提供了一套完整的开发工具和库,用于简化I.MX6U处理器的开发过程。其SDK包含了启动代码、驱动程序、库函数、示例代码、文档等,本文仅介绍部分寄存器定义的移植。

二、移植过程

1. 安装

在正点原子给的资料包 《【正点原子】阿尔法Linux开发板(A盘)-基础资料》找到:07、I.MX6U参考资料\03、I.MX6ULL SDK包,下面有两个文件,分别是Linux和Windows下的SDK包。

安装 Windows 版本:

I.MX6U 裸机开发7. NXP官方SDK部分寄存器定义移植_单片机


安装到一个适当的地方,安装后如下图所示:

I.MX6U 裸机开发7. NXP官方SDK部分寄存器定义移植_引脚_02

2. 创建工程

直接复制上节的程序文件 main.c、start.S。

I.MX6U 裸机开发7. NXP官方SDK部分寄存器定义移植_引脚_03

3. 新建 cc.h

cc.h 里用来放一些数据类型的定义,如 __I, int8_t, int16_t等。

//
// Created by Xundh on 2024/11/12.
//

#ifndef LEARN_I_MX6U_CC_H
#define LEARN_I_MX6U_CC_H

#define __I volatile
#define __O volatile
#define __IO volatile

typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;

typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;

#endif //LEARN_I_MX6U_CC_H

4. 需要移植的文件

MCIMX6Y2.h

MCIMX6Y2.h 是 NXP 提供的 I.MX6U 处理器的头文件,包含了对处理器寄存器、外设的定义(如 GPIO、UART、I2C、SPI 等)和控制宏。

MCIMX6Y2.h的位置是在 SDK/devices/MCIMX6Y2/MCIMX6Y2.h。

以下是 MCIMX6Y2.h 中的一些常用定义的示例:

#ifndef _MCIMX6Y2_H_
#define _MCIMX6Y2_H_

#include <stdint.h>

/* GPIO寄存器结构体定义 */
typedef struct {
    __IO uint32_t DR;    /* 数据寄存器, 地址偏移: 0x00 */
    __IO uint32_t GDIR;  /* 数据方向寄存器, 地址偏移: 0x04 */
    __IO uint32_t PSR;   /* 状态寄存器, 地址偏移: 0x08 */
    __IO uint32_t ICR1;  /* 中断配置寄存器1, 地址偏移: 0x0C */
    __IO uint32_t ICR2;  /* 中断配置寄存器2, 地址偏移: 0x10 */
    __IO uint32_t IMR;   /* 中断掩码寄存器, 地址偏移: 0x14 */
    __IO uint32_t ISR;   /* 中断状态寄存器, 地址偏移: 0x18 */
    __IO uint32_t EDGE_SEL; /* 边沿选择寄存器, 地址偏移: 0x1C */
} GPIO_TypeDef;

/* GPIO基地址定义 */
#define GPIO1_BASE (0x0209C000u)
#define GPIO1 ((GPIO_TypeDef *)GPIO1_BASE)

/* 其他外设和寄存器定义... */

#endif /* _MCIMX6Y2_H_ */

fsl_common.h

提供了一些通用的宏定义、类型定义和函数声明,主要用于简化和统一对硬件的访问和操作。
fsl_common.h 的位置是在: SDK/devices/MCIMX6Y2/drivers

fsl_iomuxc.h

主要用于配置 I.MX6U 处理器的 IOMUXC(输入/输出复用控制器),包含了 IOMUXC 寄存器的定义和相关的宏,用于设置引脚的复用功能和电气属性。
fsl_iomuxc.h的位置是在: SDK/devices/MCIMX6Y2/drivers

复制后的项目如下:

I.MX6U 裸机开发7. NXP官方SDK部分寄存器定义移植_单片机_04

5. 文件修改

由于要改的内容非常多且杂乱,本项目忽略更改的具体过程,直接使用了正点原子移值好的文件。

三、 主体程序编写

1. main.c

#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"

/**
 * 使能时钟
 * @return
 */
int enable_clock(void){
    CCM->CCGR1 = 0xffffffff;
    CCM->CCGR2 = 0xffffffff;
    CCM->CCGR3 = 0xffffffff;
    CCM->CCGR4 = 0xffffffff;
    CCM->CCGR5 = 0xffffffff;
    CCM->CCGR6 = 0xffffffff;

    return 0;
}

/**
 * 初始化LED
 * @return
 */
void init_led(void){
/* 1、初始化IO复用 */
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);		/* 复用为GPIO1_IO0 */

    /* 2、、配置GPIO1_IO03的IO属性
     *bit 16:0 HYS关闭
     *bit [15:14]: 00 默认下拉
     *bit [13]: 0 kepper功能
     *bit [12]: 1 pull/keeper使能
     *bit [11]: 0 关闭开路输出
     *bit [7:6]: 10 速度100Mhz
     *bit [5:3]: 110 R0/6驱动能力
     *bit [0]: 0 低转换率
     */
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);

    /* 3、初始化GPIO,设置GPIO1_IO03设置为输出  */
    GPIO1->GDIR |= (1 << 3);

    /* 4、设置GPIO1_IO03输出低电平,打开LED0 */
    GPIO1->DR &= ~(1 << 3);
}

void led_on(void){
    GPIO1->DR &= ~(1 << 3);
}

void led_off(void){
    GPIO1->DR |= (1 << 3);
}

void delay_short(volatile unsigned int n){
    while(n--);
}

void delay(volatile unsigned int n){
    while(n--){
        delay_short(0x7ff);
    }
}

int main(void){
    /** 初始化LED **/
    enable_clock();

    // 初始化LED
    init_led();

    while(1){
        led_on();
        delay(500);
        led_off();
        delay(500);
    }

    return 0;
}

2. Makefile编写

CROSS_COMPILE ?= arm-linux-gnueabihf-
NAME          ?= ledc

# 定义编译器、链接器、对象复制工具和对象转储工具
CC       := $(CROSS_COMPILE)gcc
LD       := $(CROSS_COMPILE)ld
OBJCOPY  := $(CROSS_COMPILE)objcopy
OBJDUMP  := $(CROSS_COMPILE)objdump

# 定义目标文件
OBJS	 := start.o main.o

# 生成二进制文件的规则
$(NAME).bin : $(OBJS)
	# 使用链接器将目标文件链接成 ELF 文件
	$(LD) -Tlinker.ld -o $(NAME).elf $^
	# 使用对象复制工具将 ELF 文件转换成二进制文件
	$(OBJCOPY) -O binary -S $(NAME).elf $@
	# 使用对象转储工具将 ELF 文件反汇编成可读的汇编代码
	$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis

# 将 C 源文件编译成目标文件的规则
%.o : %.c
	# 使用编译器编译 C 文件,生成目标文件
	$(CC) -Wall -nostdlib -c -O2 -o $@ $<

# 将汇编源文件编译成目标文件的规则
%.o : %.S
	# 使用编译器编译汇编文件,生成目标文件
	$(CC) -Wall -nostdlib -c -O2 -o $@ $<

# 清理生成的文件
clean:
	# 删除所有目标文件、二进制文件、反汇编文件和 ELF 文件
	rm -rf *.o $(NAME).bin $(NAME).dis $(NAME).elf

# 下载生成的二进制文件到指定设备
download:
	# 使用 imxdownload 工具将二进制文件下载到 /dev/sdb 设备
	../tools/imxdownload ledc.bin /dev/sdb

3. 启动文件

.global _start
.global _bss_start
_bs_start:
    .word __bss_start

.global _bss_end
_bss_end:
    .word __bss_end


_start:
    /** 设置处理进入 SVC 模式 */
    MRS R0, CPSR        /** 读取当前的 CPSR */
    BIC R0, R0, #0x1F   /** 清除 CPSR 的低 5 位 */
    ORR R0, R0, #0x13   /** 设置 CPSR 为 SVC 模式 */
    MSR CPSR, R0        /** 设置 CPSR */

    /** 清除 bss 段 */
    LDR R0, =__bss_start    /** 获取 bss 段的起始地址 */
    LDR R1, =__bss_end      /** 获取 bss 段的结束地址 */
    MOV R2, #0              /** 设置清零的值 */
    B bss_loop              /** 跳转到 bss_loop */
bss_loop:
    STMIA R0!, {R2}         /** 将 R2 的值存储到 R0 指向的地址,然后 R0 += 4 */
    CMP R0, R1              /** 比较 R0 和 R1 的值, 即有没有到结尾 */
    BLE bss_loop            /** 如果 R0 <= R1,跳转到 bss_loop */
bss_end:
    /** 设置堆栈 */
    LDR SP, =0x80200000
    B main              /* 跳转到C语言main函数*/

四、GPIO函数

1. IOMUXC_SetPinMux

IOMUXC_SetPinMux 函数用于设置 IOMUXC(输入/输出复用控制器)引脚的功能模式。
函数参数如下:

  • muxRegister:引脚复用寄存器的地址。这个寄存器用于选择引脚的功能。
  • muxMode:引脚复用模式。这个参数指定引脚的功能模式,例如 GPIO、UART、I2C 等。
  • inputRegister:选择输入寄存器的地址。这个寄存器用于选择输入信号的源。
  • inputDaisy:输入菊花链选择。这个参数用于选择输入信号的菊花链配置。
  • configRegister:配置寄存器的地址。这个寄存器用于配置引脚的属性,例如上拉/下拉、电平转换速度等。
  • inputOnfield:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的 bit4, SION位,控制引脚的输入路径,0:禁用软件输入,引脚的输入由硬件控制;1是启用软件输入。

对于inputDaisy配置详细说明:inputDaisy 参数用于选择输入信号的菊花链配置。菊花链配置是指在多路复用器中选择特定的输入路径,以便将信号路由到正确的输入端口。这个参数通常用于配置特定的输入信号源,以确保信号能够正确地传递到目标模块。 在 IOMUXC 配置中,inputDaisy 参数的值通常是一个寄存器地址,用于选择输入信号的源。例如,当一个引脚可以连接到多个输入信号时,inputDaisy 参数可以指定使用哪个输入信号。

2. IOMUXC_SetPinConfig

IOMUXC_SetPinConfig 用于设置 IOMUXC(输入/输出复用控制器)引脚的电气属性值。

函数参数与 IOMUXC_SetPinMux 类似 ,区别在最后一个参数。

  • configValue:引脚配置值。这个参数用于设置引脚的具体属性。

3. 宏 IOMUXC_GPIO1_IO03_GPIO1_IO03

IOMUXC_GPIO1_IO03_GPIO1_IO03 是一个宏定义,用于配置 IOMUXC(输入/输出复用控制器)引脚的复用模式和属性。该宏包含了多个参数的值,这些参数在调用 IOMUXC_SetPinMuxIOMUXC_SetPinConfig 函数时会展开为实际的参数列表。

具体定义如下:

#define IOMUXC_GPIO1_IO03_GPIO1_IO03 0x020E0200U, 0x5U, 0x00000000U, 0x0U, 0x020E048CU

该宏定义包含以下参数:

  1. 0x020E0200U:引脚复用寄存器的地址。
  2. 0x5U:引脚复用模式。
  3. 0x00000000U:选择输入寄存器的地址。
  4. 0x0U:输入菊花链选择。
  5. 0x020E048CU:配置寄存器的地址。

这些参数用于配置 GPIO1_IO03 引脚的复用模式和属性。

本文代码开源仓库地址:
https://gitee.com/xundh/learn_i.mx6u/tree/master/07_ledc_nxp_sdk


举报

相关推荐

0 条评论