1. 程式人生 > 其它 >演算法_藍橋杯_Leetcode_C++_118. 楊輝三角_歷屆真題 楊輝三角形【第十二屆】【省賽】【C組】

演算法_藍橋杯_Leetcode_C++_118. 楊輝三角_歷屆真題 楊輝三角形【第十二屆】【省賽】【C組】

spi控制陀螺儀
spi.h

#ifndef _BSP_SPI_H
#define _BSP_SPI_H
#include "imx6ul.h"

/* 函式宣告 */
void spi_init(ECSPI_Type *base);
unsigned char spich0_readwrite_byte(ECSPI_Type *base, unsigned char txdata);

#endif


spi.c

#include "bsp_spi.h"
#include "bsp_gpio.h"
#include "stdio.h"

/*
 * @description		: 初始化SPI
 * @param - base	: 要初始化的SPI
 * @return 			: 無
 */
void spi_init(ECSPI_Type *base)
{
	/* 配置CONREG暫存器
	 * bit0 : 		1 	使能ECSPI
	 * bit3 : 		1	當向TXFIFO寫入資料以後立即開啟SPI突發。
	 * bit[7:4] : 	0001 SPI通道0主模式,根據實際情況選擇,
	 *            	   	開發板上的ICM-20608接在SS0上,所以設定通道0為主模式
	 * bit[19:18]:	00 	選中通道0(其實不需要,因為片選訊號我們我們自己控制)
	 * bit[31:20]:	0x7	突發長度為8個bit。 
	 */
	base->CONREG = 0; /* 先清除控制暫存器 */
	base->CONREG |= (1 << 0) | (1 << 3) | (1 << 4) | (7 << 20); /* 配置CONREG暫存器 */

	/*
     * ECSPI通道0設定,即設定CONFIGREG暫存器
     * bit0:	0 通道0 PHA為0
     * bit4:	0 通道0 SCLK高電平有效
     * bit8: 	0 通道0片選訊號 當SMC為1的時候此位無效
     * bit12:	0 通道0 POL為0
     * bit16:	0 通道0 資料線空閒時高電平
     * bit20:	0 通道0 時鐘線空閒時低電平
	 */
	base->CONFIGREG = 0; 		/* 設定通道暫存器 */
	
	/*  
     * ECSPI通道0設定,設定取樣週期
     * bit[14:0] :	0X2000  取樣等待週期,比如當SPI時鐘為10MHz的時候
     *  		    0X2000就等於1/10000 * 0X2000 = 0.8192ms,也就是連續
     *          	讀取資料的時候每次之間間隔0.8ms
     * bit15	 :  0  取樣時鐘源為SPI CLK
     * bit[21:16]:  0  片選延時,可設定為0~63
	 */
	base->PERIODREG = 0X2000;		/* 設定取樣週期暫存器 */

	/*
     * ECSPI的SPI時鐘配置,SPI的時鐘源來源於pll3_sw_clk/8=480/8=60MHz
     * 通過設定CONREG暫存器的PER_DIVIDER(bit[11:8])和POST_DIVEDER(bit[15:12])來
     * 對SPI時鐘源分頻,獲取到我們想要的SPI時鐘:
     * SPI CLK = (SourceCLK / PER_DIVIDER) / (2^POST_DIVEDER)
     * 比如我們現在要設定SPI時鐘為6MHz,那麼PER_DIVEIDER和POST_DEIVIDER設定如下:
     * PER_DIVIDER = 0X9。
     * POST_DIVIDER = 0X0。
     * SPI CLK = 60000000/(0X9 + 1) = 60000000=6MHz
	 */
	base->CONREG &= ~((0XF << 12) | (0XF << 8));	/* 清除PER_DIVDER和POST_DIVEDER以前的設定 */
	base->CONREG |= (0X9 << 12);					/* 設定SPI CLK = 6MHz */
}

/*
 * @description		: SPI通道0傳送/接收一個位元組的資料
 * @param - base	: 要使用的SPI
 * @param - txdata	: 要傳送的資料
 * @return 			: 無
 */
unsigned char spich0_readwrite_byte(ECSPI_Type *base, unsigned char txdata)
{ 
	uint32_t  spirxdata = 0;
	uint32_t  spitxdata = txdata;

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

  	while((base->STATREG & (1 << 0)) == 0){} /* 等待發送FIFO為空 */
		base->TXDATA = spitxdata;
	
	while((base->STATREG & (1 << 3)) == 0){} /* 等待接收FIFO有資料 */
		spirxdata = base->RXDATA;
	return spirxdata;
}


