当前位置: 首页 > article >正文

Linux-Ubuntu之SPI串行通信陀螺仪和加速度计

Linux-Ubuntu之SPI串口通信陀螺仪和加速度计

  • 一,SPI通信原理
  • 二,ICM-20608六轴传感器控制
  • 三,代码
      • 1.小tip

一,SPI通信原理

SPI:串行全双工通信,最高能达到百MHZ,通常一个主设备跟多个从设备,标准是4线模式,CS片选,SCK串行时钟,MOSI主发从收,MISO从发主收,能实现全双工就是因为有两根单独的数据线。对于I2C通信,I2C只有SCL和SDA时钟和数据线,不同点:①属于半双工,②通信速度上,I2C最高400KHZ,没有SPI快,③在从机设备选择上,SPI有片选信号线,从机拉低该信号线,主机就能和该从机通信,I2C是通过在数据中发送从机的地址,选择从机设备。相同点:①都是串行通信,数据按位传输,②都是主从架构,一个主设备作为控制中心,多个从设备响应并进行数据的传输。
SPISPI通过串行时钟极性(CPOL)和相位(CPHA)的搭配来得到四种工作模式四种工作模式,CPOL为0,空闲的时候时钟线位低电平,为1的时候,空闲为高电平,CPHA,为0第一个上升沿或者下降沿就开始数据的采集,为1第二个上升沿或者下降沿开始数据采集。
在这里插入图片描述工作采用CPOL=0,CPHA=0 ,低电平空闲状态,遇到第一个上升沿,开始数据采集,传输1bit,再遇到下一个上升沿,再传输1bit。
在这里插入图片描述

二,ICM-20608六轴传感器控制

ICM20608整体程序包括三部分:1.对引脚初始化,由于片选信号用的是GPIO1-IO20,对其初始化还包括设置软件的片选,设置为输出模式,在读取数据时,对这个IO进行写0、写1操作实现软件控制片选,当然要先设置硬件片选上与这个IO连接。2.对SPI的初始化,直接调用SPI中的函数即可,并关闭休眠模式。3.这部分是真实对这个传感器的寄存器数据进行读写的函数,调用SPI中的读写函数,并且在该部分带入寄存器的值,即可实现对寄存器数据的读写,并且调用函数将寄存器中的数据,转化为正常能看懂的值。
读取的数据包括加速度、陀螺仪值和芯片温度,程序其实和I2C的类似,先在SPI的函数中,进行对SPI相关寄存器初始化,包括使能,设置写入寄存器后寄存器发送,设置通道,时钟分频以及其他先关寄存器配置,再说明读写函数,这个读写函数比I2C简单,发送时:直接判断寄存器状态是否为空,空了就往RXDATA中写数据,自动就实现数据发送,接收时:判断寄存器状态是否来数据了,来了数据就将RXDATA中的数据读取。

三,代码

/*spi.h*/
#ifndef _DSP_SPI_H
#define _DSP_SPI_H
#include "imx6ul.h"
/*spi的初始化*/
void spi_init(ECSPI_Type *base);
/*SPI发送接收函数*/
unsigned char spi_read_and_write_byte(ECSPI_Type *base,unsigned char txdata);
#endif

/*spi.c*/
#include "dsp_spi.h"

