STS-31介绍1 I7 y1 |' p: c0 e. S
详细参数请查看官方数据手册。
F6 A( a! e _2 M
. _) o5 ?9 ]- O, T7 M' t
/ p' |0 Q! {7 [# }* e, k3 S/ y. T* C
驱动源码: m7 |& g8 K- V3 g
本驱动是基于软件模拟I2C库设计的,利用了它提供的I2CDevice_Struct数据类型以及I2C通讯所需要的接口。
% o6 ]. g) Q9 e0 x+ y2 Q# n* B! U* N/ N+ _
头文件
+ m6 m" u% O+ D; Y$ Q2 D" a+ g- /*2 \1 b7 V) |5 N
- * sts31.h
3 X8 W' {4 Y5 n) s4 d& G - *
( p, c' U' ?% _( T% x0 T# l - * Created on: Jun 2, 2020
" J0 d( g/ j# ?' R- ]8 C - * Author: 81001
1 Z3 C1 W( {8 ]6 p) J8 p' W - */ y R7 c: y6 x* a9 @0 A# F
+ v) L( n* B: t( b8 N- #ifndef SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_& A* J/ u0 L/ q( H9 t/ J
- #define SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_+ P/ R9 M r" b% Q" _6 A
- H& m3 ]7 Z, W% x$ z: O7 a8 f- //#ifdef STS311 H# W; s2 Y$ Z+ m( u% T- u3 @
- #include "sts31.h"& n$ D5 f( _- n/ Q0 O$ ~
- #include "i2c_virtual.h"
+ _ Q7 P! o3 x* Q, {8 t% y
# H1 k6 y( N2 E* E$ E/ Z) f) Q- //Define GPIO for STS31: j5 M- ?$ h7 v* `
- #define STS31_1_SCL_PORT 'E'
: r. v* q, t) @' B - #define STS31_1_SCL_PIN 3
; K3 _* J' Q: _) ~ - #define STS31_1_SDA_PORT 'E'
. k0 v# @" m0 s' {- A: d! J; G - #define STS31_1_SDA_PIN 29 _8 ~( F3 G* l; n3 F" n
, _: c3 ^0 ?) y# E: Q- #define STS31_2_SCL_PORT 'E'
- \. D* a" k" X1 @ - #define STS31_2_SCL_PIN 67 n) l% _: p( @$ m ~8 U
- #define STS31_2_SDA_PORT 'E'
7 P, n9 p1 ~% A, d1 R - #define STS31_2_SDA_PIN 5& h1 m. E) C1 h' A- T1 O
- . w! e7 F M( J. X
- #define STS31_3_SCL_PORT 'F'
; W4 x* F( | F f2 ^ - #define STS31_3_SCL_PIN 2
2 h& K1 O1 }& X2 L* S$ K g - #define STS31_3_SDA_PORT 'F'4 w' G/ ]# U8 A1 ?
- #define STS31_3_SDA_PIN 1
% F2 y: b7 J; [7 l% u# V - $ [! {; e+ R( L: v) s& m
- #define STS31_4_SCL_PORT 'F'$ P% H6 N8 J. J* `9 S# |% r
- #define STS31_4_SCL_PIN 5
+ f g4 A" f6 A8 w; }; ?8 @- l+ e - #define STS31_4_SDA_PORT 'F'
; @$ c7 }, K% G8 R3 A% l7 s! } - #define STS31_4_SDA_PIN 4! y( ]( D" \- w# e
6 h& q1 @# w$ l5 Z; C9 z$ A1 Q- #define STS31_5_SCL_PORT 'A'
. X2 N2 u/ ~9 L6 e6 Y8 B - #define STS31_5_SCL_PIN 2
/ p/ B( f0 H8 ]0 @6 e6 \ - #define STS31_5_SDA_PORT 'A'
9 ~7 R9 i% g5 X2 g - #define STS31_5_SDA_PIN 1$ i, s' S {5 B- R7 E+ B
* a* C4 Z: l# G: p- #define STS31_6_SCL_PORT 'A', _ s5 ]' n L1 h
- #define STS31_6_SCL_PIN 6# y- V. |+ D/ V$ \7 T8 b
- #define STS31_6_SDA_PORT 'A'! _, o4 J5 W- D( z
- #define STS31_6_SDA_PIN 5' M# S" O! u$ B8 a+ Q* a% j
: q+ A) J$ j9 I0 U r2 Y- #define STS31_7_SCL_PORT 'C'7 N1 y, R d3 k: J/ }2 \
- #define STS31_7_SCL_PIN 5- F& D: p) k' ^: k, V0 F' X. u
- #define STS31_7_SDA_PORT 'C'/ G& I5 }5 j- z! p2 X8 t9 l
- #define STS31_7_SDA_PIN 4: l5 m7 V; A* g" A8 u& {2 U7 L/ B2 }
- ; i* L, g8 W7 @& a9 c& X# d
- #define STS31_8_SCL_PORT 'F'
1 i/ G+ Z0 ?8 p! Y% v' z# u - #define STS31_8_SCL_PIN 15
& u' H; X( B/ V - #define STS31_8_SDA_PORT 'F'
' l+ h: T2 Y' C! T# s; N - #define STS31_8_SDA_PIN 14& L9 D6 s4 L6 n: y
- + C; z& ?; Y/ J; v3 ]' d( ]
- #define STS31_9_SCL_PORT 'E'
. k7 y% s4 S0 i - #define STS31_9_SCL_PIN 7
% y& q) B7 Q* Z5 `) P - #define STS31_9_SDA_PORT 'G'. G% e3 Z- w w' V) q
- #define STS31_9_SDA_PIN 1" v( [' v* h% b6 G8 z
- , ]7 f( D- R+ m7 e
- #define STS31_10_SCL_PORT 'E'
& H ~8 _, @; a" B - #define STS31_10_SCL_PIN 12( d+ Q: w, Y, O2 f* Q+ {" {
- #define STS31_10_SDA_PORT 'E'3 r2 H2 x7 w" q6 r) R: H' z$ x
- #define STS31_10_SDA_PIN 11# j% R# p7 j }& P7 [
- [' t0 {2 |) m8 ~/ z: s- #define STS31_11_SCL_PORT 'E'4 W8 H6 k! Q8 I* n* b" G; j. v$ Z# Y8 [
- #define STS31_11_SCL_PIN 15, F" B6 ]- o' j& ~7 ^% {. w
- #define STS31_11_SDA_PORT 'E'( P' \* q9 \7 j5 R
- #define STS31_11_SDA_PIN 14
" B$ P6 ~9 J% h+ }3 C0 C - 1 R5 ?, [- l, o4 Z9 C3 [
- #define STS31_12_SCL_PORT 'B'
' b& I* s' b- ~( |# t# b - #define STS31_12_SCL_PIN 15( y2 J, y% W- C% @, n% ~' W1 n
- #define STS31_12_SDA_PORT 'B'
$ ?) J; G) m& g1 b3 I6 i$ P - #define STS31_12_SDA_PIN 14
9 U& i0 l4 @# z) s e2 S( U# b: I
5 J) t2 W B& a0 |! b) q& [- 3 B) C* J7 m- I6 a
- #define STS31_ADDRESS_0 0x4A //ADDR PIN ->GND
+ w, n9 i5 U9 b. u - #define STS31_ADDRESS_1 0x4B //ADDR PIN ->VDD6 v2 Q( Y2 ~: N9 S; l4 n% @1 I' w
- 0 y$ P/ v2 J. d/ q/ c# I8 ?. N
- //*************ADDR Initial********************/
! h7 R, G( D5 I: j- x7 q7 j - #define STS31_ADDRESS STS31_ADDRESS_0 //ADDR PIN ->GND
4 y1 x2 ]1 M$ G# B( K6 X - #define STS31_ADDRESS_W (STS31_ADDRESS<<1) | 0x00 //write address; S& K' _% ]# D& C# B8 I6 @2 d
- #define STS31_ADDRESS_R (STS31_ADDRESS<<1) | 0x01 //read address7 J: y5 N# @' v" \! E* j
- A: d% F' d& W# p
- //single shot mode4 K8 j4 g+ \, ?/ n3 x% _
- #define STS31_SINGLE_SHOT_MODE_HIGH_REP_EN_CLKSTR 0x2C06s
_+ d' p3 q" o/ B6 S - #define STS31_SINGLE_SHOT_MODE_MEDIUM_REP_EN_CLKSTR 0x2C0D! c( @- t' M8 p- d" n! ]4 M' J0 x x1 m& E
- #define STS31_SINGLE_SHOT_MODE_LOW_REP_EN_CLKSTR 0x2C109 N8 }! K+ ?) A w* E+ ~
& @4 P3 |" P; I* ?6 v) w! g: t- #define STS31_SINGLE_SHOT_MODE_HIGH_REP_DISEN_CLKSTR 0x2400
: G' O# Q, O2 W; O7 G - #define STS31_SINGLE_SHOT_MODE_MEDIUM_REP_DISEN_CLKSTR 0x240B c) G/ n, s4 R% {
- #define STS31_SINGLE_SHOT_MODE_LOW_REP_DISEN_CLKSTR 0x2416
% ^1 e/ ~! s/ o
: F0 d* v7 H8 K! e- //continue mode
6 }' d2 X- K2 [ - #define STS31_CONTINUE_MODE_HIGH_REP_05MPS 0x2032* o% P1 E! F% Z' p- T( [2 \
- #define STS31_CONTINUE_MODE_MEDIUM_REP_05MPS 0x20245 ?% D# h0 d- G2 H Z. g6 j
- #define STS31_CONTINUE_MODE_LOW_REP_05MPS 0x202F
7 B1 R' Z4 Z* r3 |8 a+ ?; Z- p - 9 `* z$ ], [" ~# b
- #define STS31_CONTINUE_MODE_HIGH_REP_1MPS 0x2130. V" u+ ^9 B- ]
- #define STS31_CONTINUE_MODE_MEDIUM_REP_1MPS 0x21269 U* I2 v3 {" ]$ _+ w" P
- #define STS31_CONTINUE_MODE_LOW_REP_1MPS 0x212D t5 p0 u! o) B. r; d; M7 ~
( R$ ?0 X. [) R# c- #define STS31_CONTINUE_MODE_HIGH_REP_2MPS 0x2236
: l; M5 J2 O& C+ c, b - #define STS31_CONTINUE_MODE_MEDIUM_REP_2MPS 0x2220& c; m& h( c6 l; O
- #define STS31_CONTINUE_MODE_LOW_REP_2MPS 0x222B* l5 Z) c" u1 e& O; Y* L5 `
- " `- U5 s0 R& d* s! Y; R/ g
- #define STS31_CONTINUE_MODE_HIGH_REP_4MPS 0x2334
* p4 s; W! O5 |8 _% G - #define STS31_CONTINUE_MODE_MEDIUM_REP_4MPS 0x2322
" }; A+ L- W! V( d1 o- W% i - #define STS31_CONTINUE_MODE_LOW_REP_4MPS 0x2329
4 R" y$ R/ {) z1 e: V$ i - 2 Y1 z/ Y/ {) G/ u u$ Q- x1 S
- #define STS31_CONTINUE_MODE_HIGH_REP_10MPS 0x2737
/ W* L" H& h. U, Y, Y - #define STS31_CONTINUE_MODE_MEDIUM_REP_10MPS 0x2721" p8 T! ~) T a/ H# d# C: |
- #define STS31_CONTINUE_MODE_LOW_REP_10MPS 0x272A
. j2 p" Q$ @: r" n
. I0 d$ j/ }' B* B. m( L- #define STS31_FETCH_DATA 0xE000 S# ]5 t) M0 P: Q* g, M. b( B
# I2 K! z; _! J2 }- //Break command/Stop periodic data acquisition mode
, `4 y) G8 Y6 J1 u' q6 C! m5 L - #define STS31_BREAK_CMD 0x3093: R! l. B- c7 p' U2 \
- $ C. M; j- o4 _0 A0 _( ?
- #define STS31_RESET_CMD 0x30A2, O6 Y6 D& P! i5 J2 [ c5 R' C
- #define STS31_HEATER_EN 0x306D
6 Z! H8 c3 s' F6 ^) _4 ` - #define STS31_HEATER_DISEN 0x3066
; X7 [6 j/ a$ ^0 {0 o' Z' s - #define STS31_READ_STATUS 0xF32D
^. H8 u" |0 J, _) x7 v9 y+ r - #define STS31_CLEAR_STATUS 0x30415 ~# `) f) U0 z. `5 U, \) W0 E
: P5 d* H$ E' n6 M- #define STS31_DEV_NUM 12
" B4 F8 e! e: Y+ u- t6 W3 i8 e - % q3 e6 k W2 M" D+ ?
- . q0 v% |6 W2 a$ S- O7 t+ J
- typedef I2CDevice_Struct STS31_Device;
# |. K2 v& X+ }. ^+ g$ l- t$ o1 J - - L! D5 m) ]% L2 S' q) w- @
- extern STS31_Device STS31_DeviceArray[STS31_DEV_NUM];% M b% L7 J4 Q2 N* X
- & a% E ~4 H' ]( D6 E
- " Z0 w1 H) D8 o3 U! T: \
- uint8_t STS31_Init(STS31_Device *sts31Dev);
4 K, Q0 u% J Z+ h+ ?$ ]1 M - void STS31_InitAll();+ b" y5 _; s0 @+ Z \
- 9 |) j) ?. q$ q! [+ C& L
- uint8_t STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp);
+ O5 E2 ^$ i' t! D+ x5 u - float STS_GetTemperature(STS31_Device *sts31Dev);
1 n, X# V4 Y p, e* N5 t4 l. a - 4 ^, |; ^" g* L
- //#endif* m$ _& u' `1 O$ u- H6 E. p
- #endif /* SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_ */
复制代码
' O) E' N+ r l: z- z' D1 V) H源文件$ n. }1 u3 r8 i$ p4 ]
- /*8 l& X. }% C3 t8 U3 u- o
- * sts31.c- I$ [4 ^ V' B$ F2 y
- *1 e% Z* k$ U! O8 K1 Q e
- * Created on: Jun 2, 2020
: L9 s7 k+ ]9 `% F2 ]; F9 M - * Author: 810019 _: ?7 _$ M3 f0 A, a/ j( ?/ _# G* \* c- V
- */
; i; l( o8 h7 p, ^$ t& l; a) L - #include "sts31.h"
* E* s5 {/ P0 M% t$ X2 Z E2 m# J# f - #include "check.h"/ ^9 p9 |8 g+ y
, j" L' \- u5 D9 n- N( E0 h0 K- STS31_Device STS31_DeviceArray[STS31_DEV_NUM]=" M/ {3 d) M$ k/ Y4 w
- {
5 u1 R" W w S% }* a+ E3 Y2 a - {.port = {.SclPort=STS31_1_SCL_PORT,.SclPin=STS31_1_SCL_PIN,.SdaPort=STS31_1_SDA_PORT,.SdaPin=STS31_1_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},9 O3 s, P4 }, z1 f
- {.port = {.SclPort=STS31_2_SCL_PORT,.SclPin=STS31_2_SCL_PIN,.SdaPort=STS31_2_SDA_PORT,.SdaPin=STS31_2_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
9 p6 ]4 }2 A: R8 q! T6 S6 y. M - {.port = {.SclPort=STS31_3_SCL_PORT,.SclPin=STS31_3_SCL_PIN,.SdaPort=STS31_3_SDA_PORT,.SdaPin=STS31_3_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
+ x" ]: {: V5 |" d4 t - {.port = {.SclPort=STS31_4_SCL_PORT,.SclPin=STS31_4_SCL_PIN,.SdaPort=STS31_4_SDA_PORT,.SdaPin=STS31_4_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
8 M, `& T2 m1 N# e$ Q$ z - {.port = {.SclPort=STS31_5_SCL_PORT,.SclPin=STS31_5_SCL_PIN,.SdaPort=STS31_5_SDA_PORT,.SdaPin=STS31_5_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0}, X1 r5 ~8 c) ?/ b8 e3 B# S5 G
- {.port = {.SclPort=STS31_6_SCL_PORT,.SclPin=STS31_6_SCL_PIN,.SdaPort=STS31_6_SDA_PORT,.SdaPin=STS31_6_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},5 ^- Y7 q8 T o
- {.port = {.SclPort=STS31_7_SCL_PORT,.SclPin=STS31_7_SCL_PIN,.SdaPort=STS31_7_SDA_PORT,.SdaPin=STS31_7_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
% I$ U) ]- G2 T% Q7 w8 g1 m4 @ - {.port = {.SclPort=STS31_8_SCL_PORT,.SclPin=STS31_8_SCL_PIN,.SdaPort=STS31_8_SDA_PORT,.SdaPin=STS31_8_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},- j% ^* U& t% A8 I9 e
- {.port = {.SclPort=STS31_9_SCL_PORT,.SclPin=STS31_9_SCL_PIN,.SdaPort=STS31_9_SDA_PORT,.SdaPin=STS31_9_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
* ~' p+ b/ R" q, ? L% r6 q - {.port = {.SclPort=STS31_10_SCL_PORT,.SclPin=STS31_10_SCL_PIN,.SdaPort=STS31_10_SDA_PORT,.SdaPin=STS31_10_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},* l0 G& l* \4 b4 W( u& r# f
- {.port = {.SclPort=STS31_11_SCL_PORT,.SclPin=STS31_11_SCL_PIN,.SdaPort=STS31_11_SDA_PORT,.SdaPin=STS31_11_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},! x' g$ a$ g: `. V; J/ q/ q
- {.port = {.SclPort=STS31_12_SCL_PORT,.SclPin=STS31_12_SCL_PIN,.SdaPort=STS31_12_SDA_PORT,.SdaPin=STS31_12_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
! Q3 d$ n {* w& p) u - };4 o |! q5 E* t3 _0 ?( l: `0 O. o
# ~) D$ g1 D# q# Q }9 g0 g- ) s, X/ @. u1 ~8 b3 U; M7 @
- /**
6 g& Q9 ~5 F1 ]4 E- ?) `1 W& h - * @brief 初始化STS31温度传感器5 d' Y6 `, \) K8 z4 o, u1 e& K E) W* P
- * 由于STS31温度传感器需要初始化后才能工作,因此需要在读取温度之前调用此函数。* D) O8 N; I0 t$ Y5 b" w
- * 考虑到设备不存在或者通讯出错等因素,需要验证初始化设备是否成功。8 f% ?) Y0 d. F. c
- * 有两种方式可以完成验证:1. 获取此函数的返回值 2. 获取STS31_Device的devStatus成员的值。; Q" f7 L9 Q4 r3 ]2 U5 ~ ^/ B2 y
- * 推荐采用第二种方式验证是否完成配置。此值也可用作STS31的插拔检测。6 K7 |- o `4 z7 p7 |1 p* N+ p
- * @param sts31Dev: 需要初始化的I2C设备
# {' m ?* y B4 ~& A4 ~0 b - * @return 初始化的结果(0:初始化失败,1:初始化成功)
7 |0 T7 D% s/ A4 b M* e& W D - */
( A- I2 X* F7 S9 F - uint8_t STS31_Init(STS31_Device *sts31Dev)! }/ k& m) X Q8 n* Y
- {
G( d6 n {0 q6 Y0 P9 ` - 8 a) |! C K( V
- I2C_Virtual_SetPin(sts31Dev->port.SdaPort, sts31Dev->port.SdaPin, sts31Dev->port.SclPort, sts31Dev->port.SclPin);
+ w6 j7 v* E7 b
, O1 n/ `! _, N. r/ I" H8 A- I2C_Virtual_Start(); //启动总线& r' x# k9 M+ d4 l
- I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x00); //发送器件地址(写)
! A" U. k" T, t5 ]7 O - : P3 ~; C: H: R$ {/ Z, g
- if (I2C_Virtual_ack == 0)1 V1 L# j! ]# m* C* G4 \- g( ~- e
- {
( E, Y$ C* w. K: e - sts31Dev->devStatus = 0;5 r- P4 {& N0 u. `3 d# i
- return 0;- A7 h) [/ z' ]7 Q2 [1 ]- d4 q
- }: e# k: z0 k9 b5 I9 d2 ]% Y
- # g3 a4 @2 [. s5 J r
- I2C_Virtual_SendByte((STS31_CONTINUE_MODE_MEDIUM_REP_2MPS >> 8) & 0xFF);
5 _% A$ b6 @/ ] @ - 3 s$ k7 z6 m) T) ]) x
- if (I2C_Virtual_ack == 0)
$ {- Y- G7 l M3 U) N - {
# |6 Z% I2 ^6 m1 B' _/ h; G - sts31Dev->devStatus = 0;6 n" p9 W/ C4 x0 K9 G2 K
- return 0;
0 M1 v+ R/ r% d/ U- T& G' j) r# f - }
; A$ X+ h5 K. A$ w" ` - ( n4 L4 }" R1 x" U* s
- I2C_Virtual_SendByte(STS31_CONTINUE_MODE_MEDIUM_REP_2MPS & 0xFF);
, K2 k/ d' M3 s S$ M) B8 ` - / Z7 ^1 S# L0 f) a3 R
- if (I2C_Virtual_ack == 0)
! K S8 F2 P0 Y+ O3 D/ R# b. o4 r - {! M! T8 I( M4 C0 R6 i$ j9 q
- sts31Dev->devStatus = 0;7 Q) }1 Z7 c. G& `: v* K2 I, s
- return 0;, ^) R: E5 R" w4 E
- }! B3 V* P) }, s) H) {+ V6 M
- & b- N' b; v. C" \( d3 T
- I2C_Virtual_Stop();
- H: w! x" C$ |2 O - / U- U1 Y7 D. ]
- sts31Dev->devStatus = 1;5 M4 J" u# ~ C- |) B1 ?
- return 1;
- l8 T6 d3 g5 a! P - }
6 h% |9 F6 y- h3 j+ `/ h$ P$ l
) ?' A, z. z( s- B6 g/ t
+ [. } I& J+ m6 K" l) x9 |- /**
( n1 w( d0 @ o - * 将STS31_DeviceArray中的成员依次进行初始化
/ j2 M! P1 a$ {9 a% [- [! ] - */3 B* ?% N7 {5 r4 A
- void STS31_InitAll()
& n, [, }& S% V - {* Y" F, n1 C2 h( o9 G0 J8 x
- for(uint8_t i = 0; i<STS31_DEV_NUM; i++)& B$ y; J: p- t1 S- w
- {
% M9 ?' J+ D M- N6 p - STS31_Init(&STS31_DeviceArray<i>);' T# N' x: o; g, p* p3 z( L' d; n
- }& O. o& }* I' ]$ n
- }
8 z h- a: Q& K - / p+ w8 | O, `
- 4 U w2 @# x# i i( a. ~; R5 z
- /**7 b4 t% x0 w8 Z# w0 U2 K2 k1 s* |) E
- * @brief 读取STS31的温度原始数据
6 g& x# l1 ]8 H. r1 L7 s - * @param sts31Dev: 需要操作的I2C设备8 I& j: f) E# n e
- * @param dataTemp: 传入需要读出的数据缓存地址(3个字节)
! @9 \- g# z, ~- } - * @return 读取数据的执行结果,0:读取失败;1:读取成功5 w3 d" K+ R5 p
- */
( z( Q3 d0 z& k5 F$ W* m a - uint8_t STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp)
. {% y2 l- H8 ^ - {; x) `$ @& u* |3 ^9 p0 p4 t" j
- I2C_Virtual_SetPin(sts31Dev->port.SdaPort, sts31Dev->port.SdaPin, sts31Dev->port.SclPort, sts31Dev->port.SclPin);
7 [+ [( o( t* F& l$ p, i
! U w m/ U$ o0 Q# h) l+ }/ N" @7 W- I2C_Virtual_Start(); //启动总线/ b, c2 d( \3 G$ v: X
- I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x00); //发送器件地址(写)' @4 J$ B" m! u
/ O: l& M5 s" w, J6 }- if (I2C_Virtual_ack == 0)
% O- g p6 w% I$ L$ a" | - {8 |0 i/ j9 q: X+ [2 ]$ }0 Z4 F
- sts31Dev->devStatus = 0;9 n- Q& Q5 ]2 d. T5 \
- return 0;0 m6 D/ T5 g. d- N
- }
# C0 Y* v1 A/ Y1 x* f - ) b3 x" d1 g, v) j
+ e" k! [+ m# M1 l- I2C_Virtual_SendByte((STS31_FETCH_DATA >> 8) & 0xFF);
) }8 z. Q* O/ J# i
4 E0 z n* J4 X0 [0 w- if (I2C_Virtual_ack == 0)) t+ A4 j+ o% S) r* n5 h7 f" K4 v/ K
- {
8 k# d! T: Q, c* I4 K - sts31Dev->devStatus = 0;. W$ t! F1 C% d
- return 0;0 Z: }' n5 _* x v
- }
( k5 n1 z; Q" V+ s4 `
) E6 w. S. m* N. M4 ?3 z9 b! c' C5 g- 6 r2 B H$ P# N: G/ l
- I2C_Virtual_SendByte(STS31_FETCH_DATA & 0xFF);5 H( m3 N! T7 L4 @0 Z8 a( P
- $ A4 G! }: V" ]# h* ?% n; T
- if (I2C_Virtual_ack == 0)0 H# C; |: |+ j% ` d0 f& Z
- {) D3 `- x8 O7 b' G; v
- sts31Dev->devStatus = 0;
3 u/ Z7 o3 W0 V- x. ^- D) N# m - return 0;
4 L, t/ r, f4 d3 | - }
' x! |2 i) ?! p
. v& T. f8 S& c' u- I2C_Virtual_Stop();" H# M9 {/ h; Q4 s. z$ }% D9 {" y
- 7 Z' f$ ^6 p, |4 l2 O
- delay_us(10);1 H4 c* \ t" t' V
9 e2 l( f: Q" U# O- I2C_Virtual_Start(); //启动总线
# }- H V# ^, y+ {8 ~4 }9 C - I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x01); //发送器件地址(读)
i* N/ m" q0 p, u - 1 j L7 {2 {% z6 {% C
- if (I2C_Virtual_ack == 0)
- c' Z: N( x2 u- E - {
* y! Z6 _8 Q) A; d9 G+ B3 R& V - sts31Dev->devStatus = 0;
: y5 Y" ], t2 b; H* j' e" j5 o - return 0;
! r/ y0 G( M4 I: G3 b D - }
* i% v o1 l _6 O* J9 w# T% d
) ]& U, ]0 L$ U5 w* h3 B5 J- dataTemp[0] = I2C_Virtual_RcvByte(); //接收数据0 u% u7 H" e5 z' o
- I2C_Virtual_Ack(); //发送就答位
) A" j9 y! U5 B
0 p; I: {( J/ M/ ]7 f/ p. ?5 n- dataTemp[1] = I2C_Virtual_RcvByte();
( h ^0 O' T1 h( P2 M2 l - I2C_Virtual_Ack(); //发送就答位
6 ?, F4 e6 w6 m* u5 U' |! R! b
7 V; V; y9 I7 r" d6 S- dataTemp[2] = I2C_Virtual_RcvByte();3 }' M* H6 s4 a% t
- I2C_Virtual_NoAck(); //发送非应位$ s" G" e. A) N4 M2 b5 c
: m+ J& e% r+ I9 _* ~" J' b- I2C_Virtual_Stop(); //结束总线& X+ ?% N- X( W4 E( G: l
- + `1 ^& x$ t: Y) A) ~0 ]& u. H
- sts31Dev->devStatus = 1;7 ]) J; i F6 w; A
- return 1;5 Y+ z% ~+ x' _
- }
, e4 V) g2 ^' j2 o9 e" O7 Q
7 U! g) |: s5 N
& d- @: H4 N7 l7 l s6 e- /**
$ N' s* T% d3 K1 g. { - * @brief 读取STS31的温度数据
* n3 Z3 W" }- F$ k9 | M - * 由STS_ReadData函数进一步封装得到,需要特别注意的是,如果读取出错将会返回919。; N, a0 a3 r4 n, I2 l6 b' G; W
- * @param sts31Dev: 需要操作的I2C设备
) N) \* r# p) e. w; \* W3 V - * @return 温度数值(float类型)1 I4 @5 \/ M4 L- S) F$ U
- */
2 x4 W/ l9 S4 S8 H! v$ T - float STS_GetTemperature(STS31_Device *sts31Dev)2 \! }/ n% w X" B9 x1 s0 V
- {# U7 J8 X' C7 E. h
- float data = 0;
" W, O3 b* G: h' e. W: B# @ - uint8_t dataTemp[3] = { 0 };9 }( \6 Z" R! e. _; V, u
7 `0 L S# Z1 L% s# p2 N- STS_ReadData(sts31Dev, dataTemp);4 M0 y! ]7 D, q
5 z! y/ F; q6 J# @3 q( e- if (CheckCRC8(dataTemp, 3) != 0)
0 v% n9 l0 q0 g - {
( G1 b$ t' h4 m! F/ ^ - data = (-45 + 175 * (dataTemp[0] * 256 + dataTemp[1]) / 65535.0);, ~) d# F8 P* i/ ]* w$ ~
- }
& X1 j: B0 x8 ~; L% U/ L - else
' J# F& ?; A C Q - {
. [9 x5 L( i' d' t - data = 919;
3 l; k7 t( n- F - }& ]3 w2 D- Y8 `0 ~$ s
- ; ^2 b4 M* y. {# j' c o7 x4 B
- return data;
6 O3 \8 i; i9 r- p$ a - }</i>
复制代码 % h7 ]& a8 C4 ]2 J" m0 v* ]
应用指南1 p- n: y& q5 Z. _6 w6 u
定义并初始化设备结构体变量( s8 E5 v* Z( |4 V, x" W2 F
- #define STS31_DEV_NUM 12
. B* E8 p- |0 N - typedef I2CDevice_Struct STS31_Device;
6 }! w, G* o0 X/ e7 U. U
. D4 b7 f) t, E& J' a" }' X- //Define GPIO for STS31
* X: g2 E/ c9 {- l2 `0 j$ k, s4 Y2 [ - #define STS31_1_SCL_PORT 'E'
4 L) y. s4 k* \" C6 u7 _& | - #define STS31_1_SCL_PIN 3 k2 ]& D4 c. S9 w4 ?; U
- #define STS31_1_SDA_PORT 'E'1 ], G0 S- Y1 Q
- #define STS31_1_SDA_PIN 2
7 D8 Q$ q+ D% a' r2 _ T5 I- X5 x - 7 V. K1 L" J& g6 ^: u3 e( m
- #define STS31_2_SCL_PORT 'E'/ g4 D' {) a/ i) B( V* M0 ]
- #define STS31_2_SCL_PIN 6
# @9 Q! r7 \. M/ N - #define STS31_2_SDA_PORT 'E'
$ \; j, u( i! a [) Y- V( P& I7 K - #define STS31_2_SDA_PIN 5
% a5 `5 ~8 H- `0 P) D$ q2 s" b - & M6 i1 e4 ~! o. o4 Q5 O
- #define STS31_3_SCL_PORT 'F'. I/ {3 z( K5 L: r6 Y
- #define STS31_3_SCL_PIN 2* h/ P5 P: ~: l; H! c+ `5 `
- #define STS31_3_SDA_PORT 'F'% G- ]3 J* o# t& ?# F8 l& R+ b
- #define STS31_3_SDA_PIN 1- @2 j) D6 x) \( T1 \2 l# x
- & c8 i8 k- A7 O( F
- #define STS31_4_SCL_PORT 'F'5 r# T( v$ P8 q7 l! c' X
- #define STS31_4_SCL_PIN 5
- w' |/ o3 Q7 w2 M3 l' ` - #define STS31_4_SDA_PORT 'F'
E) c, T, Y# j- T - #define STS31_4_SDA_PIN 40 Z: K( E' x! g- ?" F V/ t9 l
) @+ |$ G6 T; y- z5 f: V% T: a- #define STS31_5_SCL_PORT 'A'4 \5 H- @% {) X' b/ g
- #define STS31_5_SCL_PIN 2
7 {& ~* j: s3 s2 ^) {( Z - #define STS31_5_SDA_PORT 'A'! @: Z6 \2 L" U# U1 i4 r
- #define STS31_5_SDA_PIN 1
: F9 s' P# `" a7 j2 G% y# a - 5 k7 N2 b/ x, C( J* W# ?
- #define STS31_6_SCL_PORT 'A'5 |# ~- d1 c1 e8 w7 I
- #define STS31_6_SCL_PIN 68 t& Z9 q5 ?1 K( ]6 s
- #define STS31_6_SDA_PORT 'A'
1 z) Y8 Z+ f; p L+ b( ` - #define STS31_6_SDA_PIN 5
& W5 x$ g/ a+ `; t, q) ] - ( g, O/ `9 T! l
- #define STS31_7_SCL_PORT 'C'$ E9 H( D& c9 o1 ^5 k. i6 k
- #define STS31_7_SCL_PIN 5
9 M T: S- _/ W( ]% C - #define STS31_7_SDA_PORT 'C'$ d5 v" ]3 v2 ~% L% r8 B* H, B" _
- #define STS31_7_SDA_PIN 4
" X" H3 T w: c5 v( `
( n* n( M4 ]% l" e- #define STS31_8_SCL_PORT 'F'
+ V6 \- I6 u ^ - #define STS31_8_SCL_PIN 154 l' v- r; M8 {* O
- #define STS31_8_SDA_PORT 'F'
- O ~" ~2 B/ q' T K! f Y - #define STS31_8_SDA_PIN 14* {: {$ p9 f9 B0 H% s* y5 ]
- . h- y' ]7 @( Z/ d
- #define STS31_9_SCL_PORT 'E'
R. {' Y" B% ^9 C - #define STS31_9_SCL_PIN 7) r2 I) l1 X7 s& [. r! d' V" J
- #define STS31_9_SDA_PORT 'G'% h- ?7 n x7 M
- #define STS31_9_SDA_PIN 1
% V/ I P9 A( x' ` J - 2 t8 U' h4 n+ l, t; z
- #define STS31_10_SCL_PORT 'E'
5 _2 h- g0 F' a - #define STS31_10_SCL_PIN 12
8 }% M! E) s( H: J - #define STS31_10_SDA_PORT 'E'
& d9 E! M# a8 K4 p8 I- g0 W" x - #define STS31_10_SDA_PIN 11
: |5 t9 i" y7 m7 Z - 9 T( f9 A( W6 D, Y. U
- #define STS31_11_SCL_PORT 'E', U; w, z+ d! U
- #define STS31_11_SCL_PIN 15
2 y) K& @! |* K3 K3 G& ]* f" m0 j% v - #define STS31_11_SDA_PORT 'E'6 Y" s4 m* h. l! }; u
- #define STS31_11_SDA_PIN 14
# G6 ~6 H' U! o* L: f
6 L# j8 d6 R* e# ~2 l- #define STS31_12_SCL_PORT 'B'- w8 j1 b0 c2 o u8 }! H
- #define STS31_12_SCL_PIN 15
# ^# q0 I+ _8 f - #define STS31_12_SDA_PORT 'B' ^$ J/ }/ m: m3 c: T% Z
- #define STS31_12_SDA_PIN 14
7 x9 R* z* p8 ?; u- w, D' d
4 E& q2 j5 E+ W, P+ P- extern STS31_Device STS31_DeviceArray[STS31_DEV_NUM];6 g, b) G7 V+ p4 Y3 I
3 X; b8 ~3 n3 z/ U+ `- STS31_Device STS31_DeviceArray[STS31_DEV_NUM]=; S3 e; n$ i( U! x, S
- {$ ]" k+ O, A" r! T1 D
- {.port = {.SclPort=STS31_1_SCL_PORT,.SclPin=STS31_1_SCL_PIN,.SdaPort=STS31_1_SDA_PORT,.SdaPin=STS31_1_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},0 [; C: o0 k ]: E1 }9 ^3 W ?6 P% l
- {.port = {.SclPort=STS31_2_SCL_PORT,.SclPin=STS31_2_SCL_PIN,.SdaPort=STS31_2_SDA_PORT,.SdaPin=STS31_2_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},) _4 U& B) t. ~3 v
- {.port = {.SclPort=STS31_3_SCL_PORT,.SclPin=STS31_3_SCL_PIN,.SdaPort=STS31_3_SDA_PORT,.SdaPin=STS31_3_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},3 |: u8 e$ L0 C
- {.port = {.SclPort=STS31_4_SCL_PORT,.SclPin=STS31_4_SCL_PIN,.SdaPort=STS31_4_SDA_PORT,.SdaPin=STS31_4_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},0 U" [/ n9 ?) ^* E q' p! ^
- {.port = {.SclPort=STS31_5_SCL_PORT,.SclPin=STS31_5_SCL_PIN,.SdaPort=STS31_5_SDA_PORT,.SdaPin=STS31_5_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
5 H/ `1 c0 B) m5 _& l( ?% m$ F# D - {.port = {.SclPort=STS31_6_SCL_PORT,.SclPin=STS31_6_SCL_PIN,.SdaPort=STS31_6_SDA_PORT,.SdaPin=STS31_6_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},0 B4 a* c9 v! S0 ~
- {.port = {.SclPort=STS31_7_SCL_PORT,.SclPin=STS31_7_SCL_PIN,.SdaPort=STS31_7_SDA_PORT,.SdaPin=STS31_7_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
- U9 J6 q7 J' J. K8 {8 E - {.port = {.SclPort=STS31_8_SCL_PORT,.SclPin=STS31_8_SCL_PIN,.SdaPort=STS31_8_SDA_PORT,.SdaPin=STS31_8_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
2 Q2 M( _( G; w" F0 E - {.port = {.SclPort=STS31_9_SCL_PORT,.SclPin=STS31_9_SCL_PIN,.SdaPort=STS31_9_SDA_PORT,.SdaPin=STS31_9_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
: B e3 X8 U( \* y - {.port = {.SclPort=STS31_10_SCL_PORT,.SclPin=STS31_10_SCL_PIN,.SdaPort=STS31_10_SDA_PORT,.SdaPin=STS31_10_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
, N. }2 [* `0 j8 N - {.port = {.SclPort=STS31_11_SCL_PORT,.SclPin=STS31_11_SCL_PIN,.SdaPort=STS31_11_SDA_PORT,.SdaPin=STS31_11_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},8 a; K0 X/ V' z8 [7 ]- ~0 O. V
- {.port = {.SclPort=STS31_12_SCL_PORT,.SclPin=STS31_12_SCL_PIN,.SdaPort=STS31_12_SDA_PORT,.SdaPin=STS31_12_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},; G- f& f1 @" t- x
- };
复制代码
0 H3 z+ r0 h/ N$ X" S5 _% D配置STS-31芯片
) K- y( U& |6 S7 q在工程的合适位置调用void STS31_InitAll()或uint8_t STS31_Init(STS31_Device *sts31Dev)完成初始化。初始化函数按照默认的配置方式(STS31_CONTINUE_MODE_MEDIUM_REP_2MPS)对芯片进行初始化,如果需要其他的配置方式需要重写此函数。6 K7 ^! @5 u+ Q3 R( O2 f
: d+ h- k& ]3 Q- b% F$ P3 t1 \* I0 D2 F4 K
需要特别注意的是由于STS31温度传感器需要初始化后才能工作,因此需要在读取温度之前调用此函数。考虑到设备不存在或者通讯出错等因素,需要验证初始化设备是否成功。有两种方式可以完成验证:1 @1 z2 G& o& M x: S+ @
3 Z5 \1 M8 ~8 D" F/ j' m( D! U) S
1.获取此函数的返回值,0为配置失败,1为配置成功。
( C8 j& T# j* B \4 p$ i3 n2.获取STS31_Device的devStatus成员的值。
A6 A2 m7 N. y3 {- K推荐采用第二种方式验证是否完成配置。此值也可用作STS31的插拔检测,即当sts31Dev->devStatus = 0时,可认为通讯失败或者器件不存在,此时可以选择周期性的轮询初始化函数,以检测STS-31芯片是否恢复工作。. L$ T& a( D( ~0 |8 q
2 U+ ~) H: {/ }! R读取STS-31温度
N( O/ Q1 \2 I5 H5 C( W在工程合适位置调用uint8_t STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp)或float STS_GetTemperature(STS31_Device *sts31Dev)。后面的函数是对前面的封装,可以直接调用以获取传感器采集的温度数据,如果采集或通讯出错,将返回数值919。( P' l/ q& B6 o7 S
9 y/ N8 E7 h' ~2 c5 I! N特别说明
) }0 {' f2 j6 W$ e @, Y如果在PCB加热器上应用了此传感器作为温度的反馈,应该特别注意传感器配置与读取数据的有效性。当传感器失效时,应该及时的关闭加热器,以免温度调节失控。
9 |1 B' m f4 G6 E
, ?: b' `/ a; ~" \: q/ G2 x" B1 \7 c B' B/ a$ G3 P& p
1 ?3 n' p: e. {6 Z
: b# \: n% e8 e* `: i) u5 G. p
|