icm20608.h

#ifndef _BSP_ICM20608_H
#define _BSP_ICM20608_H
#include "imx6ul.h"
#include "bsp_gpio.h"


/* 巨集定義 */
#define ICM20608_CSN(n)    (n ? gpio_pinwrite(GPIO1, 20, 1) : gpio_pinwrite(GPIO1, 20, 0))   /* SPI片選訊號	 */

#define ICM20608G_ID			0XAF	/* ID值 */
#define ICM20608D_ID			0XAE	/* ID值 */

/* ICM20608暫存器 
 *復位後所有暫存器地址都為0,除了
 *Register 107(0X6B) Power Management 1 	= 0x40
 *Register 117(0X75) WHO_AM_I 				= 0xAF或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

/* 陀螺儀靜態偏移 */
#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結構體
 */
struct icm20608_dev_struc
{
	signed int gyro_x_adc;		/* 陀螺儀X軸原始值 			*/
	signed int gyro_y_adc;		/* 陀螺儀Y軸原始值 			*/
	signed int gyro_z_adc;		/* 陀螺儀Z軸原始值 			*/
	signed int accel_x_adc;		/* 加速度計X軸原始值 			*/
	signed int accel_y_adc;		/* 加速度計Y軸原始值 			*/
	signed int accel_z_adc;		/* 加速度計Z軸原始值 			*/
	signed int temp_adc;		/* 溫度原始值 				*/

	/* 下面是計算得到的實際值,擴大100倍 */
	signed int gyro_x_act;		/* 陀螺儀X軸實際值 			*/
	signed int gyro_y_act;		/* 陀螺儀Y軸實際值 			*/
	signed int gyro_z_act;		/* 陀螺儀Z軸實際值 			*/
	signed int accel_x_act;		/* 加速度計X軸實際值 			*/
	signed int accel_y_act;		/* 加速度計Y軸實際值 			*/
	signed int accel_z_act;		/* 加速度計Z軸實際值 			*/
	signed int temp_act;		/* 溫度實際值 				*/
};

struct icm20608_dev_struc icm20608_dev;	/* icm20608裝置 */


/* 函式宣告 */
unsigned char icm20608_init(void);
void icm20608_write_reg(unsigned char reg, unsigned char value);
unsigned char icm20608_read_reg(unsigned char reg);
void icm20608_read_len(unsigned char reg, unsigned char *buf, unsigned char len);
void icm20608_getdata(void);


#endif

icm20608.c

#include "bsp_icm20608.h"
#include "bsp_delay.h"
#include "bsp_spi.h"
#include "stdio.h"

struct icm20608_dev_struc icm20608_dev;	/* icm20608裝置 */

/*
 * @description	: 初始化ICM20608
 * @param		: 無
 * @return 		: 0 初始化成功,其他值 初始化失敗
 */