/*spi的初始化*/
void spi_init(ECSPI_Type *base)
{
    base->CONREG = 0;//清0
    base->CONREG |=(1<<0)|(1<<3)|(1<<4)|(7<<20);//使能SPI  设置写入数据后发送数据   通道0  8bit突发

    base->CONFIGREG = 0;
    base->PERIODREG = 0x2000;

    /*SPI时钟分频*/
    base->CONREG &=~((0xf<<12)|(0xf<<8));//清0
    base->CONREG |=(0x9<<12);//设置分频10  60MHZ/10=6MHZ
}
/*SPI发送接收函数*/
unsigned char spi_read_and_write_byte(ECSPI_Type *base,unsigned char txdata)
{
    uint32_t spi_rxdata = 0;
    uint32_t spi_txdata = txdata;

    /*通道0*/
    base->CONREG &=~(3<<18);
    base->CONREG |=(0<<18);

    /*数据发送*/
    while((base->STATREG & (1<<0))==0){};
    base->TXDATA = spi_txdata;

    /*数据接收*/
    while((base->STATREG & (1<<3))==0){};
    spi_rxdata = base->RXDATA;
    return spi_rxdata;
}
/*icm20608.c*/
#include "dsp_icm20608.h"
#include "dsp_spi.h"
#include "dsp_delay.h"
#include "stdio.h"
struct icm20608_dev_struc icm20608_dev;	/* icm20608设备 */
/*icm20608初始化*/
void icm20608_init(void)
{
    // unsigned char vallll;
    // vallll = icm20608_read_reg(ICM20_WHO_AM_I);
    /*1.引脚初始化*/
    IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK,0);//ECSPI3_SCLK		
	IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK,0X10b1);

    IOMUXC_SetPinMux(IOMUXC_UART2_CTS_B_ECSPI3_MOSI,0);	//主输出 从输入	
	IOMUXC_SetPinConfig(IOMUXC_UART2_CTS_B_ECSPI3_MOSI,0X10b1);

    IOMUXC_SetPinMux(IOMUXC_UART2_RTS_B_ECSPI3_MISO,0);	//主输入 从输出	
	IOMUXC_SetPinConfig(IOMUXC_UART2_RTS_B_ECSPI3_MISO,0X10b1);

    IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_GPIO1_IO20,0);	//片选
	IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_GPIO1_IO20,0X10b0);

    gpio_config_t CS_config;
    CS_config.section= gpio_out;
    CS_config.mode=0;
    gpio_init(GPIO1,20,&CS_config);

    /*2.spi初始化*/
    spi_init(ECSPI3);
    icm20608_write_reg(ICM20_PWR_MGMT_1, 0x80);//打开休眠模式
    delay(50);
    icm20608_write_reg(ICM20_PWR_MGMT_1, 0x01);//关闭休眠模式
    delay(50);
    /*3.icm20608内部寄存器设置,即初始化*/
    icm20608_write_reg(ICM20_SMPLRT_DIV,0X00);//输出数率是采样率
    icm20608_write_reg(ICM20_GYRO_CONFIG,0X18);//陀螺仪量程2000
    icm20608_write_reg(ICM20_ACCEL_CONFIG,0X18);//加速度16
    icm20608_write_reg(ICM20_CONFIG,0x04);
 	icm20608_write_reg(ICM20_ACCEL_CONFIG2, 0x04); 	
	icm20608_write_reg(ICM20_PWR_MGMT_2, 0x00); 	
	icm20608_write_reg(ICM20_LP_MODE_CFG, 0x00); 	
	icm20608_write_reg(ICM20_FIFO_EN, 0x00);		   
}

/*进行读寄存器数据*/
unsigned char icm20608_read_reg(unsigned char reg_address)
{
    unsigned char result;
    reg_address |=0x80;//最高为值置1,表示进行读数据
    IMC20608_CSN(0);//片选拉低

    spi_read_and_write_byte(ECSPI3,reg_address);//先写入寄存器地址
    result=spi_read_and_write_byte(ECSPI3,0xff);//进行读操作,后面跟的数据没什么用,读的是RXDATA中第数据

    IMC20608_CSN(1);//片选拉高
    return result;
}

/*进行写寄存器数据*/
void icm20608_write_reg(unsigned char reg_address,unsigned char reg_in_data)
{
    
    reg_address &=~(1<<8);//最高为值置0,表示进行写数据
    IMC20608_CSN(0);//片选拉低

    spi_read_and_write_byte(ECSPI3,reg_address);//先写入寄存器地址
    spi_read_and_write_byte(ECSPI3,reg_in_data);//进行写操作,先写寄存器地址,再写数据

    IMC20608_CSN(1);//片选拉高
}

