演算法_藍橋杯_Leetcode_C++_118. 楊輝三角_歷屆真題 楊輝三角形【第十二屆】【省賽】【C組】
阿新 • • 發佈:2021-11-24
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)
主要是給自己看的,所以肯定會出現很多錯誤哈哈哈哈哈