unsigned char icm20608_init(void)
{	
	unsigned char regvalue;
	gpio_pin_config_t cs_config;

	/* 1、ESPI3 IO初始化 
 	 * ECSPI3_SCLK 	-> UART2_RXD
 	 * ECSPI3_MISO 	-> UART2_RTS
 	 * ECSPI3_MOSI	-> UART2_CTS
 	 */
	IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0);
	IOMUXC_SetPinMux(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0);
	IOMUXC_SetPinMux(IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0);
	
	/* 配置SPI   SCLK MISO MOSI IO屬性	
	 *bit 16: 0 HYS關閉
	 *bit [15:14]: 00 預設100K下拉
	 *bit [13]: 0 keeper功能
	 *bit [12]: 1 pull/keeper使能 
	 *bit [11]: 0 關閉開路輸出
 	 *bit [7:6]: 10 速度100Mhz
 	 *bit [5:3]: 110 驅動能力為R0/6
	 *bit [0]: 1 高轉換率
 	 */
	IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0x10B1);
	IOMUXC_SetPinConfig(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0x10B1);
	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);
	cs_config.direction = kGPIO_DigitalOutput;
	cs_config.outputLogic = 0;
	gpio_init(GPIO1, 20, &cs_config);
	
	/* 2、初始化SPI */
	spi_init(ECSPI3);	

	icm20608_write_reg(ICM20_PWR_MGMT_1, 0x80);		/* 復位,復位後為0x40,睡眠模式 			*/
	delayms(50);
	icm20608_write_reg(ICM20_PWR_MGMT_1, 0x01);		/* 關閉睡眠,自動選擇時鐘 					*/
	delayms(50);

	regvalue = icm20608_read_reg(ICM20_WHO_AM_I);
	printf("icm20608 id = %#X\r\n", regvalue);
	if(regvalue != ICM20608G_ID && regvalue != ICM20608D_ID)
		return 1;
		
	icm20608_write_reg(ICM20_SMPLRT_DIV, 0x00); 	/* 輸出速率是內部取樣率					*/
	icm20608_write_reg(ICM20_GYRO_CONFIG, 0x18); 	/* 陀螺儀±2000dps量程 				*/
	icm20608_write_reg(ICM20_ACCEL_CONFIG, 0x18); 	/* 加速度計±16G量程 					*/
	icm20608_write_reg(ICM20_CONFIG, 0x04); 		/* 陀螺儀低通濾波BW=20Hz 				*/
	icm20608_write_reg(ICM20_ACCEL_CONFIG2, 0x04); 	/* 加速度計低通濾波BW=21.2Hz 			*/
	icm20608_write_reg(ICM20_PWR_MGMT_2, 0x00); 	/* 開啟加速度計和陀螺儀所有軸 				*/
	icm20608_write_reg(ICM20_LP_MODE_CFG, 0x00); 	/* 關閉低功耗 						*/
	icm20608_write_reg(ICM20_FIFO_EN, 0x00);		/* 關閉FIFO						*/
	return 0;
}

	
/*
 * @description  : 寫ICM20608指定暫存器
 * @param - reg  : 要讀取的暫存器地址
 * @param - value: 要寫入的值
 * @return		 : 無
 */
void icm20608_write_reg(unsigned char reg, unsigned char value)
{
	/* ICM20608在使用SPI介面的時候暫存器地址
	 * 只有低7位有效,暫存器地址最高位是讀/寫標誌位
	 * 讀的時候要為1,寫的時候要為0。
	 */
	reg &= ~0X80;	
	
	ICM20608_CSN(0);						/* 使能SPI傳輸			*/
	spich0_readwrite_byte(ECSPI3, reg); 	/* 傳送暫存器地址		*/ 
	spich0_readwrite_byte(ECSPI3, value);	/* 傳送要寫入的值			*/
	ICM20608_CSN(1);						/* 禁止SPI傳輸			*/
}	

/*
 * @description	: 讀取ICM20608暫存器值
 * @param - reg	: 要讀取的暫存器地址
 * @return 		: 讀取到的暫存器值
 */
unsigned char icm20608_read_reg(unsigned char reg)
{
	unsigned char reg_val;	   	

	/* ICM20608在使用SPI介面的時候暫存器地址
	 * 只有低7位有效,暫存器地址最高位是讀/寫標誌位
	 * 讀的時候要為1,寫的時候要為0。
	 */
	reg |= 0x80; 	
	
   	ICM20608_CSN(0);               					/* 使能SPI傳輸	 		*/
  	spich0_readwrite_byte(ECSPI3, reg);     		/* 傳送暫存器地址  		*/ 
  	reg_val = spich0_readwrite_byte(ECSPI3, 0XFF);	/* 讀取暫存器的值 			*/
 	ICM20608_CSN(1);                				/* 禁止SPI傳輸 			*/
  	return(reg_val);               	 				/* 返回讀取到的暫存器值 */
}

/*
 * @description	: 讀取ICM20608連續多個暫存器
 * @param - reg	: 要讀取的暫存器地址
 * @return 		: 讀取到的暫存器值
 */
void icm20608_read_len(unsigned char reg, unsigned char *buf, unsigned char len)
{  
	unsigned char i;
	
	/* ICM20608在使用SPI介面的時候暫存器地址,只有低7位有效,
	 * 暫存器地址最高位是讀/寫標誌位讀的時候要為1,寫的時候要為0。
	 */
	reg |= 0x80; 
		
   	ICM20608_CSN(0);               				/* 使能SPI傳輸	 		*/
  	spich0_readwrite_byte(ECSPI3, reg);			/* 傳送暫存器地址  		*/   	   
 	for(i = 0; i < len; i++)					/* 順序讀取暫存器的值 			*/
 	{
		buf[i] = spich0_readwrite_byte(ECSPI3, 0XFF);	
	}
 	ICM20608_CSN(1);                			/* 禁止SPI傳輸 			*/
}