/*加速度计计算需要的值*/
unsigned short icm20608_accel_scaleget(void)
{
	unsigned char data;
	unsigned short accelscale;
	
	data = (icm20608_read_reg(ICM20_ACCEL_CONFIG) >> 3) & 0X3;
	switch(data) {
		case 0: 
			accelscale = 16384;
			break;
		case 1:
			accelscale = 8192;
			break;
		case 2:
			accelscale = 4096;
			break;
		case 3:
			accelscale = 2048;
			break;
	}
	return accelscale;
}
/*陀螺仪计算需要的值*/
float icm20608_gyro_scaleget(void)
{
	unsigned char data;
	float gyroscale;
	
	data = (icm20608_read_reg(ICM20_GYRO_CONFIG) >> 3) & 0X3;
	switch(data) {
		case 0: 
			gyroscale = 131;
			break;
		case 1:
			gyroscale = 65.5;
			break;
		case 2:
			gyroscale = 32.8;
			break;
		case 3:
			gyroscale = 16.4;
			break;
	}
	return gyroscale;
}

/*读多个寄存器值*/
void icm20608_read_more(unsigned char reg,unsigned char *buf,unsigned char len)
{
    unsigned int i=0;
    reg |=0x80;//设置为读模式
    IMC20608_CSN(0);//使能
    spi_read_and_write_byte(ECSPI3,reg);//先写入寄存器地址  
    for(i=0;i<len;i++)
    {
        buf[i]=spi_read_and_write_byte(ECSPI3,0xff);//??

    }

    IMC20608_CSN(1);//关闭使能
}

/*获取数据*/
void icm20608_get_data(void)
{
    unsigned char data[14];

    icm20608_read_more(ICM20_ACCEL_XOUT_H,data,14);//真神奇,能够一直往地址加一的寄存器读取数据      
    float gyroscale=icm20608_gyro_scaleget();
    unsigned short accescale=icm20608_accel_scaleget();
    icm20608_dev.accel_x_adc=(signed short)((data[0]<<8)|data[1]);
    icm20608_dev.accel_y_adc=(signed short)((data[2]<<8)|data[3]);    
    icm20608_dev.accel_z_adc=(signed short)((data[4]<<8)|data[5]);
    icm20608_dev.temp_adc=(signed short)((data[6]<<8)|data[7]);
    icm20608_dev.gyro_x_adc=(signed short)((data[8]<<8)|data[9]);
    icm20608_dev.gyro_y_adc=(signed short)((data[10]<<8)|data[11]);
    icm20608_dev.gyro_z_adc=(signed short)((data[12]<<8)|data[13]);

    /*转换为实际值*/
	icm20608_dev.gyro_x_act = ((float)(icm20608_dev.gyro_x_adc)  / gyroscale) * 100;
	icm20608_dev.gyro_y_act = ((float)(icm20608_dev.gyro_y_adc)  / gyroscale) * 100;
	icm20608_dev.gyro_z_act = ((float)(icm20608_dev.gyro_z_adc)  / gyroscale) * 100;

	icm20608_dev.accel_x_act = ((float)(icm20608_dev.accel_x_adc) / accescale) * 100;
	icm20608_dev.accel_y_act = ((float)(icm20608_dev.accel_y_adc) / accescale) * 100;
	icm20608_dev.accel_z_act = ((float)(icm20608_dev.accel_z_adc) / accescale) * 100;

	icm20608_dev.temp_act = (((float)(icm20608_dev.temp_adc) - 25 ) / 326.8 + 25) * 100;

}


/*icm20608.h*/
#ifndef _DSP_ICM20608_H
#define _DSP_ICM20608_H
#include "imx6ul.h"
#include "dsp_gpio.h"


#define IMC20608_CSN(n)  (n ? gpio_write(GPIO1,20,1):gpio_write(GPIO1,20,0)) //n濞戞搫鎷�1闁告劧鎷�1 濞戞搫鎷�0闁告劧鎷�0
#define ICM20608G_ID			0XAF	
#define ICM20608D_ID			0XAE	

