正点原子IMX6ULL裸机开发,C语言配置和C语言实现亮灯闪烁

目录

设置处理器模式

设置SP指针

跳转C语言

软件编写

链接脚本

利用makefile进行编译


设置处理器模式

设置6ULL处于SVC模式下。

设置程序状态寄存器(CPSR)的bit4-0

即,将寄存器M[4:0]设置为10011 = 0X13。

读写状态寄存器需要使用汇编中的MRS和MSR指令

MRS指令将CPSR寄存器中的数据读出到通用寄存器中,MSR将通用寄存器中的数据写入CPSR之中

设置SP指针

SP指针可以指向内部RAM,也可以指向DDR,我们这里将其指向DDR。SP设置到哪里?512MB的范围0X80000000-0X9FFFFFFF。栈大小,0X200000 = 2MB。在A7中,栈的增长方式是向下增长的(即,sp指针由高地址向低地址方向增长)。所以我们将SP指针设置到0X80000000+0X200000→0X80200000

跳转C语言

使用b指令直接跳转到main函数所在位置。

 利用汇编代码完成上述配置

.global  _start

_start:
    /*设置处理器进入SVC模式----修改0-4位但是不能改变其他位 */
    MRS R0, CPSR        /*将CPSR中的数据先进行读取 */
    BIC R0, R0, #0x1f   /*清除CPSR的bit4-0 (本质为与运算)*/
    ORR R0, R0, #0x13   /*设置为SVC模式(利用或运算) */
    MSR CPSR, R0        /*将R0写入CPSR中 */


    /*设置sp指针 */
    LDR sp, =0x80200000 /*恩智浦的处理器在bin文件的头部已经初始化DDR了,所以只需要设置sp指针 */
    b main              /*跳转到C语言main函数 */

软件编写

首先编写main函数的头文件定义寄存器

#ifndef __MAIN_H
#define __MAIN_H

/*定义需要使用的寄存器*/
#define CCM_CCGR0           *((volatile unsigned int*)0x020C4068)
#define CCM_CCGR1           *((volatile unsigned int*)0x020C406C)
#define CCM_CCGR2           *((volatile unsigned int*)0x020C4070)
#define CCM_CCGR3           *((volatile unsigned int*)0x020C4074)
#define CCM_CCGR4           *((volatile unsigned int*)0x020C4078)
#define CCM_CCGR5           *((volatile unsigned int*)0x020C407C)
#define CCM_CCGR6           *((volatile unsigned int*)0x020C4080)

/*IOMUX相关寄存器*/
#define SW_MUX_GPIO1_IO03   *((volatile unsigned int*)0x020E0068)
#define SW_PAD_GPIO1_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

然后进行main函数的写入,本次实现的效果为led灯闪烁

#include "main.h"


/*使能外设时钟*/
void clk_enable(void)
{
    //将时钟全部使能
    CCM_CCGR0 = 0xFFFFFFFF;
    CCM_CCGR1 = 0xFFFFFFFF;
    CCM_CCGR2 = 0xFFFFFFFF;
    CCM_CCGR3 = 0xFFFFFFFF;
    CCM_CCGR4 = 0xFFFFFFFF;
    CCM_CCGR5 = 0xFFFFFFFF;
    CCM_CCGR6 = 0xFFFFFFFF;
}
/*初始化led*/
void led_init(void)
{
    //复用为GPIO1---IO03
    SW_MUX_GPIO1_IO03 = 0x5;
    /*设置GPIO1_IO03的电气属性
    * bit0:     0 低速率(压摆率)
    * bit5~3:   110 R0/6的驱动能力
    * bit7~6:   10 100MHz的速度
    * bit11:    0 关闭开路输出
    * bit12:    1 使能pull/keeper
    * bit13:    0 keeper
    * bit14~15: 00 100k下拉
    * bit16:    0 关闭hys
    */
    SW_PAD_GPIO1_IO03 = 0x10B0;
    //GPIO初始化
    //设置为输出模式
    GPIO1_GDIR = 0x8;
    //led默认打开
    GPIO1_DR = 0x0;
}
/*短延时*/
void delay_short(volatile unsigned int n)
{
    while(n--){}
}