/*
 * @description : 獲取陀螺儀的解析度
 * @param		: 無
 * @return		: 獲取到的解析度
 */
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;
}

/*
 * @description : 獲取加速度計的解析度
 * @param		: 無
 * @return		: 獲取到的解析度
 */
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;
}


/*
 * @description : 讀取ICM20608的加速度、陀螺儀和溫度原始值
 * @param 		: 無
 * @return		: 無
 */
void icm20608_getdata(void)
{
	float gyroscale;
	unsigned short accescale;
	unsigned char data[14];
	
	icm20608_read_len(ICM20_ACCEL_XOUT_H, data, 14);
	
	gyroscale = icm20608_gyro_scaleget();
	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;
}

main.c

#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_uart.h"
#include "stdio.h"
#include "bsp_lcd.h"
#include "bsp_lcdapi.h"
#include "bsp_icm20608.h"
#include "bsp_spi.h"

/*
 * @description	: 指定的位置顯示整數資料
 * @param - x	: X軸位置
 * @param - y 	: Y軸位置
 * @param - size: 字型大小
 * @param - num : 要顯示的資料
 * @return 		: 無
 */
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); 
}

/*
 * @description	: 指定的位置顯示小數資料,比如5123,顯示為51.23
 * @param - x	: X軸位置
 * @param - y 	: Y軸位置
 * @param - size: 字型大小
 * @param - num : 要顯示的資料,實際小數擴大100倍,
 * @return 		: 無
 */
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); 
}

/*
 * @description	: 使能I.MX6U的硬體NEON和FPU
 * @param 		: 無
 * @return 		: 無
 */

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

/*
 * @description	: main函式
 * @param 		: 無
 * @return 		: 無
 */
int main(void)
{
	unsigned char state = OFF;

	imx6ul_hardfpu_enable();	/* 使能I.MX6U的硬體浮點 			*/
	int_init(); 				/* 初始化中斷(一定要最先呼叫!) */
	clk_init();					/* 初始化系統時鐘 			*/
	delay_init();				/* 初始化延時 			*/
	clk_enable();				/* 使能所有的時鐘 			*/
	led_init();					/* 初始化led 			*/
	beep_init();				/* 初始化beep	 		*/
	uart_init();				/* 初始化串列埠,波特率115200 */
	lcd_init();					/* 初始化LCD 			*/
	rtc_init();					/* rtc初始化 */

	tftlcd_dev.forecolor = LCD_RED;
	lcd_show_string(50, 10, 400, 24, 24, (char*)"IMX6U-ZERO SPI TEST");  
	lcd_show_string(50, 40, 200, 16, 16, (char*)"ICM20608 TEST");  
	lcd_show_string(50, 60, 200, 16, 16, (char*)"ATOM@ALIENTEK");  
	lcd_show_string(50, 80, 200, 16, 16, (char*)"2019/3/27");  
	
	while(icm20608_init())		/* 初始化ICM20608	 			*/
	{
		lcd_show_string(50, 100, 200, 16, 16, (char*)"ICM20608 Check Failed!");
		delayms(500);
		lcd_show_string(50, 100, 200, 16, 16, (char*)"Please Check!        ");
		delayms(500);
	}	

	lcd_show_string(50, 100, 200, 16, 16, (char*)"ICM20608 Ready");
	
	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");
	
	tftlcd_dev.forecolor = LCD_BLUE;

	while(1)					
	{		
		icm20608_getdata();
		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);

#if 0		
		printf("accel x = %d\r\n",icm20608_dev.accel_x_adc);
		printf("accel y = %d\r\n",icm20608_dev.accel_y_adc);
		printf("accel z = %d\r\n",icm20608_dev.accel_z_adc);
		printf("gyrp  x = %d\r\n",icm20608_dev.gyro_x_adc);
		printf("gyro  y = %d\r\n",icm20608_dev.gyro_y_adc);
		printf("gyro  z = %d\r\n",icm20608_dev.gyro_z_adc);
		printf("temp    = %d\r\n",icm20608_dev.temp_adc);
#endif
		delayms(120);
		state = !state;
		led_switch(LED0,state);	
	}
	return 0;
}