/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕曢柛婊冭嫰婵偤鏌呴悢宄邦唺闁煎浜濈粊锟�(闁告垼妗ㄦ鍥籍閹偊鍟庣紓鍐惧櫙缁辨繈鎮介妸銈囪壘濞戞挸娴烽弫銈夊箣妞嬪孩鐣遍柤濂変簼椤ュ懏娼忛幘鍐叉瘔闁稿﹤鍚嬮惁顔芥綇閸愯法绀� */
#define	ICM20_SELF_TEST_X_GYRO		0x00
#define	ICM20_SELF_TEST_Y_GYRO		0x01
#define	ICM20_SELF_TEST_Z_GYRO		0x02
#define	ICM20_SELF_TEST_X_ACCEL		0x0D
#define	ICM20_SELF_TEST_Y_ACCEL		0x0E
#define	ICM20_SELF_TEST_Z_ACCEL		0x0F

/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕曢梻鍫熺懕閹风兘鏁撻挊澶夌剨缂佸鎷�1闁跨噦鎷�7 */
#define	ICM20_XG_OFFS_USRH			0x13
#define	ICM20_XG_OFFS_USRL			0x14
#define	ICM20_YG_OFFS_USRH			0x15
#define	ICM20_YG_OFFS_USRL			0x16
#define	ICM20_ZG_OFFS_USRH			0x17
#define	ICM20_ZG_OFFS_USRL			0x18

#define	ICM20_SMPLRT_DIV			0x19
#define	ICM20_CONFIG				0x1A
#define	ICM20_GYRO_CONFIG			0x1B
#define	ICM20_ACCEL_CONFIG			0x1C
#define	ICM20_ACCEL_CONFIG2			0x1D
#define	ICM20_LP_MODE_CFG			0x1E
#define	ICM20_ACCEL_WOM_THR			0x1F
#define	ICM20_FIFO_EN				0x23
#define	ICM20_FSYNC_INT				0x36
#define	ICM20_INT_PIN_CFG			0x37
#define	ICM20_INT_ENABLE			0x38
#define	ICM20_INT_STATUS			0x3A

/* 闁告梻濯撮幏鐑芥晸閽樺顔婇弶鍫熸尭閸わ拷 */
#define	ICM20_ACCEL_XOUT_H			0x3B
#define	ICM20_ACCEL_XOUT_L			0x3C
#define	ICM20_ACCEL_YOUT_H			0x3D
#define	ICM20_ACCEL_YOUT_L			0x3E
#define	ICM20_ACCEL_ZOUT_H			0x3F
#define	ICM20_ACCEL_ZOUT_L			0x40

/* 婵炴挴鏅涚€硅櫕娼忛幘鍐叉瘔 */
#define	ICM20_TEMP_OUT_H			0x41
#define	ICM20_TEMP_OUT_L			0x42

/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕曢弶鍫熸尭閸わ拷 */
#define	ICM20_GYRO_XOUT_H			0x43
#define	ICM20_GYRO_XOUT_L			0x44
#define	ICM20_GYRO_YOUT_H			0x45
#define	ICM20_GYRO_YOUT_L			0x46
#define	ICM20_GYRO_ZOUT_H			0x47
#define	ICM20_GYRO_ZOUT_L			0x48
#define	ICM20_SIGNAL_PATH_RESET		0x68
#define	ICM20_ACCEL_INTEL_CTRL 		0x69
#define	ICM20_USER_CTRL				0x6A
#define	ICM20_PWR_MGMT_1			0x6B
#define	ICM20_PWR_MGMT_2			0x6C
#define	ICM20_FIFO_COUNTH			0x72
#define	ICM20_FIFO_COUNTL			0x73
#define	ICM20_FIFO_R_W				0x74
#define	ICM20_WHO_AM_I 				0x75
#define	ICM20_XA_OFFSET_H			0x77
#define	ICM20_XA_OFFSET_L			0x78
#define	ICM20_YA_OFFSET_H			0x7A
#define	ICM20_YA_OFFSET_L			0x7B
#define	ICM20_ZA_OFFSET_H			0x7D
#define	ICM20_ZA_OFFSET_L 			0x7E

/*
 * ICM20608缂備焦鎸婚悗顖涙媴閿燂拷1闁跨噦鎷�7
 */
struct icm20608_dev_struc
{
	signed int gyro_x_adc;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昘閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int gyro_y_adc;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昚閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int gyro_z_adc;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昛閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_x_adc;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憮閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_y_adc;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憰閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_z_adc;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憱閺夌偞娼欑敮顐f叏鐎h埖瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int temp_adc;		/* 婵炴挴鏅涚€规娊宕㈤悢濂夋綏闁稿⿵鎷�1闁跨噦鎷�7 				*/

	/* 濞戞挸顑夊浼村及椤栨繍鍚€缂佺姵顨呯欢閬嶅礆閹殿喗鐣遍悗鍦仱濡绢垶宕愮涵椋庣闁圭鏅涢妵锟�100闁稿⿵鎷�1闁跨噦鎷�7 */
	signed int gyro_x_act;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昘閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int gyro_y_act;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昚閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int gyro_z_act;		/* 闂傚嫷婢侀幏鐑芥懚鏉炴澘宕昛閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_x_act;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憮閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_y_act;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憰閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int accel_z_act;		/* 闁告梻濯撮幏鐑芥晸閽樺顔婇悹渚囨憱閺夌偞娼欓悿鍕⒔閸滃啯瀚归柨鐕傛嫹1闁跨噦鎷�7 			*/
	signed int temp_act;		/* 婵炴挴鏅涚€瑰磭鈧湱鍋ゅ顖炲磹閿燂拷1闁跨噦鎷�7 				*/
};
extern struct icm20608_dev_struc icm20608_dev;	/* icm20608閻犱焦鍎抽ˇ锟� */


void icm20608_init(void);
unsigned char icm20608_read_reg(unsigned char reg_address);/*閺夆晜绋栭、鎴犳嫚鐠囪尙妲戦悗娑櫭▍鎺楀极閻楀牆绁�*/
void icm20608_write_reg(unsigned char reg_address,unsigned char reg_in_data);/*閺夆晜绋栭、鎴﹀礃濞嗗繒妲戦悗娑櫭▍鎺楀极閻楀牆绁�*/
void icm20608_read_more(unsigned char reg,unsigned char *buf,unsigned char len);//閻犲洩顕чˇ鎸庣▔椤忓嫮妲戦悗娑櫭▍鎺楀磹閿燂拷
/*闂勨偓閾昏桨鍗庣拋锛勭暬闂団偓鐟曚胶娈戦崐锟�*/
float icm20608_gyro_scaleget(void);
/*閸旂娀鈧喎瀹崇拋陇顓哥粻妤呮付鐟曚胶娈戦崐锟�*/
unsigned short icm20608_accel_scaleget(void);
void icm20608_get_data(void);


#endif

主函数:

#include "main.h"

#include "dsp_clk.h"

#include "dsp_led.h"

#include "dsp_delay.h"

#include "beep.h"

#include "dsp_key.h"

#include "dsp_int.h"

#include "dsp_exti.h"

#include "dsp_epit.h"

#include "dsp_uart.h"

#include "stdio.h"

#include "dsp_lcd.h"

#include "dsp_lcdapi.h"

#include "dsp_rtc.h"

#include "dsp_i2c.h"

#include "dsp_ap3216c.h"

#include "dsp_spi.h"

#include "dsp_icm20608.h"

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);

}