/*延时,一次循环大概是一毫秒 在主频396MHz
* n:延时ms数
*/
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)
{
    //初始化led
    clk_enable();
    led_init();

    //设置led闪烁
    while(1)
    {
        led_on();
        delay(500);

        led_off();
        delay(500);
    }
    return 0;
}

链接脚本

为了解决在编译过程中,文件链接顺序出现问题我们需要写一个链接脚本,如果不写这个脚本,就要注意连接时文件的先后顺序。

链接脚本描述了要链接的文件,以及顺序,和链接首地址(文件后缀为.lds)

SECTIONS
{
    . = 0x87800000;
    .text :
    {
        start.o
        *(.text)
    }
    .rodata ALIGN(4)    : {*(.rodata)}
    .data   ALIGN(4)    : {*(.data)}
    __bss_start = .;
    .bss    ALIGN(4)    : {*(.bss) *(COMMON)}
    __bss_end = .;
}

利用makefile进行编译

编译和烧录过程可见https://blog.csdn.net/wusuowei12138/article/details/132059178

makefile如下:

objs = start.o main.o

ledc.bin:$(objs)
	arm-linux-gnueabihf-ld -Timx6ull.lds $^ -o ledc.elf
	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@
	arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis


%.o : %.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<

%.o : %.s
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $<

clearn:
	rm -rf *.o ledc.elf ledc.dis ledc.bin

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 正点原子imx6ull底板是基于NXP公司的i.MX6ULL处理器设计的一款开发板,具有高性能和低功耗两大特点。该底板采用了6层PCB板,保证了板子的稳定性和信号完整性,同时还具有完善的电源管理系统,让开发者可以更加方便地进行开发。 该底板主板集成了512MB DDR3 RAM,8GB eMMC存储器以及微型SD卡插槽,为用户提供了基本的数据存储和扩展接口,方便进行相关操作。该底板还支持多种网络接口,包括以太网、WiFi和蓝牙,可以使用户灵活选择满足自己需求的网络环境。 此外,该底板还具有丰富的外设接口,包括多个UART、I2C、SPI、PWM、ADC等接口,方便开发者进行通信、控制和数据采集。支持HDMI显示输出和MIPI DSI接口,可以连接外部显示器进行图像、视频等显示。 总之,正点原子imx6ull底板是一款功能强大、性能稳定的开发板,具有广泛的使用场景和应用。无论是物联网、嵌入式系统开发,还是机器人、智能家居、电子产品等都可以使用该底板来实现自己的创意和想法。 ### 回答2: 正点原子imx6ull底板是一种基于NXP i.MX6ULL处理器设计的开发板,采用了6层板设计,具有高性能、稳定性和可靠性等特点。这款底板的主频高达696MHz,内存容量为512MB DDR3,存储容量为4GB eMMC,同时还带有TF卡接口,可以扩展存储容量。除此之外,该底板还具备多种接口,包括USB、UART、以太网等,方便用户进行二次开发和应用。同时,该底板支持多种操作系统,如Linux、Android等,用户可以根据需要进行选择。此外,正点原子imx6ull底板还支持多种外设,如LCD、摄像头等,可以实现更丰富的应用场景。总之,该底板是一款性能优越、功能丰富、易于扩展的开发板,适合各类嵌入式应用场景,例如工业控制、智能家居、医疗设备等。 ### 回答3: 正点原子imx6ull底板是一款核心板,采用了i.MX 6ULL处理器,具有低功耗和高性能的特点。该底板具有丰富的硬件资源,如独立的芯片供电、Gigabit以太网、USB Host和OTG、UART、SPI、I2C等接口,能够满足不同场景下的开发需求。同时,该底板支持蓝牙、WiFi、4G等无线通信模块,方便集成智能化设备中。此外,该底板还有可扩展的TF卡存储和LCD屏接口,为开发者提供了更大的空间来满足不同的应用需求。 值得注意的是,正点原子imx6ull底板提供了多样化的软件开发环境,支持Ubuntu、Android、Yocto、OpenWRT等多种系统,开发者可以根据需求自由选择不同的系统进行开发。此外,正点原子还提供了完善的开发文档和示例代码,帮助开发者快速上手和开发。总之,正点原子imx6ull底板是一款性能强大、可扩展性好的核心板,非常适合在物联网、车联网、智慧家居等领域的开发应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值