Makefile

# ?= 沒有賦值的話就賦值
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET 		  ?= bsp

# :=覆蓋之前的值
GCC    			 := $(CROSS_COMPILE)gcc 
LD 				 := $(CROSS_COMPILE)ld
OBJCOPY 		 := $(CROSS_COMPILE)objcopy
OBJDUMP  		 := $(CROSS_COMPILE)objdump 

LIBPATH			 := -lgcc -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4

# INCDIRS 包含整個工程的.h 標頭檔案目錄 \是換行符
INCDIRS          := imx6ull \
					bsp/clk \
					bsp/gpio \
					bsp/led \
					bsp/delay \
					bsp/beep \
					bsp/key \
					bsp/int \
					bsp/exit \
					bsp/epittimer \
					bsp/keyfilter \
					bsp/uart \
					stdio/include \
					bsp/lcd \
					bsp/rtc \
					bsp/i2c \
					bsp/ap3216c \
					bsp/mpu9520 \
					bsp/spi \
					bsp/icm20608

# SRCDIRS 包含整個工程的.s .c檔案目錄
SRCDIRS			 := project \
					bsp/clk \
					bsp/gpio \
					bsp/led \
					bsp/delay \
					bsp/beep \
					bsp/key \
					bsp/int \
					bsp/exit \
					bsp/epittimer \
					bsp/keyfilter \
					bsp/uart \
					stdio/lib \
					bsp/lcd \
					bsp/rtc \
					bsp/i2c \
					bsp/ap3216c \
					bsp/mpu9520 \
					bsp/spi \
					bsp/icm20608

# patsubst的作用是給INCDIRS中的每個目錄前面加一個 -I,指明標頭檔案目錄時必須加
# -I imx6ull -I bsp/clk -I bsp/led -I bsp/delay 
INCLUDE 		 := $(patsubst %, -I %, $(INCDIRS))

# foreach dir對每個dir都執行一次,SRCDIRS中dir, 即上面的資料夾
# wildcard 取出資料夾內所有檔案
# 比如bsp/clk/bsp_clk.c
SFILES 			 := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES 			 := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

# notdir 上面取出來之後去掉目錄
SFILENDIR 		 := $(notdir $(SFILES))
CFILENDIR  		 := $(notdir $(CFILES))

# 把所有的.s和.c都變成點o檔案,並在前面加上obj
SOBJS  			 := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS 			 := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS 			 := $(SOBJS) $(COBJS)

# 相當於重新命名
VPATH 			 := $(SRCDIRS)

.PHONY: clean

# 這段和以前是一樣的
$(TARGET).bin : $(OBJS)
	$(LD) -Timx6ul.lds -o $(TARGET).elf $^ $(LIBPATH)
	$(OBJCOPY) -O binary -S $(TARGET).elf $@
	$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis

# -Wall 編譯後顯示所有警告
# -nostdlib 不連線系統標準啟動檔案和標準庫檔案,只把指定的檔案傳遞給聯結器。
#			這個選項常用於編譯核心、bootloader等程式,它們不需要啟動檔案、標準庫檔案
# -O2   是比O1更高階的選項,進行更多的優化。
# 		Gcc將執行幾乎所有的不包含時間和空間折中的優化。
# 		當設定O2選項時,編譯器並不進行迴圈開啟()loop unrolling以及函式內聯。
# 		與O1比較而言,O2優化增加了編譯時間的基礎上,提高了生成程式碼的執行效率。
# 這樣還能帶著.h檔案一起編譯 
$(SOBJS) : obj/%.o : %.S
	$(GCC) -Wall -Wa,-mimplicit-it=thumb -fno-builtin -nostdlib -c -O2 $(INCLUDE) -o $@ $<
$(COBJS) : obj/%.o : %.c
	$(GCC) -Wall -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
# 行加入了“-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard”指令,這些指令用於
# 指定編譯浮點運算的時候使用硬體 FPU。因為本章使用到了浮點運算,而 I.MX6U 是支援硬體
# FPU 的,雖然我們在 main 函式中已經打開了 NEON 和 FPU,但是在編譯相應 C 檔案的時候也
# 要指定使用硬體 FPU 來編譯浮點運算。

clean:
	rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)


主要是給自己看的,所以肯定會出現很多錯誤哈哈哈哈哈