spi收发时的寄存器sr不变_「正点原子Linux连载」第二十七章SPI实验(二)
1)實(shí)驗(yàn)平臺(tái):正點(diǎn)原子Linux開發(fā)板
2)摘自《正點(diǎn)原子I.MX6U嵌入式Linux驅(qū)動(dòng)開發(fā)指南》
關(guān)注官方微信號(hào)公眾號(hào),獲取更多資料:正點(diǎn)原子
文件bsp_spi.c中有兩個(gè)函數(shù):spi_init和spich0_readwrite_byte,函數(shù)spi_init是SPI初始化函數(shù),此函數(shù)會(huì)初始化SPI的時(shí)鐘,通道等。函數(shù)spich0_readwrite_byte是SPI收發(fā)函數(shù),通過此函數(shù)即可完成SPI的全雙工數(shù)據(jù)收發(fā)。
接下來在文件bsp_icm20608.h中輸入如下內(nèi)容:
示例代碼27.3.3 bsp_icm20608.h文件代碼
1 #ifndef _BSP_ICM20608_H
2 #define _BSP_ICM20608_H
3/***************************************************************
4 Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
5 文件名 : bsp_icm20608.h
6 作者 : 左忠凱
7 版本 : V1.0
8 描述 : ICM20608驅(qū)動(dòng)文件。
9 其他 : 無
10 論壇 : www.openedv.com
11 日志 : 初版V1.0 2019/3/26 左忠凱創(chuàng)建
12 ***************************************************************/
13 #include "imx6ul.h"
14 #include "bsp_gpio.h"
15
16/* SPI片選信號(hào) */
17 #define ICM20608_CSN(n)(n ? gpio_pinwrite(GPIO1,20,1):
gpio_pinwrite(GPIO1,20,0))
18
19 #define ICM20608G_ID 0XAF/* ID值 */
20 #define ICM20608D_ID 0XAE/* ID值 */
21
22/* ICM20608寄存器
23 *復(fù)位后所有寄存器地址都為0,除了
24 *Register 107(0X6B) Power Management 1 = 0x40
25 *Register 117(0X75) WHO_AM_I = 0xAF或者0xAE
26 */
27/* 陀螺儀和加速度自測(cè)(出產(chǎn)時(shí)設(shè)置,用于與用戶的自檢輸出值比較) */
28 #define ICM20_SELF_TEST_X_GYRO 0x00
29 #define ICM20_SELF_TEST_Y_GYRO 0x01
30 #define ICM20_SELF_TEST_Z_GYRO 0x02
31 #define ICM20_SELF_TEST_X_ACCEL 0x0D
32 #define ICM20_SELF_TEST_Y_ACCEL 0x0E
33 #define ICM20_SELF_TEST_Z_ACCEL 0x0F
34/***********省略掉其他宏定義*************/
35 #define ICM20_ZA_OFFSET_H 0x7D
36 #define ICM20_ZA_OFFSET_L 0x7E
37
38/*
39 * ICM20608結(jié)構(gòu)體
40 */
41struct icm20608_dev_struc
42{
43 signedint gyro_x_adc; /* 陀螺儀X軸原始值 */
44 signedint gyro_y_adc; /* 陀螺儀Y軸原始值 */
45 signedint gyro_z_adc; /* 陀螺儀Z軸原始值 */
46 signedint accel_x_adc; /* 加速度計(jì)X軸原始值 */
47 signedint accel_y_adc; /* 加速度計(jì)Y軸原始值 */
48 signedint accel_z_adc; /* 加速度計(jì)Z軸原始值 */
49 signedint temp_adc; /* 溫度原始值 */
50
51 /* 下面是計(jì)算得到的實(shí)際值,擴(kuò)大100倍 */
52 signedint gyro_x_act; /* 陀螺儀X軸實(shí)際值 */
53 signedint gyro_y_act; /* 陀螺儀Y軸實(shí)際值 */
54 signedint gyro_z_act; /* 陀螺儀Z軸實(shí)際值 */
55 signedint accel_x_act; /* 加速度計(jì)X軸實(shí)際值 */
56 signedint accel_y_act; /* 加速度計(jì)Y軸實(shí)際值 */
57 signedint accel_z_act; /* 加速度計(jì)Z軸實(shí)際值 */
58 signedint temp_act; /* 溫度實(shí)際值 */
59};
60
61struct icm20608_dev_struc icm20608_dev;/* icm20608設(shè)備 */
62
63/* 函數(shù)聲明 */
64unsignedchar icm20608_init(void);
65void icm20608_write_reg(unsignedchar reg,unsignedchar value);
66unsignedchar icm20608_read_reg(unsignedchar reg);
67void icm20608_read_len(unsignedchar reg,unsignedchar*buf,
unsignedchar len);
68void icm20608_getdata(void);
69 #endif
文件bsp_icm20608.h里面先定義了一個(gè)宏ICM20608_CSN,這個(gè)是ICM20608的SPI片選引腳。接下來定義了一些ICM20608的ID和寄存器地址。第41行定義了一個(gè)結(jié)構(gòu)體icm20608_dev_struc,這個(gè)結(jié)構(gòu)體是ICM20608的設(shè)備結(jié)構(gòu)體,里面的成員變量用來保存ICM20608的原始數(shù)據(jù)值和經(jīng)過轉(zhuǎn)換得到的實(shí)際值。實(shí)際值是有小數(shù)的,本章例程取兩位小數(shù),為了方便計(jì)算,實(shí)際值擴(kuò)大了100倍,這樣實(shí)際值就是整數(shù)了,但是在使用的時(shí)候要除100重新得到小數(shù)部分。最后就是一些函數(shù)聲明,接下來在文件bsp_icm20608.c中輸入如下所示內(nèi)容:
示例代碼27.3.4 bsp_icm20608.c文件代碼
/***************************************************************
Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名 : bsp_icm20608.c
作者 : 左忠凱
版本 : V1.0
描述 : ICM20608驅(qū)動(dòng)文件。
其他 : 無
論壇 : www.openedv.com
日志 : 初版V1.0 2019/3/26 左忠凱創(chuàng)建
***************************************************************/
1 #include "bsp_icm20608.h"
2 #include "bsp_delay.h"
3 #include "bsp_spi.h"
4 #include "stdio.h"
5
6struct icm20608_dev_struc icm20608_dev;/* icm20608設(shè)備 */
7
8/*
9 * @description : 初始化ICM20608
10 * @param : 無
11 * @return : 0 初始化成功,其他值初始化失敗
12 */
13unsignedchar icm20608_init(void)
14{
15unsignedchar regvalue;
16 gpio_pin_config_t cs_config;
17
18/* 1、ESPI3 IO初始化
19 * ECSPI3_SCLK -> UART2_RXD
20 * ECSPI3_MISO -> UART2_RTS
21 * ECSPI3_MOSI -> UART2_CTS
22 */
23 IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK,0);
24 IOMUXC_SetPinMux(IOMUXC_UART2_CTS_B_ECSPI3_MOSI,0);
25 IOMUXC_SetPinMux(IOMUXC_UART2_RTS_B_ECSPI3_MISO,0);
26 IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK,0x10B1);
27 IOMUXC_SetPinConfig(IOMUXC_UART2_CTS_B_ECSPI3_MOSI,0x10B1);
28 IOMUXC_SetPinConfig(IOMUXC_UART2_RTS_B_ECSPI3_MISO,0x10B1);
29
30/* 初始化片選引腳 */
31 IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_GPIO1_IO20,0);
32 IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_GPIO1_IO20,0X10B0);
33 cs_config.direction = kGPIO_DigitalOutput;
34 cs_config.outputLogic =0;
35 gpio_init(GPIO1,20,&cs_config);
36
37/* 2、初始化SPI */
38 spi_init(ECSPI3);
39
40 icm20608_write_reg(ICM20_PWR_MGMT_1,0x80);/* 復(fù)位 */
41 delayms(50);
42 icm20608_write_reg(ICM20_PWR_MGMT_1,0x01);/* 關(guān)閉睡眠 */
43 delayms(50);
44
45 regvalue = icm20608_read_reg(ICM20_WHO_AM_I);
46 printf("icm20608 id = %#X", regvalue);
47if(regvalue != ICM20608G_ID && regvalue != ICM20608D_ID)
48return1;
49
50 icm20608_write_reg(ICM20_SMPLRT_DIV,0x00); /* 輸出速率設(shè)置 */
51 icm20608_write_reg(ICM20_GYRO_CONFIG,0x18);/* 陀螺儀±2000dps */
52 icm20608_write_reg(ICM20_ACCEL_CONFIG,0x18);/* 加速度計(jì)±16G */
53 icm20608_write_reg(ICM20_CONFIG,0x04);/* 陀螺BW=20Hz */
54 icm20608_write_reg(ICM20_ACCEL_CONFIG2,0x04);
55 icm20608_write_reg(ICM20_PWR_MGMT_2,0x00);/* 打開所有軸 */
56 icm20608_write_reg(ICM20_LP_MODE_CFG,0x00);/* 關(guān)閉低功耗 */
57 icm20608_write_reg(ICM20_FIFO_EN,0x00); /* 關(guān)閉FIFO */
58return0;
59}
60
61/*
62 * @description : 寫ICM20608指定寄存器
63 * @param - reg : 要讀取的寄存器地址
64 * @param – value : 要寫入的值
65 * @return : 無
66 */
67void icm20608_write_reg(unsignedchar reg,unsignedchar value)
68{
69/* ICM20608在使用SPI接口的時(shí)候寄存器地址只有低7位有效,
70 * 寄存器地址最高位是讀/寫標(biāo)志位,讀的時(shí)候要為1,寫的時(shí)候要為0。
71 */
72 reg &=~0X80;
73
74 ICM20608_CSN(0); /* 使能SPI傳輸 */
75 spich0_readwrite_byte(ECSPI3, reg); /* 發(fā)送寄存器地址 */
76 spich0_readwrite_byte(ECSPI3, value); /* 發(fā)送要寫入的值 */
77 ICM20608_CSN(1); /* 禁止SPI傳輸 */
78}
79
80/*
81 * @description : 讀取ICM20608寄存器值
82 * @param - reg : 要讀取的寄存器地址
83 * @return : 讀取到的寄存器值
84 */
85unsignedchar icm20608_read_reg(unsignedchar reg)
86{
87unsignedchar reg_val;
88
89/* ICM20608在使用SPI接口的時(shí)候寄存器地址只有低7位有效,
90 * 寄存器地址最高位是讀/寫標(biāo)志位,讀的時(shí)候要為1,寫的時(shí)候要為0。
91 */
92 reg |=0x80;
93
94 ICM20608_CSN(0); /* 使能SPI傳輸 */
95 spich0_readwrite_byte(ECSPI3, reg); /* 發(fā)送寄存器地址 */
96 reg_val = spich0_readwrite_byte(ECSPI3,0XFF);/* 讀取寄存器的值*/
97 ICM20608_CSN(1); /* 禁止SPI傳輸 */
98return(reg_val); /* 返回讀取到的寄存器值 */
99}
100
101/*
102 * @description : 讀取ICM20608連續(xù)多個(gè)寄存器
103 * @param - reg : 要讀取的寄存器地址
104 * @return : 讀取到的寄存器值
105 */
106void icm20608_read_len(unsignedchar reg,unsignedchar*buf,
unsignedchar len)
107{
108unsignedchar i;
109
110/* ICM20608在使用SPI接口的時(shí)候寄存器地址,只有低7位有效,
111 * 寄存器地址最高位是讀/寫標(biāo)志位讀的時(shí)候要為1,寫的時(shí)候要為0。
112 */
113 reg |=0x80;
114
115 ICM20608_CSN(0);/* 使能SPI傳輸 */
116 spich0_readwrite_byte(ECSPI3, reg);/* 發(fā)送寄存器地址 */
117for(i =0; i < len; i++)/* 順序讀取寄存器的值 */
118{
119 buf[i]= spich0_readwrite_byte(ECSPI3,0XFF);
120}
121 ICM20608_CSN(1);/* 禁止SPI傳輸 */
122}
123
124/*
125 * @description : 獲取陀螺儀的分辨率
126 * @param : 無
127 * @return : 獲取到的分辨率
128 */
129float icm20608_gyro_scaleget(void)
130{
131unsignedchar data;
132float gyroscale;
133
134 data =(icm20608_read_reg(ICM20_GYRO_CONFIG)>>3)&0X3;
135switch(data){
136case0:
137 gyroscale =131;
138break;
139case1:
140 gyroscale =65.5;
141break;
142case2:
143 gyroscale =32.8;
144break;
145case3:
146 gyroscale =16.4;
147break;
148}
149return gyroscale;
150}
151
152/*
153 * @description : 獲取加速度計(jì)的分辨率
154 * @param : 無
155 * @return : 獲取到的分辨率
156 */
157unsignedshort icm20608_accel_scaleget(void)
158{
159unsignedchar data;
160unsignedshort accelscale;
161
162 data =(icm20608_read_reg(ICM20_ACCEL_CONFIG)>>3)&0X3;
163switch(data){
164case0:
165 accelscale =16384;
166break;
167case1:
168 accelscale =8192;
169break;
170case2:
171 accelscale =4096;
172break;
173case3:
174 accelscale =2048;
175break;
176}
177return accelscale;
178}
179
180/*
181 * @description : 讀取ICM20608的加速度、陀螺儀和溫度原始值
182 * @param : 無
183 * @return : 無
184 */
185void icm20608_getdata(void)
186{
187float gyroscale;
188unsignedshort accescale;
189unsignedchar data[14];
190
191 icm20608_read_len(ICM20_ACCEL_XOUT_H, data,14);
192
193 gyroscale = icm20608_gyro_scaleget();
194 accescale = icm20608_accel_scaleget();
195
196 icm20608_dev.accel_x_adc =(signedshort)((data[0]<<8)|
data[1]);
197 icm20608_dev.accel_y_adc =(signedshort)((data[2]<<8)|
data[3]);
198 icm20608_dev.accel_z_adc =(signedshort)((data[4]<<8)|
data[5]);
199 icm20608_dev.temp_adc =(signedshort)((data[6]<<8)|
data[7]);
200 icm20608_dev.gyro_x_adc =(signedshort)((data[8]<<8)|
data[9]);
201 icm20608_dev.gyro_y_adc =(signedshort)((data[10]<<8)|
data[11]);
202 icm20608_dev.gyro_z_adc =(signedshort)((data[12]<<8)|
data[13]);
203
204/* 計(jì)算實(shí)際值 */
205 icm20608_dev.gyro_x_act =((float)(icm20608_dev.gyro_x_adc)/
gyroscale)*100;
206 icm20608_dev.gyro_y_act =((float)(icm20608_dev.gyro_y_adc)/
gyroscale)*100;
207 icm20608_dev.gyro_z_act =((float)(icm20608_dev.gyro_z_adc)/
gyroscale)*100;
208 icm20608_dev.accel_x_act =((float)(icm20608_dev.accel_x_adc)/
accescale)*100;
209 icm20608_dev.accel_y_act =((float)(icm20608_dev.accel_y_adc)/
accescale)*100;
210 icm20608_dev.accel_z_act =((float)(icm20608_dev.accel_z_adc)/
accescale)*100;
211 icm20608_dev.temp_act =(((float)(icm20608_dev.temp_adc)-25)/
326.8+25)*100;
212}
文件bsp_imc20608.c是ICM20608的驅(qū)動(dòng)文件,里面有7個(gè)函數(shù),我們依次來看一下。第1個(gè)函數(shù)是icm20608_init,這個(gè)是ICM20608的初始化函數(shù),此函數(shù)先初始化ICM20608所使用的SPI引腳,將其復(fù)用為ECSPI3。因?yàn)槲覀儽菊碌腟PI片選采用軟件控制的方式,所以SPI片選引腳設(shè)置成了普通的輸出模式。設(shè)置完SPI所使用的引腳以后就是調(diào)用函數(shù)spi_init來初始化SPI3,最后初始化ICM20608,就是配置ICM20608的寄存器。第2個(gè)和第3個(gè)函數(shù)分別是icm20608_write_reg和icm20608_read_reg,這兩個(gè)函數(shù)分別用于寫/讀ICM20608的指定寄存器。第4個(gè)函數(shù)是icm20608_read_len,此函數(shù)也是讀取ICM20608的寄存器值,但是此函數(shù)可以讀取連續(xù)多個(gè)寄存器的值,一般用于讀取ICM20608傳感器數(shù)據(jù)。第5和第6個(gè)函數(shù)分別是icm20608_gyro_scaleget和icm20608_accel_scaleget,這兩個(gè)函數(shù)分別用于獲取陀螺儀和加速度計(jì)的分辨率,因?yàn)橥勇輧x和加速度的測(cè)量范圍設(shè)置的不同,其分辨率就不同,所以在計(jì)算實(shí)際值的時(shí)候要根據(jù)實(shí)際的量程范圍來得到對(duì)應(yīng)的分辨率。最后一個(gè)函數(shù)是icm20608_getdata,此函數(shù)就是用于獲取ICM20608的加速度計(jì)、陀螺儀和溫度計(jì)的數(shù)據(jù),并且會(huì)根據(jù)設(shè)置的測(cè)量范圍計(jì)算出實(shí)際的值,比如加速度的g值、陀螺儀的角速度值和溫度計(jì)的溫度值。
最后在main.c中輸入如下內(nèi)容:
示例代碼27.3.5 main.c文件代碼
/**************************************************************
Copyright ? zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名 : mian.c
作者 : 左忠凱
版本 : V1.0
描述 : I.MX6U開發(fā)板裸機(jī)實(shí)驗(yàn)19 SPI實(shí)驗(yàn)
其他 : SPI也是最常用的接口,ALPHA開發(fā)板上有一個(gè)6軸傳感器ICM20608,
這個(gè)六軸傳感器就是SPI接口的,本實(shí)驗(yàn)就來學(xué)習(xí)如何驅(qū)動(dòng)I.MX6U
的SPI接口,并且通過SPI接口讀取ICM20608的數(shù)據(jù)值。
論壇 : www.openedv.com
日志 : 初版V1.0 2019/1/17 左忠凱創(chuàng)建
**************************************************************/
1 #include "bsp_clk.h"
2 #include "bsp_delay.h"
3 #include "bsp_led.h"
4 #include "bsp_beep.h"
5 #include "bsp_key.h"
6 #include "bsp_int.h"
7 #include "bsp_uart.h"
8 #include "bsp_lcd.h"
9 #include "bsp_rtc.h"
10 #include "bsp_icm20608.h"
11 #include "bsp_spi.h"
12 #include "stdio.h"
13
14/*
15 * @description : 指定的位置顯示整數(shù)數(shù)據(jù)
16 * @param - x : X軸位置
17 * @param - y : Y軸位置
18 * @param – size : 字體大小
19 * @param - num : 要顯示的數(shù)據(jù)
20 * @return : 無
21 */
22void integer_display(unsignedshort x,unsignedshort y,
unsignedchar size,signedint num)
23{
24char buf[200];
25
26 lcd_fill(x, y, x +50, y + size, tftlcd_dev.backcolor);
27
28 memset(buf,0,sizeof(buf));
29if(num <0)
30 sprintf(buf,"-%d",-num);
31else
32 sprintf(buf,"%d", num);
33 lcd_show_string(x, y,50, size, size, buf);
34}
35
36/*
37 * @description : 指定的位置顯示小數(shù)數(shù)據(jù),比如5123,顯示為51.23
38 * @param - x : X軸位置
39 * @param - y : Y軸位置
40 * @param – size : 字體大小
41 * @param - num : 要顯示的數(shù)據(jù),實(shí)際小數(shù)擴(kuò)大100倍,
42 * @return : 無
43 */
44void decimals_display(unsignedshort x,unsignedshort y,
unsignedchar size,signedint num)
45{
46signedint integ;/* 整數(shù)部分 */
47signedint fract;/* 小數(shù)部分 */
48signedint uncomptemp = num;
49char buf[200];
50
51if(num <0)
52 uncomptemp =-uncomptemp;
53 integ = uncomptemp /100;
54 fract = uncomptemp %100;
55
56 memset(buf,0,sizeof(buf));
57if(num <0)
58 sprintf(buf,"-%d.%d", integ, fract);
59else
60 sprintf(buf,"%d.%d", integ, fract);
61 lcd_fill(x, y, x +60, y + size, tftlcd_dev.backcolor);
62 lcd_show_string(x, y,60, size, size, buf);
63}
64
65/*
66 * @description : 使能I.MX6U的硬件NEON和FPU
67 * @param : 無
68 * @return : 無
69 */
70void imx6ul_hardfpu_enable(void)
71{
72uint32_t cpacr;
73uint32_t fpexc;
74
75/* 使能NEON和FPU */
76 cpacr = __get_CPACR();
77 cpacr =(cpacr &~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
78|(3UL<< CPACR_cp10_Pos)|(3UL<< CPACR_cp11_Pos);
79 __set_CPACR(cpacr);
80 fpexc = __get_FPEXC();
81 fpexc |=0x40000000UL;
82 __set_FPEXC(fpexc);
83}
84
85/*
86 * @description : main函數(shù)
87 * @param : 無
88 * @return : 無
89 */
90int main(void)
91{
92unsignedchar state = OFF;
93
94 imx6ul_hardfpu_enable(); /* 使能I.MX6U的硬件浮點(diǎn) */
95 int_init(); /* 初始化中斷(一定要最先調(diào)用!) */
96 imx6u_clkinit(); /* 初始化系統(tǒng)時(shí)鐘 */
97 delay_init(); /* 初始化延時(shí) */
98 clk_enable(); /* 使能所有的時(shí)鐘 */
99 led_init(); /* 初始化led */
100 beep_init(); /* 初始化beep */
101 uart_init(); /* 初始化串口,波特率115200 */
102 lcd_init(); /* 初始化LCD */
103
104 tftlcd_dev.forecolor = LCD_RED;
105 lcd_show_string(50,10,400,24,24,
(char*)"IMX6U-ALPHA SPI TEST");
106 lcd_show_string(50,40,200,16,16,(char*)"ICM20608 TEST");
107 lcd_show_string(50,60,200,16,16,(char*)"ATOM@ALIENTEK");
108 lcd_show_string(50,80,200,16,16,(char*)"2019/3/27");
109
110while(icm20608_init()) /* 初始化ICM20608 */
111{
112 lcd_show_string(50,100,200,16,16,
(char*)"ICM20608 Check Failed!");
113 delayms(500);
114 lcd_show_string(50,100,200,16,16,
(char*)"Please Check! ");
115 delayms(500);
116}
117 lcd_show_string(50,100,200,16,16,(char*)"ICM20608 Ready");
118 lcd_show_string(50,130,200,16,16,(char*)"accel x:");
119 lcd_show_string(50,150,200,16,16,(char*)"accel y:");
120 lcd_show_string(50,170,200,16,16,(char*)"accel z:");
121 lcd_show_string(50,190,200,16,16,(char*)"gyro x:");
122 lcd_show_string(50,210,200,16,16,(char*)"gyro y:");
123 lcd_show_string(50,230,200,16,16,(char*)"gyro z:");
124 lcd_show_string(50,250,200,16,16,(char*)"temp :");
125 lcd_show_string(50+181,130,200,16,16,(char*)"g");
126 lcd_show_string(50+181,150,200,16,16,(char*)"g");
127 lcd_show_string(50+181,170,200,16,16,(char*)"g");
128 lcd_show_string(50+181,190,200,16,16,(char*)"o/s");
129 lcd_show_string(50+181,210,200,16,16,(char*)"o/s");
130 lcd_show_string(50+181,230,200,16,16,(char*)"o/s");
131 lcd_show_string(50+181,250,200,16,16,(char*)"C");
132
133 tftlcd_dev.forecolor = LCD_BLUE;
134
135while(1)
136{
137 icm20608_getdata();/* 獲取數(shù)據(jù)值 */
138/* 在LCD上顯示原始值 */
139 integer_display(50+70,130,16, icm20608_dev.accel_x_adc);
140 integer_display(50+70,150,16, icm20608_dev.accel_y_adc);
141 integer_display(50+70,170,16, icm20608_dev.accel_z_adc);
142 integer_display(50+70,190,16, icm20608_dev.gyro_x_adc);
143 integer_display(50+70,210,16, icm20608_dev.gyro_y_adc);
144 integer_display(50+70,230,16, icm20608_dev.gyro_z_adc);
145 integer_display(50+70,250,16, icm20608_dev.temp_adc);
146
147/* 在LCD上顯示計(jì)算得到的原始值 */
148 decimals_display(50+70+50,130,16,
icm20608_dev.accel_x_act);
149 decimals_display(50+70+50,150,16,
icm20608_dev.accel_y_act);
150 decimals_display(50+70+50,170,16,
icm20608_dev.accel_z_act);
151 decimals_display(50+70+50,190,16,
icm20608_dev.gyro_x_act);
152 decimals_display(50+70+50,210,16,
icm20608_dev.gyro_y_act);
153 decimals_display(50+70+50,230,16,
icm20608_dev.gyro_z_act);
154 decimals_display(50+70+50,250,16,
icm20608_dev.temp_act);
155 delayms(120);
156 state =!state;
157 led_switch(LED0,state);
158}
159return0;
160}
文件main.c一開始有兩個(gè)函數(shù)integer_display和decimals_display,這兩個(gè)函數(shù)用于在LCD上顯示獲取到的ICM20608數(shù)據(jù)值,函數(shù)integer_display用于顯示原始數(shù)據(jù)值,也就是整數(shù)值。函數(shù)decimals_display用于顯示實(shí)際值,實(shí)際值擴(kuò)大了100倍,此函數(shù)會(huì)提取出實(shí)際值的整數(shù)部分和小數(shù)部分并顯示在LCD上。另一個(gè)重要的函數(shù)是imx6ul_hardfpu_enable,這個(gè)函數(shù)用于開啟I.MX6U的NEON和硬件FPU(浮點(diǎn)運(yùn)算單元),因?yàn)楸菊率褂玫搅烁↑c(diǎn)運(yùn)算,而I.MX6U的Cortex-A7是支持NEON和FPU(VFPV4_D32)的,但是在使用I.MX6U的硬件FPU之前是先要開啟的。
第110行調(diào)用了函數(shù)icm20608_init來初始化ICM20608,如果初始化失敗的話就會(huì)在LCD上閃爍提示語句。最后在main函數(shù)的while循環(huán)中不斷的調(diào)用函數(shù)icm20608_getdata獲取ICM20608的傳感器數(shù)據(jù),并且顯示在LCD上。實(shí)驗(yàn)程序編寫就到這里結(jié)束了,接下來就是編譯、下載和驗(yàn)證了。
27.4編譯下載驗(yàn)證
27.4.1 編寫Makefile和鏈接腳本
修改Makefile中的TARGET為icm20608,然后在在INCDIRS和SRCDIRS中加入“bsp/spi”和“bsp/icm20608”,修改后的Makefile如下:
示例代碼27.4.1.1 Makefile文件代碼
1 CROSS_COMPILE ?= arm-linux-gnueabihf-
2 TARGET ?= icm20608
3
4/* 省略掉其它代碼...... */
5
6 INCDIRS := imx6ul
7 stdio/include
8 bsp/clk
9 bsp/led
10 bsp/delay
11 bsp/beep
12 bsp/gpio
13 bsp/key
14 bsp/exit
15 bsp/int
16 bsp/epittimer
17 bsp/keyfilter
18 bsp/uart
19 bsp/lcd
20 bsp/rtc
21 bsp/i2c
22 bsp/ap3216c
23 bsp/spi
24 bsp/icm20608
25
26 SRCDIRS := project
27 stdio/lib
28 bsp/clk
29 bsp/led
30 bsp/delay
31 bsp/beep
32 bsp/gpio
33 bsp/key
34 bsp/exit
35 bsp/int
36 bsp/epittimer
37 bsp/keyfilter
38 bsp/uart
39 bsp/lcd
40 bsp/rtc
41 bsp/i2c
42 bsp/ap3216c
43 bsp/spi
44 bsp/icm20608
45
46/* 省略掉其它代碼...... */
47
48$(COBJS): obj/%.o : %.c
49 $(CC) -Wall -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -Wa,
-mimplicit-it=thumb -nostdlib -fno-builtin
-c -O2 $(INCLUDE) -o $@ $<
50
51 clean:
52 rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS)$(SOBJS)
第2行修改變量TARGET為“icm20608”,也就是目標(biāo)名稱為“ap3216c”。
第23和24行在變量INCDIRS中添加SPI和ICM20608的驅(qū)動(dòng)頭文件(.h)路徑。
第43和44行在變量SRCDIRS中添加SPI和ICM20608驅(qū)動(dòng)文件(.c)路徑。
第49行加入了“-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard”指令,這些指令用于指定編譯浮點(diǎn)運(yùn)算的時(shí)候使用硬件FPU。因?yàn)楸菊率褂玫搅烁↑c(diǎn)運(yùn)算,而I.MX6U是支持硬件FPU的,雖然我們?cè)趍ain函數(shù)中已經(jīng)打開了NEON和FPU,但是在編譯相應(yīng)C文件的時(shí)候也要指定使用硬件FPU來編譯浮點(diǎn)運(yùn)算。
鏈接腳本保持不變。
27.4.2編譯下載
使用Make命令編譯代碼,編譯成功以后使用軟件imxdownload將編譯完成的icm20608.bin文件下載到SD卡中,命令如下:
chmod 777 imxdownload //給予imxdownload可執(zhí)行權(quán)限,一次即可
./imxdownload icm20608.bin /dev/sdd //燒寫到SD卡中
燒寫成功以后將SD卡插到開發(fā)板的SD卡槽中,然后復(fù)位開發(fā)板。如果ICM20608工作正常的話就會(huì)在LCD上顯示獲取到的傳感器數(shù)據(jù),如圖27.4.2.1所示:
圖27.4.2.1LCD界面
在圖27.4.2.1中可以看到加速度計(jì)Z軸在靜止?fàn)顟B(tài)下是0.98g,這不正是重力加速度。溫度傳感器測(cè)量到的溫度是31.39°C,這個(gè)是芯片內(nèi)部的溫度,并不是室溫!芯片內(nèi)部溫度一般要比室溫高。如果動(dòng)一下開發(fā)板的話加速度計(jì)和陀螺儀的數(shù)據(jù)就會(huì)變化。
總結(jié)
以上是生活随笔為你收集整理的spi收发时的寄存器sr不变_「正点原子Linux连载」第二十七章SPI实验(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Express框架开发知识点总结
- 下一篇: linux telnet smtp,如何