本文基于rtt的iic驱动框架来实现加速度传感器数据的读取测试,废话不多说开启正文。. K0 z( }# T7 ], N y
( M1 `$ l M5 D6 D4 s6 s+ J& T
1.编译RT-thread加入I2c框架相关代码本实验使用的是官方代码中已经值支持bsp(\rt-thread\bsp\stm32\stm32l476-st-nucleo),默认的配置是没有组入软件IIC的软件框架。使用RTT 的ENV 工具很容易就可以将IIC软件框架代码组入系统,组入方法如下,在BSP目录下使用env工具,输入menuconfig。
, N5 T% n1 q/ `0 x, H4 o2 R( |* b
$ S0 i6 _- A3 {, E& N: A5 l
+ k( l+ C# p! [& ]8 I1 }; u1 A* D
配置路径如下:
+ Z2 i4 `3 ~( x; C* P K6 l3 z ]0 M5 G
; A- i0 |' s. H# { Y( g: ~0 u
, W ]2 m5 h1 X1 O2 S) W, U6 v3 l9 y8 ]+ o% n4 @3 C
即可开启I2C,并配置SCL,SDA对应的引脚ID即可。配置完成后,运行SCONS即可发现相关的IIC代码文件已经参与编译了,我的配置如下。 ' D. x0 p F# V5 A |. p( k
0 w/ l* J$ R7 I* X" V; I# b' h4 D9 S# w5 r
2.适配加速度传感器,按照上一篇IIC驱动框架的理解,使用的时只要使用rt_i2c_bus_device_find查找对应的I2C设备,试验配置的名称为“i2c1”,找到相应的设备后调用rt_i2c_transfer 函数即可操作i2c总线的读和写操作了,所有的基于I2C总线的操作驱动框架已经集成,只需要用户实现芯片相关的配置即可而不用关心IIC协议的具体细节。适配过程中遇到两个问题。
. }* Y; s( y5 u5 H/ K①i2c的地址问题,发送结合接收时地址设置为芯片手册对应的7bit地址值即可,开始的时候读和写操做设置的地址为实际的8位地址,总是应答NACK,跟了下代码发现底层代码会根据读写操做自动设定地址,自己的操作存粹是多此一举。
) ?5 C7 V/ s0 P- e I, u②因硬件上未配置总线上拉电阻,造作总线的时候总是失败,默认的IO配置的开漏输出是没有配置内部上拉的,所以总是失败,配置成内部上拉后总线就可以正常通信了。
$ U0 @8 V7 G$ e3 M) A) m& |0 a" {/ d' K5 v2 N
8 |/ J2 B m% e9 \6 A# G! K3 q
- A% u! B ]) J7 r6 W: f1 `7 O6 M+ n/ ?3 k, q5 \: `" b
7 p6 b! E; e$ u+ a) O- r* g3 g
3.相关的测试代码如下:
$ R" N: ~6 {+ i- a①初始化KX224
: e# d. J( F f# o- static rt_uint32_t _g_sens;# z ?/ }% A. U3 V! w
- struct rt_i2c_bus_device* bus = NULL;) P3 `. |4 P0 U
/ S& p, v6 e2 P- ~; A8 w5 z- static void kx224_init(void)0 H8 n8 G. Y: j+ h* p8 K
- {# }) o: [' b n6 p7 V! Q) N" h5 j
- rt_uint8_t deviceid = 0,reg = 0,gsel = 0;" ^4 m5 O' G6 D7 m
-
6 e; d% `1 E- B- [; S* G, H - bus = rt_i2c_bus_device_find("i2c1");/ i% n0 I; l; ~, R
- if(!bus)
% |% J+ W: t1 d; S* M - {4 C1 y2 V3 B! s$ r4 H! m
- rt_kprintf("can't find i2c device\n");
6 c" N2 q, J6 n# ~9 Y, _ t' }3 e - return;
& o: Y" h9 r: g- N - }
7 B$ ], r# ~% _" @, e9 Q4 p6 b - write_cmd(bus,KX224_WHO_AM_I);
; g8 W4 W T' w4 s" F - red_reg(bus,1,&deviceid);
, j+ u; i0 V" U" B$ f% h$ O' i8 k - if(deviceid != KX224_WAI_VAL)5 M1 t# }/ K; }0 r1 s. S# `9 B/ x
- {: [1 ^' t5 u% J3 x5 B6 d
- rt_kprintf("can't find device\n");
3 H" Z. c1 h) B' s. h/ @ - return; $ y/ D! Z2 |! ]
- }& a' R/ w4 F* H) h0 f* A% |6 Q: X
- write_reg(bus,KX224_CNTL1,KX224_CNTL1_VAL);
) B3 |- }/ D( o$ K - write_reg(bus,KX224_ODCNTL,KX224_ODCNTL_VAL);8 Y7 h. v/ a; A6 e
- write_cmd(bus,KX224_CNTL1);
# l, @; p k( g& h - red_reg(bus,1,®);
9 U$ ?/ _! K8 _4 Q* O - gsel = reg & KX224_CNTL1_GSELMASK;/ F2 `& _8 L" V% f' G
- rt_kprintf("reg is 0x%02x gsel is 0x%02x\n",reg,gsel);! d' _4 m; e% u, c e" G; g
- reg |= KX224_CNTL1_PC1;7 W6 @+ E1 A7 W- i
- write_reg(bus,KX224_CNTL1, reg);2 ?+ h* U4 E# C6 J) {
- switch(gsel) {6 L B5 ?0 x1 S" a
- case KX224_CNTL1_GSEL_8G :
9 d$ |0 E/ c, N. r2 E9 }' @+ k - // (Equivalent counts) / (Range) = (32768 / 8)- W8 ]- g# f7 E+ v* h6 V. v
- _g_sens = 4096;& E1 L5 R! t- F; k" @
- break;
# z9 a/ A# c3 l! }) K$ {. Q. ]4 }" o# K
- G8 _" m3 v4 t0 U- P- case KX224_CNTL1_GSEL_16G :2 `1 v6 h& ~$ A O# X
- // (Equivalent counts) / (Range) = (32768 / 16)
$ K& @8 b2 E u: C- y3 d - _g_sens = 2048;/ D4 ?" }6 L& g- y( }0 o7 ]
- break;. e9 ?2 v3 c$ Y) s
- 2 u4 N& {' [5 E$ E3 v m
- case KX224_CNTL1_GSEL_32G :
+ f5 ^7 O! i7 O0 V5 D' d; c) N% g; q6 R - // (Equivalent counts) / (Range) = (32768 / 32)8 D, a H6 h G6 v
- _g_sens = 1024;7 G3 P0 Q$ E1 m0 F4 E' u! c; @
- break;
7 k( }; ^4 Z8 D0 I6 M
8 F# A N; w. o' l" _, J. j' }- default:: P7 h- V- h7 X; Q% r9 C
- break;2 |1 X1 z, g: B# c0 ?6 {
- }* |7 w$ w; V# ]. Z
- rt_kprintf("_g_sens is <%d>\n",_g_sens);
& S4 d# \- ?- ^8 W' f8 A - }
复制代码 : k. u- }7 _# x* J: e
: I! ]+ m3 N* h8 h
②i2c总线的读写操 2 p2 A( C& z( R9 z. i6 t8 ^+ V9 q
- static rt_err_t write_reg(struct rt_i2c_bus_device *bus,rt_uint8_t reg,rt_uint8_t data)
) x, g5 G* B' c0 I - {+ x1 P( P1 P2 ?" R% T0 L
- struct rt_i2c_msg msgs;6 L# X* \9 O" \
- rt_uint8_t buff[2];
J. \7 F- V( n) R - rt_size_t size = 0;
; Y$ i i# \* h+ g6 s. M; f - & B& R) o9 i5 D4 N0 E6 q5 |
- buff[0] = reg;
. ]3 N1 c+ f' t* D - buff[1] = data;5 R0 t! l, I7 W0 e( o4 a' {; ?0 Y
- 2 b' U7 L; H, e$ {
- msgs.addr = KX224_DEVICE_ADDRESS_1E;3 f1 o; x7 k" V) ~
- msgs.flags = RT_I2C_WR;
1 t; Y* I% ~" }0 p/ ]; e% K& K - msgs.buf = buff;
% |7 ~ X& s1 o1 v. m5 H1 G - msgs.len = 2;
' [ d, _) M; Y" @; h - 5 i0 _5 l+ K: i3 u+ ~& S$ O7 T
- if( rt_i2c_transfer(bus, &msgs, 1))# a) N0 N/ q( c" {' Q/ k% l
- {7 r0 C) @- n/ L
- return RT_EOK;
$ x! F' w! z5 L a - }
) Q# o9 L1 ?% e" b# o) } - else( o/ A* c& f+ n
- {
4 V& j, d. N/ _+ ` - return -RT_ERROR;) {- \9 \9 f, M' [4 X
- }
7 S. A6 S6 B& s1 {; H - }3 S- S# {, | F: Z, G( R. m+ I
- + }/ e0 O3 _# G) J S. D4 j
- static rt_err_t write_cmd(struct rt_i2c_bus_device *bus,rt_uint8_t reg)
0 @' P; P) N" Y - {
2 T7 Z2 |# i) [6 ?" u. E9 n5 o; i - struct rt_i2c_msg msgs;3 u; J8 w+ L6 g/ }, f5 S9 V
- rt_uint8_t buff[2];4 b! c: Y" ]0 l9 |4 e
- rt_size_t size = 0;# X/ O+ _( S/ x7 O+ @
- " B _2 q3 p# l U ]8 P' B
- buff[0] = reg;
5 n; r8 S* r+ U" @+ x/ J/ C. [
* e" P0 q$ {. T6 k0 A- V Q) h3 c- msgs.addr = KX224_DEVICE_ADDRESS_1E;
" r1 Q9 w) |+ w( I8 z' P - msgs.flags = RT_I2C_WR;
: A. Y( Q; Q' [$ ]! w# K - msgs.buf = buff;) k6 q6 U" a. ^) ]
- msgs.len = 1;$ @ ~% X5 m" M6 [$ x
0 `6 S2 u8 m$ X( k+ k; R! R- if(rt_i2c_transfer(bus, &msgs, 1))
$ V, k/ n7 {& ]1 D - {" h& K$ Z, h! L7 D
- return RT_EOK;0 R) f$ y1 m+ c. K& l* C: k
- }
6 i& h5 R0 Q, O' g" z* \ - else
" H+ R& r( b" X. F; s& Y! e2 M - {
0 v, e) @. d# v5 Z( g5 P - return -RT_ERROR;' x& z. t# h1 Q. h% p4 w
- }
# ? n7 W7 l6 c6 q" x - }$ W0 ~5 p( L% X$ [& w, z9 L
7 k; Y, R% h+ a2 T7 H+ |9 _. H
. p7 l* X5 {" J! Y2 I% a- static rt_err_t red_reg(struct rt_i2c_bus_device *bus,rt_uint8_t len,rt_uint8_t * buf)
( @' E# j0 g( P2 c7 N9 T1 U+ c( m - {
- b8 N, s# F% C7 r- m) C4 J9 l - struct rt_i2c_msg msgs;
1 _% D- [) j) L5 E+ ]0 X2 y$ v - rt_size_t size = 0;
& D" }4 ?/ B0 @% U/ s - 9 A5 @5 C A: g+ `' e1 ~
- msgs.addr = KX224_DEVICE_ADDRESS_1E;$ P' d% `. |/ Z2 d# _7 j
- msgs.flags = RT_I2C_RD;
( k! {; B; ^3 V1 L - msgs.buf = buf;9 u/ a. F! \6 P/ L8 ? E3 d
- msgs.len = len;0 H. B. n4 {6 i7 N" w T4 d
- 4 u: m) Z0 D: c5 S3 V
- if(rt_i2c_transfer(bus, &msgs, 1))
/ b$ w0 p- M5 m' ]( |9 X6 ] - {9 r, o& g, `* x4 Z: B
- return RT_EOK;
* I7 ]5 m: p4 j% E4 t+ i+ V - }
$ ? J" g; I. F& x7 j - else) E. o; {% o6 ~ I' R
- {
. K0 x) [9 p5 K/ `5 }# M+ z; ]8 u - return -RT_ERROR;
E8 A" i+ d8 z% R2 }0 P - }
' k6 k9 ~& }9 n - }
复制代码
- R# k O& ^7 }' U |. l) {4 a ( \: i6 [1 T; ^/ U- |* Y
下载运行后发现能够获得数据了,数据的准确性后续在进行研究。
* e) D6 C5 i& F9 m' U# l( \# X, L8 T ^* U( A
! J. v: O6 o% X- ^, w" E, ]* }, j4 t q
' Y- O! G- X' K$ t7 o& ]. t
' l3 [3 `9 r* F. U. S. P
2 Z& Q( z0 |0 v( P0 p5 p. h; l
& ?( u2 X7 r$ F- m( b) r6 x* V
! U6 c0 B9 M% p, C" b |
金币追加的速度啊, [. ^! A: ^0 Z; i2 C