你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32G4 NUCLEO G431RB】+ I2C通讯终于完成

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:9 J, ^* u  i. q% z3 t8 ]: U! Y$ Z  S
I2C_Bus_Ok.jpg
; E5 }' ~# _1 T7 b2 \3 ?. O$ d6 ~' _6 T7 ^1 l) z: u. M' {1 d
    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
+ n7 o  H' ]8 C& h; B. i/ D
  1. /******************************************************************************************
    5 j$ c; |0 ?, ~: Q8 [/ r, }5 Q, }4 Y1 n
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size): R+ C! H: e  w* l' m/ q+ {6 B
  3. * 功能说明: 写数据到DS1307
    ) `" `- D. ]1 n
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)8 @: u1 y* e- {% w9 C' i
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误5 v; v1 s* x  k# U$ u$ N
  6. ******************************************************************************************/
    , ?( |6 C) w0 o- b5 Z
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    ) O! i- A0 c+ r  u
  8. {9 M6 K/ |7 g! v* |: X: [* ~
  9.     uint8_t addr = 0;0 K  U7 _( I7 Q8 w/ m
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
    7 c% U/ K. F8 x. _5 L, L% x" F
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    0 K  y' ~6 n  B7 t" `# i, I
  12.        
    : V# D6 O! @8 W
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)- u$ |8 ], `  u
  14.     {3 ^: _3 B9 G/ }9 R
  15.         return 1;
    6 q+ G/ z/ f: S# R) e- F
  16.     }3 j8 v, |/ p0 B& P, m
  17.         return 0;
    1 z: H, {. ]! P% B" Y# j8 f
  18. }: T) e% ?) g7 _5 S+ R

  19. $ T; U' V& n* n  e% A6 w- x
  20. /******************************************************************************************
    / s$ h; o* {" V, Z9 U/ j( `6 R
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    / t& Y- `3 f! G. s5 k
  22. * 功能说明: 从DS1307读出数据5 S/ j( N, b1 _0 \( Z
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)& w3 R' X3 J- Y- m; W! x' @# S6 E
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误" {& |6 C. B$ f- z+ o
  25. ******************************************************************************************/# Z0 C  u# b4 A1 W# v$ H/ n% M! @
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    ( L8 m) S- e2 h' y9 H8 Y
  27. {$ \& C" |& y* D% D
  28.         uint8_t addr = 0;, F! B( g7 ?' o6 P! D" ^: v
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址; D+ ~* X% d* L3 B  ^9 \- R$ {
  30.         # R7 V! ^) b9 \* i
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    5 Y8 t1 |/ e! A+ F, q8 \) J
  32.     {
    $ E" t& c. F& K' n
  33.         return 1;
    9 H; ~) }$ J' G) L1 p6 N3 F
  34.     }
    4 K. _& i: f4 l5 S: c) b3 a& ~
  35.     if(size == 1){               //检查DS1307是否需要初始化
    0 _% I. J: K& L
  36.                 if(DS_Buff[0]>127){- ~2 ^# ~6 A) `  V( `) b
  37.             year = 2019;
    , _) S4 s* p7 @6 Q; g
  38.                     month = 9;$ E" \; F7 E- O! |, ]  t; n  P
  39.                     day = 18;
    6 o+ J' c. ]8 s+ B  f( S7 Q
  40.                     week = 3;
    * z& r& y- w3 j/ _3 G" V$ O
  41.                     hour = 9;! p$ t! q1 p  B$ N0 j
  42.                     minute = 1;
    4 B& N) t+ y, u. |- }
  43.                 8 A- N  K% Y5 z! Q( K
  44.             DS1307_DataToBuff();
    * [% F& b* K2 d) q, ~
  45.                         DS1307_I2C_Transmit(8);7 Q# |6 Y! M" j6 I3 p3 r' [7 w
  46.                 }
    6 Z; [5 o5 O3 ~5 G4 i
  47.         }$ k! A7 g6 v8 W: u3 B; r
  48.         else{
    + C9 U( u! Y9 m% i  Z
  49.             DS1307_BuffToData();4 [2 C' F* E# Q7 Z+ n1 C. o
  50.     }
    / T' G9 _- V3 y7 [1 e
  51.         return 0;       
    , \+ Q1 {" Y& ]% w- w
  52. }
    7 e0 y* k  ~8 c5 K. ]0 @
  53.                  : v7 h. K$ _1 t& D" c. Z
  54. /******************************************************************************************
    / K; S1 _, i0 U! @" O/ u9 p
  55. * 函数名称: DS1307_I2C_Read()
    / M3 y& p5 J: W) _" D! p% y
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    * h2 J3 p- D2 J, H
  57. * 输    入: 无
    : e8 a! ~# t6 J9 |  n
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误+ D1 Z$ L# n3 A% u, J
  59. ******************************************************************************************/( u1 D" N# ^; H
  60. void DS1307_I2C_Read(void)$ v# j$ W! u' @7 r
  61. {
    ' [: s4 t5 f) t& \

  62. , v6 q$ j0 ^9 p- u( t
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    8 c' r: F% T) A! \3 n6 b2 b, T
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)7 ]3 O$ X6 F& `/ O/ m  Q5 Z; b
  65.     {
    8 y1 s8 b% g4 k
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)- L$ V% O! d) C' `- q0 U
  67.         {5 f2 Q4 U0 I; E- u' v
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");3 ~) P" S+ u! W1 T, w/ r
  69.         }
    ! z' a3 s! @! U+ O
  70.     }
    & L$ ~! g, q  x& b. e; m! D
  71. . t9 x, Y( c2 k4 `9 N  I& A2 d% B8 B' |
  72.         DS1307_BuffToData();' ]; m0 H' C- O7 Z- n3 L
  73.        
      p2 k0 U' a+ k* ~( h
  74. }' W5 V, I6 f; t" P2 K8 @

  75. 0 @  v' h/ a( x! N
  76. /****************************************************************************************** 7 S( @% g  ~5 q' ^8 P
  77. * 函数名称: DS1307_I2C_Write()
    . L+ y2 K! L# w* Y+ ^
  78. * 功能说明: 将当前的日历数据写入DS1307
    4 o5 a! f! b$ u
  79. * 输    入: 无
    $ Z: W# E: D, T; u- K
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误% Y3 J: D6 s: r+ R- y* _
  81. ******************************************************************************************/
    6 t' y! I: W5 y3 m
  82. void DS1307_I2C_Write(void)
    2 m7 Z/ k( r: f( n+ T) m
  83. {
    ! y; h8 L7 y* |) i* i& L3 b* T4 L1 w
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中( }) `: h5 J* t. B: y
  85.         4 n6 c$ q  _! x+ J& V" ~
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    : p* f, D7 c; B' I
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)- w; g* m4 d7 b9 R
  88.     {
    " R- S4 e) A6 u
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    + L5 ?" V) |! u' ?: Q* T0 l, c, C
  90.         {9 R3 l( y5 D9 y
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    0 g1 ~* I) }, y& h6 |! p9 S2 A3 l
  92. //                        return 2;
    / F/ W; }% x# |3 c% R8 g
  93.         }
    4 n' V$ G1 i7 v) L' P3 c( ~
  94.     }
    / B! u0 |2 p, S
  95. //        return 0;4 @7 i7 p9 Y) j- e
  96. }( T, O8 y/ r5 e, ~, s6 i

  97. $ |* F# C% A$ N( j, k+ G5 z* O
  98. /****************************************************************************************** ' L# y" S; l- G! I
  99. * 函数名称: DS1307_Chick()! K' e( \5 R# {$ a. {* \, D
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化& N$ Z# ?* }# a% }. f4 K3 _) ]
  101. * 输    入: 无
    7 F4 V9 t1 R8 M! W/ R& U
  102. * 输    出: 无: u8 Q* f( n1 ~. a; i$ P7 {: k
  103. ******************************************************************************************/* {. H) {. s0 E3 o; D; N
  104. void DS1307_Check(void)! r: I* c& p: j: B# X
  105. {
    0 u6 H0 f* d- H% V5 e! r

  106. - _: t3 K1 v) S. n" J0 c
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");6 b! V0 h- T8 W3 V, M. j
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK), K; \3 }, J2 K
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)6 Y% D* F' ^% l6 x7 j" J
  110.     {
    ! Q) i4 |, Q3 X& _. R6 `' D
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)* G" G6 r% O1 f. x
  112.                 {4 _- {7 Z/ B( X. Q; k7 s, z2 F! E( N
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");/ P5 v7 F. u% E, t3 p; T
  114.                 }
    % X( H2 M1 n% l! Y
  115.         }
    6 ?. O) }" a+ R
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
    ; A# R$ B3 G8 A( N% K* ~
  117.         if(DS_Buff[0]> 127){
    ' K& x: x# W5 E" W1 S  J4 Q
  118.         year = 2019;
    0 ]/ C$ d: h! X" k
  119.                 month = 9;
    $ r/ F' v2 ?: }: i
  120.                 day = 18;* P7 g6 b6 I) q. L
  121.                 week = 3;& M# J* E+ z0 r" |5 D
  122.                 hour = 9;: g7 m8 g) x8 Q
  123.                 minute = 1;
    % u3 ]% T) U6 O% @. D
  124.                
    + J* Y% x7 q5 \0 e
  125.         DS1307_DataToBuff();, C0 |5 m) c# ^3 V9 H
  126. , b: L+ U0 p: y8 h
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    7 {/ X8 c0 a8 X8 \/ o$ x
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    0 q# K$ F3 ^7 H' g  X* ~
  129.         {/ O5 Y4 \2 k5 K
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    1 S. D8 I7 B5 X+ V/ M0 z: o; ]
  131.             {
    5 _* L( u0 P) S- g3 N5 m
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");4 q$ D! n- l& _
  133.             }
    / ?5 f7 [0 C" q( t( i
  134.         }
    / ]7 A* F) C' q! ~: V; i* V5 R
  135.         }
    : {9 F2 B9 Z- Z9 V8 ?/ }. f, y
  136. }
    ; i6 }0 _0 q; H% A) \4 m; E2 m' Y
  137. ; w+ h1 m. T9 H+ @# T7 p, d) @
  138. /****************************************************************************************** $ c( @& E% B/ F( p/ v
  139. * 函数名称: DS1307_DataToBuff()* s( m/ P# |+ d/ T
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中3 J0 N4 F1 e3 j: Z8 i
  141. * 输    入: 无" w9 i2 c+ `8 \5 P8 I2 m6 k6 a
  142. * 输    出: 无
    6 j! Q; C6 j& i2 I* o5 u! G
  143. ******************************************************************************************/' I4 e5 n! _% c5 u) Y  V* U
  144. void DS1307_DataToBuff(void)% O( s3 z+ c( |. b8 y$ P- {
  145. {
    2 u: @* o2 u7 z
  146.     uint8_t temp;9 V& i; m4 u5 F" w7 B
  147.         DS_Buff[0] = 0;                  //秒8 d' q' s7 T: N
  148.     temp = ((minute/10)<<4|(minute%10));6 ^" `7 }7 k" j1 ?
  149.     DS_Buff[1] = temp;               //分
    0 z# m) Y( }0 R4 P& f# _: F6 u
  150.     temp = ((hour/10)<<4|(hour%10));
    & n; ^# w1 f/ P1 d
  151.     DS_Buff[2] = temp;               //时  _! }4 c( v8 W

  152. 4 J1 d. g: T4 T' a6 L( M
  153.     DS_Buff[3] = week;               //星期$ s3 B: W5 |% H5 I+ w* ?3 g# S. x
  154. 7 X: [  x* p9 c" b
  155.     temp = ((day/10)<<4|(day%10));
    1 _6 K# K" r! B7 \
  156.     DS_Buff[4] = temp;               //日
    % D+ y+ H8 ]1 `  P" V7 n" q$ ~/ ~
  157.     temp = ((month/10)<<4|(month%10));
    . L5 b; p# ~. |
  158.     DS_Buff[5] = temp;               //月
    8 ]1 @- w! d$ D: O& n  U1 q/ }
  159.     temp = ((year%100)/10<<4|(year%10));
    2 v3 \8 g- F; `7 q
  160.     DS_Buff[6] = temp;               //年
    9 z; R8 i8 ?, b* S
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    2 t0 z4 h/ I1 X/ e1 F" k# ^
  162. }1 J- p0 D' _1 @- L) A$ t% F
  163. " }8 w% e( X' Y

  164. / E+ E# r8 D! ^6 K+ m4 ~( f
  165. /******************************************************************************************
    1 {6 v3 ^3 m" v7 l0 q/ Y$ G+ K. @1 V
  166. * 函数名称: DS1307_BuffToData()
    1 ~- N. f2 g* q1 e9 S/ o
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中  r4 o. X, C+ a6 e" v% B, Z
  168. * 输    入: 无& V+ H9 P& d( H, w4 X% w+ U0 N2 A
  169. * 输    出: 无9 ?0 Z5 l  ]2 ?2 |3 I. x( M9 w5 a
  170. ******************************************************************************************/3 z5 l+ Y* ?; W, F/ t, W! Q
  171. void DS1307_BuffToData(void)9 n2 ~. ]# r* A6 s" n" u; i1 @
  172. {
    1 s) Z" O$ o, Q1 a0 A6 ?
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
    + R; a5 D" q+ z# _; d* I
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)/ K* }, F# M' j$ t9 v: O; W. l
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
    ! j8 n1 m. Q) _6 k: b" O9 j7 ~4 ^4 K
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)1 V0 @/ W' q, \! d& j: L, v
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)% e  n+ Q( o4 x: c
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)/ \+ b2 g) ]+ d& d0 F
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    : h5 w6 \% ?8 y# a& H' Q
  180. }4 \# A9 Q. b+ }! J) B& s7 B
  181. % v4 u3 u) w* E$ I% A" u
  182. /******************************************************************************************
    9 ~# v2 t/ j! ^1 Z. C( I1 N
  183. * 函数名称: AT24C32_I2C_Read()
    * x# k. z- {& Q8 _% P
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)4 p+ M+ Q. p' ~3 M  m$ v. p2 s$ G
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    8 z, t7 a; m/ @' c4 n
  186. * 输    出: 无
    8 q# W7 t+ w4 J9 c/ l* N% M
  187. ******************************************************************************************/
    ' G# q3 N& p' X" P" z+ J
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)) }7 {7 h) U! V/ h) V
  189. {. L# G6 J. s# u; K) E, j  t" |* f
  190.   e( @, E% x' Q) Q
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    9 \0 Q# L/ y6 W4 _4 L4 U
  192.     {
    1 t, `$ c: c. G: \0 n% Z
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)& e) s6 e( C! J& q, `  g
  194.         {) h" Y; x7 y$ Q9 f+ O, m
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");
    # E5 C$ k7 H1 o/ _) B  a
  196.         }
    ; b: |, p# n5 \' t, D' r! ^4 |
  197.     }+ z- p* }: i5 H) g( B( g% W2 H
  198. . H) Y  p5 I5 x6 ~) `# {- x
  199. }
    8 }1 x- d  e6 k4 M7 g; F; `7 d

  200. 6 R! ~+ E( d: A' t: _3 |' a
  201. /******************************************************************************************
    3 Z* C: x) ?' f. J' i8 Y. H
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    ; @/ x4 U* J- |- S. m
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
    ! C( l4 _; e4 E7 m
  204. * 输    入: adrr(起始地址),size(写入的字节长度)
    . |1 A4 x' e: q- V
  205. * 输    出: 无
    0 N( `% \, U  n# p. v% @5 |) a
  206. ******************************************************************************************/
      ?  d) G. i/ _/ D6 o, ~" Z5 [
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)0 P' ~2 |5 O. F/ v3 p: ?6 Z
  208. {5 t; |  A% U! w- q
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    , I& d% I9 q& v4 {* d3 a3 _
  210.     {( e! @% c; d7 |6 O3 @- |+ \
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)) p, D; Q' z, v  a  B. f
  212.         {6 n0 q) {" x/ a, a
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    2 q$ g$ f: Q( y0 \8 V, }
  214.         }: R: g- S5 |, Z5 N% e
  215.     }
    . @( m3 @* z! _2 Q

  216. & v6 s) u. k0 `* H- P
  217. }
复制代码

4 g. n: ?. P- g" l8 Y) k2 m) X. r2 c
8 @% s: a  I% R0 W/ U& r. o
. ~* G0 E" K1 a' |7 `2 N% ~
6 n3 r# L) L- D
收藏 1 评论4 发布时间:2019-9-20 21:19

举报

4个回答
Litthins 回答时间:2019-9-22 22:01:27
DS1307和DS1302区别大吗?
老牛洋车 回答时间:2019-9-23 12:10:18
有区别,DS1307要依靠器件地址来选定,也就是说可以挂在标准的I2C总线上使用,而DS1302则不需要器件地址,直接发送要操作的内存(寄存器)地址就行,按我的理解就是在这个总线上只能一个器件。
香醋 回答时间:2019-9-23 13:50:32
顶一下~~!
kongxiangtong28 回答时间:2019-11-16 12:08:07
您好,能给我发一下G4的pack吗?官网下载老是提示错误,谢谢
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版