void integer_display(unsigned short x, unsigned short y, unsigned char size, signed int num)//重新构建显示函数

{

	char buf[200];

	

	lcd_fill(x, y, x + 50, y + size, tftlcd_dev.backcolor);

	

	memset(buf, 0, sizeof(buf));

	if(num < 0)

		sprintf(buf, "-%d", -num);

	else 

		sprintf(buf, "%d", num);

	lcd_show_string(x, y, 50, size, size, buf); 

}

void decimals_display(unsigned short x, unsigned short y, unsigned char size, signed int num)//将整数结果转化为真实的数据

{

	signed int integ; 	/* 整数部分 */

	signed int fract;	/* 小数部分 */

	signed int uncomptemp = num; 

	char buf[200];



	if(num < 0)

		uncomptemp = -uncomptemp;

	integ = uncomptemp / 100;

	fract = uncomptemp % 100;



	memset(buf, 0, sizeof(buf));

	if(num < 0)

		sprintf(buf, "-%d.%d", integ, fract);

	else 

		sprintf(buf, "%d.%d", integ, fract);

	lcd_fill(x, y, x + 60, y + size, tftlcd_dev.backcolor);

	lcd_show_string(x, y, 60, size, size, buf); 

}

int main(void)

{

    // int b=0;

    // unsigned short ir,ps,als;

     unsigned char kkkk=0;

    // struct rtc_datetime rtc_now_time;

    // char buf[160]={};

    imx6ul_hardfpu_enable();//打开浮点运算

    int_init();//中断初始化

    imx6u_clkinit();//时钟初始化

    key_init();//按键初始化

    clk_enable();//时钟初始化

    uart_init();//串口初始化

    beep_init();//凤鸣器初始化

    led_init();//led初始化

    lcd_init();//LCD读ID号

    rtc_init();//RTC初始化

    ap3216c_init();//传感器初始化

    icm20608_init();//加速度计 陀螺仪等传感器初始化

    tftlcd_dev.forecolor = LCD_RED;

    tftlcd_dev.backcolor = LCD_WHITE;

    // unsigned char *b,*c,*f;

    // unsigned short *a;

   // lcd_show_string(10,40,260,32,32,(char *)"Fucking high");

    

	lcd_show_string(50, 130, 200, 16, 16, (char*)"accel x:");  

	lcd_show_string(50, 150, 200, 16, 16, (char*)"accel y:");  

	lcd_show_string(50, 170, 200, 16, 16, (char*)"accel z:");  

	lcd_show_string(50, 190, 200, 16, 16, (char*)"gyro  x:"); 

	lcd_show_string(50, 210, 200, 16, 16, (char*)"gyro  y:"); 

	lcd_show_string(50, 230, 200, 16, 16, (char*)"gyro  z:"); 

	lcd_show_string(50, 250, 200, 16, 16, (char*)"temp   :"); 



	lcd_show_string(50 + 181, 130, 200, 16, 16, (char*)"g");  

	lcd_show_string(50 + 181, 150, 200, 16, 16, (char*)"g");  

	lcd_show_string(50 + 181, 170, 200, 16, 16, (char*)"g");  

	lcd_show_string(50 + 181, 190, 200, 16, 16, (char*)"o/s"); 

	lcd_show_string(50 + 181, 210, 200, 16, 16, (char*)"o/s"); 

	lcd_show_string(50 + 181, 230, 200, 16, 16, (char*)"o/s"); 

	lcd_show_string(50 + 181, 250, 200, 16, 16, (char*)"C");

    while(1)

    {

        icm20608_get_data();

		integer_display(50 + 70, 130, 16, icm20608_dev.accel_x_adc);

		integer_display(50 + 70, 150, 16, icm20608_dev.accel_y_adc);

		integer_display(50 + 70, 170, 16, icm20608_dev.accel_z_adc);

		integer_display(50 + 70, 190, 16, icm20608_dev.gyro_x_adc);

		integer_display(50 + 70, 210, 16, icm20608_dev.gyro_y_adc);

		integer_display(50 + 70, 230, 16, icm20608_dev.gyro_z_adc);

		integer_display(50 + 70, 250, 16, icm20608_dev.temp_adc);



		decimals_display(50 + 70 + 50, 130, 16, icm20608_dev.accel_x_act);

		decimals_display(50 + 70 + 50, 150, 16, icm20608_dev.accel_y_act);

		decimals_display(50 + 70 + 50, 170, 16, icm20608_dev.accel_z_act);

		decimals_display(50 + 70 + 50, 190, 16, icm20608_dev.gyro_x_act);

		decimals_display(50 + 70 + 50, 210, 16, icm20608_dev.gyro_y_act);

		decimals_display(50 + 70 + 50, 230, 16, icm20608_dev.gyro_z_act);

		decimals_display(50 + 70 + 50, 250, 16, icm20608_dev.temp_act);





        // unsigned char vallll;

        // vallll = icm20608_read_reg(ICM20_WHO_AM_I);

        // printf("ID:%x\r\n",vallll);

        // ap3216c_redata(&ir,&ps,&als);

		// lcd_shownum(200, 160, ir, 5, 32);	

        // lcd_shownum(200, 200, ps, 5, 32);	

        // lcd_shownum(200, 240, als, 5, 32);	 

        // printf("ir = %d    ps = %d  als = %d  \r\n",ir,ps,als);

        // tftlcd_dev.forecolor = LCD_RED;

        // rtc_out_register(&rtc_now_time);

        // sprintf(buf,"%d.%d.%d-%d:%d:%d\r\n",rtc_now_time.year,rtc_now_time.month,

        //         rtc_now_time.day,rtc_now_time.hour,rtc_now_time.minute,rtc_now_time.second);

        // lcd_show_string(70,70,240,32,32,(char *)buf);

        led_mode(kkkk);

        delay(1000);

        kkkk = !kkkk;     

    }

    return 0;    

}

