IMX6ULL裸机篇SPI实验-IMX6ULL硬件浮点的开启

一.   SPI 实验

SPI实验:学习如何使用 I.MX6U 的 SPI 接口来驱动 ICM-20608,读取 ICM-20608 的六轴数据。

ICM20608 传感器包括陀螺仪与加速度计,还有温度值。本实验就是读取 陀螺仪的角速度,加速度计的加速值,以及芯片温度的值。

本文学习一下,开启 IMX6ULL芯片的硬件浮点支持操作(因为SPI实验读取的数据有浮点型数据)。

二.  IMX6ULL开启硬件浮点

我们在使用浮点计算的时候程序卡死了。串口卡死的原因有两点,如下所示:

(1)  IMX6ULL芯片没有开启硬件浮点运算。

(2)  在编译的时候没有使用浮点编译选项。

I.MX6U 的 Cortex-A7 是支持 NEON FPU(VFPV4_D32) 的,但是在使用 I.MX6U 的硬件 FPU 之前是先要 开启的。

下面具体介绍 Cortex-A系列芯片硬件浮点的开启操作。

1.   开启硬件浮点运算

IMX6ULL芯片属于 Cortex-A7系列芯片,这里需要参考两个文档,在 "/参考资料" 目录下。分别为

" Cortex-A7 Technical ReferenceManua.pdf " 文档 与

"ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf "文档 。

IMX6ULL芯片支持硬件浮点功能,其中涉及两个寄存器的配置:CPACR寄存器 FPEXC寄存器。

CPACR寄存器:(" Cortex-A7 Technical ReferenceManua.pdf " 文档中

bit[31]:  与 VFP指令有关,VFP即 Vector Float Point,向量浮点体系结构。该位写 0。

bit[30]:  说明 "All instructions accessing D0-D31 execute normally. ",而寄存器 D0-D31是双精度寄存器。该位写 0。

bit[23:22]: cp11协处理器有关。这两位写 11。

bit[21:20]:  cp10协处理器有关。这两位写 11

(经过百度可以知道,ARMv7-A架构的芯片,CP10、CP11 两个协处理器一起,提供了浮点运算和向量操作,以及高级的 SIMD 指令扩展。)

FPEXC寄存器:("ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf " 文档

bit[30]:  "Enable bit. A global enable for the Advanced SIMD and Floating-point Extensions",可以看出涉及 浮点操作的使能。该位置 1。

main.c文件添加 硬件浮点函数,实现如下:

//使能I.MX6U的硬件浮点支持,即NEON和FPU
void imx6ul_hardfpu_enable(void)
{
    uint32_t cpacr;
	uint32_t fpexc;

    /*使能NEON与FPU */
    cpacr = __get_CPACR();
	cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
		   |  (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
	__set_CPACR(cpacr);

	fpexc = __get_FPEXC();
    fpexc |= 0x40000000UL;
    __set_FPEXC(fpexc);
}

主函数中添加 函数的调用,如下:

int main(void)
{
	unsigned char state = OFF;
    char icm_buffer[20] = {0};

    imx6ul_hardfpu_enable(); //开启硬件浮点支持与NEON

	int_init();       /* 初始化中断(一定要最先调用!) */
	imx6u_clkinit();  /* 初始化系统时钟 			*/
	delay_init();	  /* 初始化延时 			*/
	clk_enable();	  /* 使能所有的时钟 			*/
	led_init();		  /* 初始化led 			*/
	beep_init();      /* 初始化beep	 		*/
	uart_init();      /* 初始化串口,波特率115200 */		
    rtc_init();       /* RTC时钟初始化      */

    while(icm20608_spi_init()) /*SPI从设备ICM20608初始化  */
    {
        printf("---SPI--not check icm20608!!!\r\n");
    }

	while(1)				
	{
        icm20608_get_data();

        decimal_data_handle(icm20608_dev.accel_x_act, icm_buffer);
        printf("acce-x: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.accel_y_act, icm_buffer);
        printf("acce-y: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.accel_z_act, icm_buffer);
        printf("acce-z: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.gyro_x_act, icm_buffer);
        printf("gyro-x: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.gyro_y_act, icm_buffer);
        printf("gyro-y: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.gyro_z_act, icm_buffer);
        printf("gyro-z: %s\r\n", icm_buffer);
        decimal_data_handle(icm20608_dev.temp_act, icm_buffer);
        printf("temperature: %s\r\n\n", icm_buffer);

		state = !state;
		led_switch(LED0, state);
		delayms(500);
	}
	return 0;
}

2.   添加浮点编译选项

Makefile 文件添加 硬件浮点支持。添加项如下:

-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard

-march=:指定目标架构的型号

-mfpu=:来指定浮点协处理的类型

 -mfloat-abi=: 生成的代码采用硬浮点(FPU)调用接口。

Makefile文件在编译 .c 文件时需要添加。如下所示:

$(COBJS) : obj/%.o : %.c

	$(CC) -Wall -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2  $(INCLUDE) -o $@ $<

3.  运行程序

做完以上硬件浮点工作后,即可编译并运行程序。

串口打印的参数值,如下:

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值