实现:
在这里插入图片描述

1.小tip

①#define IMC20608_CSN(n) (n ? gpio_write(GPIO1,20,1):gpio_write(GPIO1,20,0))
(n ? gpio_write(GPIO1,20,1):gpio_write(GPIO1,20,0))是3目运算,条件? 表达式1 : 表达式2,条件为真,执行表达式1,否则执行表达式2。因此当n=1,IMC20608_CSN(1)就相当于执行了 gpio_write(GPIO1,20,1),后面同理,利用宏定义来这样实现片选,很新颖。
②`

/*读多个寄存器值*/
void icm20608_read_more(unsigned char reg,unsigned char *buf,unsigned char len)
{
    unsigned int i=0;
    reg |=0x80;//设置为读模式
    IMC20608_CSN(0);//使能
    spi_read_and_write_byte(ECSPI3,reg);//先写入寄存器地址  
    for(i=0;i<len;i++)
    {
        buf[i]=spi_read_and_write_byte(ECSPI3,0xff);//??

    }
    IMC20608_CSN(1);//关闭使能
}

在 for 循环中,通过不断调用 spi_read_and_write_byte(ECSPI3, 0xff) 来连续读取数据。在 SPI 通信中,主设备发送什么数据并不影响从设备返回数据的过程,这里发送 0xff 通常是一种占位操作,目的是触发从设备在每个时钟周期返回数据。每调用一次该函数,从设备就会根据当前内部寄存器地址指针的位置返回一个字节的数据,同时地址指针自动指向下一个寄存器地址(这是由从设备内部的硬件机制实现的)。通过循环多次调用,就可以连续读取多个寄存器的值,并将它们存储到 buf 数组中。


http://www.kler.cn/a/471170.html

相关文章:

  • 『SQLite』常见日期时间函数的使用
  • 30天开发操作系统 第 12 天 -- 定时器
  • Android存储方案对比(SharedPreferences 、 MMKV 、 DataStore)
  • 学习threejs,导入assimp assimp2json格式的模型
  • C# 修改项目类型 应用程序程序改类库
  • 067B-基于R语言平台Biomod2模型的物种分布建模与数据可视化-高阶课程【2025】
  • Java Web开发进阶——Spring Boot与Spring Data JPA
  • 【2025最新】网络安全攻防实战:护网行动经验与策略解析
  • 120.Jenkins里的Pipeline Script
  • 【Linux网络编程】第二十一弹---深入解析I/O多路转接技术之poll函数:优势、缺陷与实战代码
  • git①111
  • HDFS架构原理
  • TextMeshPro保存偏移数据
  • React18实现账单管理项目(三):日期分组与图标适配
  • 请求是如何通过k8s service 路由到对应的pod
  • Express 加 sqlite3 写一个简单博客
  • Oracle SQL子查询实例
  • UE4_用户控件_4_Widgets嵌套Widgets构建复杂系统
  • VLMs之Agent之CogAgent:CogAgent的简介、安装和使用方法、案例应用之详细攻略
  • Yolov8训练方式以及C#中读取yolov8+onnx模型进行目标检测.NET 6.0
  • 分布式与集群
  • 基于SpringBoot+Vue的考研百科网站
  • UG NX二次开发(C++)-UFun函数-按照特定方向提取轮廓线
  • el-table拖拽表格
  • 吉客云与金蝶云星空数据集成技术详解
  • 20250107在WIN10下使用无线ADB连接Andorid7.1.2