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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:; O$ ^! P# q6 R# s
I2C_Bus_Ok.jpg
+ o5 G. H6 {4 t! m" z; t- ?% L. Y" f# i% i& [) g3 `& _, }
    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:* ]! M  ^$ B/ `4 W% k0 X5 r
  1. /****************************************************************************************** " Z  f3 {2 F* R# o
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size): r6 X, _+ ~, H, o6 y
  3. * 功能说明: 写数据到DS1307. n- l6 K, k' s1 Z. _1 U$ o
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
    : {; Y  S7 j4 R  p
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误2 x5 b% N7 h& s2 R* X
  6. ******************************************************************************************/
    1 g$ M1 U5 L2 h' J
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)8 V- q/ m0 i4 n+ p! V9 s
  8. {
    # s6 N7 U( ^$ a. ?
  9.     uint8_t addr = 0;
    ! i, H4 C1 Y# a5 r+ H
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中6 ]) ~0 [7 ]; c+ L* S. L
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    " l% {4 L* `+ P0 s( G: ~
  12.        
      ~, D0 ~1 R) r) p# R0 i. U
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)! e" Y$ K7 F1 O, X. `
  14.     {* S( e! e. ?( s
  15.         return 1;6 H" E5 e1 `& t" F$ j9 N2 t
  16.     }
    ' I' {4 }4 s/ [/ \, A
  17.         return 0;7 K: [" Y, ?9 V, _
  18. }
    4 \( a3 W% E: `! I7 F( X4 @

  19.   l( y0 q% J+ ^$ u2 ?
  20. /******************************************************************************************
    ; |0 I; Z# E  I& [9 _' ^" t% z
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)$ D! j  S8 ]9 K0 S4 h. _
  22. * 功能说明: 从DS1307读出数据
    5 v7 p1 u" `" C& T* Q+ D- _
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)1 H2 k  q: E3 `0 `/ @1 Y: j' Y
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
    ; r- N* P7 p& X6 Q6 T. e
  25. ******************************************************************************************/) _7 _0 y( o5 H' \. A8 B4 p/ @( B% R
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    & X; x" A+ p  }- P
  27. {
    ! T7 ~( j$ L) Q0 N7 z5 A
  28.         uint8_t addr = 0;7 t% s3 Z2 A0 H7 |% d
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址# B$ {0 K" e9 v7 u& {$ P& @- c9 |4 l
  30.        
    & k( [3 s$ h2 ?
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)0 B# v% J' c$ Q! g, y, T
  32.     {* ~3 p7 P5 {7 z+ K
  33.         return 1;
      q8 H) C) _: _* F" d9 ?
  34.     }
    : l7 @) M  J4 k& R
  35.     if(size == 1){               //检查DS1307是否需要初始化
    * ]+ U% ^7 Q. m" s2 F
  36.                 if(DS_Buff[0]>127){
    ' i4 B" Q% e/ |
  37.             year = 2019;% \% [. o+ e- c
  38.                     month = 9;
    * q! t# d  G8 l, d0 W; }
  39.                     day = 18;& V7 n9 w" B. T0 x0 L
  40.                     week = 3;
    ( P- o1 v; s: s7 h; e$ V
  41.                     hour = 9;0 u" P7 L  d7 B0 w* X$ F' r; G
  42.                     minute = 1;" H6 E, n7 W* P+ I
  43.                 , D7 ]+ Q7 b" l' X& K
  44.             DS1307_DataToBuff();
    6 o& [0 C6 s0 Q* N: m9 F$ N" w
  45.                         DS1307_I2C_Transmit(8);
    ( W% H* s$ _( L8 e2 D5 R/ j
  46.                 }
    ' M; r1 Q# ~! d8 ~9 ^
  47.         }0 m+ s/ N# G2 ]
  48.         else{
      D3 e" z  Q* s* @5 M0 N! ]
  49.             DS1307_BuffToData();* O% U/ @/ d5 r& B7 G
  50.     }
      ]& P( l6 S! J- h& Q: S7 k. Q
  51.         return 0;        , J( M/ z* C9 d8 x7 E3 [
  52. }
    . r! L6 l0 ]1 G  m& B( Q( I
  53.                  7 `. i- h% {- t9 ?
  54. /****************************************************************************************** 3 A. B( H9 I7 T  r' }4 k' g
  55. * 函数名称: DS1307_I2C_Read()
    ; g/ s! `- }+ r% P# A2 E+ X9 ~& n
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    7 G! f7 J: z1 I7 S8 O% a) i
  57. * 输    入: 无
    ' @% x# w. w7 v4 v( A& K( b7 y
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误
    6 L& R6 C) N) F( t: ]
  59. ******************************************************************************************/1 d, G) c) U: V/ x) ^, ?* z) y2 W
  60. void DS1307_I2C_Read(void)' K) Q; O3 E. [$ E
  61. {  t. F' `( g0 J

  62. 3 v, `6 N5 i- s% ^6 ?
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK). R6 Q' F# p1 I, j
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)9 n$ I* r( G' q! j* t
  65.     {% e! [) G+ K! ]- i: _- x
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF). x& d0 V1 `& T) _+ s. s* f- s
  67.         {3 Z6 }* V( T+ Z1 @/ w' n
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");  I% R- L1 N9 w5 Q1 R" J' u# [
  69.         }$ Y+ ?6 R3 P2 c1 H; y
  70.     }9 c+ o: P. L+ P) w, v; ^

  71. + g6 v6 w5 c3 A- v8 \
  72.         DS1307_BuffToData();' ?: z) C5 h7 L4 J1 s
  73.        
    3 g% ~9 x- N! e$ n! I" N1 i9 K6 Z
  74. }
    8 w8 o" f4 o) }: g
  75. 6 O- Q0 ^2 o+ F4 ^
  76. /****************************************************************************************** # K. l& s' f5 q) V) A5 U6 O5 b% b" [( G
  77. * 函数名称: DS1307_I2C_Write()
    * }6 m0 V; v8 e, z
  78. * 功能说明: 将当前的日历数据写入DS13072 h5 M; i0 s% j7 ]/ W
  79. * 输    入: 无
    & _! d! i1 _- n* i2 i
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误' q2 |, x6 @2 I. ?0 O8 ]5 p8 ~9 ]
  81. ******************************************************************************************/. ]& F3 F' m3 r- B( H% @( Q
  82. void DS1307_I2C_Write(void)
    1 n3 `2 d& T* L& u. F- Y( H" d
  83. {+ ?! O% o. R/ S2 P" h
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中9 o. g2 K% e5 v4 g4 g$ h' m
  85.        
    * B) h  P, W0 |3 l- [
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    & k$ X" Z( `2 x1 r+ {+ y6 ]
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    3 a7 v5 O! u5 }$ c
  88.     {
    6 N+ R" [( [4 L" T2 R. b2 w6 w/ b
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)( \0 u* `$ o; R& w
  90.         {( e7 e4 k) C# V/ P3 ?2 v3 Q6 s
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    . W$ Y+ u& E- F8 x; M* a# `
  92. //                        return 2;1 V# B: n" m- l1 G# b# a, [
  93.         }
    $ U5 L' q' Y1 [8 n$ R
  94.     }
    ' x4 Y! I9 {+ }3 H3 t; j+ V0 x
  95. //        return 0;
    1 p4 z/ s5 G# I3 _7 O: z
  96. }
    5 \7 Q0 s5 G' h- V$ Q

  97. $ y' H  H, Y- {( c& e" t+ d0 r+ S
  98. /******************************************************************************************
    " M' |' Y; ?$ }1 i8 U& d$ ]! H! W6 _, N
  99. * 函数名称: DS1307_Chick(), a+ }5 u* k4 ]/ P8 V. g9 H
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化' P. V* F# C. K
  101. * 输    入: 无
    * Q7 R7 N6 o4 ~
  102. * 输    出: 无' u+ R/ d2 d% x
  103. ******************************************************************************************/$ n# D% K, C6 T2 I$ {1 J2 p0 C
  104. void DS1307_Check(void)! ^5 ^9 l, P4 ~* Z: Q* T  O
  105. {
    1 o5 R- U  W% R  `4 \, q
  106.   Q  S5 |3 |3 q4 U! ]! ]5 H  o
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");
    " C+ _# Y( E8 p, V+ S- J
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK). i$ P3 M* {7 v; N" m" U7 r* I
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)/ o8 N8 P' |0 z7 G  v- o
  110.     {- B" [* F# ]4 \* _8 A$ q/ ]
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)$ B, K; p2 H6 q
  112.                 {
    0 {% M+ D9 z+ P. e. e
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    - M1 q8 U2 I; U
  114.                 }
    4 a+ [$ Q6 m1 t5 s9 z4 X" V
  115.         }
    8 k, ^: f+ `7 o
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
    8 N, c: B4 g' B: E% d
  117.         if(DS_Buff[0]> 127){
    / H" {6 m3 T+ y3 `- {
  118.         year = 2019;: c' C4 \& C2 @3 c% X) d" e
  119.                 month = 9;% C  P, m3 _1 [+ z
  120.                 day = 18;
    : A% q$ y, N' \8 h6 G5 X( M9 b
  121.                 week = 3;
    8 l  e, ~7 A' x" O+ i* z* C
  122.                 hour = 9;
    2 t+ N* `2 Y9 K- K
  123.                 minute = 1;' {) d/ y% c, E
  124.                 ( G7 E5 L4 s$ k' q
  125.         DS1307_DataToBuff();
    ) l" _+ T3 z; D" ?$ D
  126. . r; f  i# a- [+ G* D
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    ; _9 U, K; L; Q6 R4 |
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)% r: c+ \7 J# a3 _: O+ L  ]
  129.         {
    / }2 ]0 k2 z6 D
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)2 C% U7 e. N* t& a' _
  131.             {
    ! \( K9 i, Z6 G' D% c: t
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");/ X/ w1 Q$ t, p2 x
  133.             }; }  J$ u/ G2 [; V" x/ D
  134.         }
    # w7 p5 t- y$ \/ g3 s2 U$ \8 |  E
  135.         }
    % j1 [, Z$ `+ u* ~8 _7 `0 z
  136. }4 D; u3 _) C" P+ B, o; N9 X
  137. ( [, F  Z9 V$ _, _+ L$ y8 d: w
  138. /******************************************************************************************
    6 V9 S" s! l: I/ n, H
  139. * 函数名称: DS1307_DataToBuff()
    8 t' c; M( G5 \9 J* M
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中
    . S4 l- F1 D5 G# D
  141. * 输    入: 无1 p$ @7 h/ _. C
  142. * 输    出: 无4 o) B  z& T" F8 _
  143. ******************************************************************************************/3 ?. i5 L2 {, B8 k- ^$ B  o
  144. void DS1307_DataToBuff(void)
    + n0 p, d% b0 ^1 |' k- h( ^
  145. {
    : t; ~4 ~* Z9 }. W* q
  146.     uint8_t temp;; J) F$ Q& x+ g$ U
  147.         DS_Buff[0] = 0;                  //秒4 b7 S& f2 P' N# ]- u
  148.     temp = ((minute/10)<<4|(minute%10));3 B" W1 O' s- d8 h) v
  149.     DS_Buff[1] = temp;               //分; W% [9 Q6 p# @0 l6 K/ k+ N
  150.     temp = ((hour/10)<<4|(hour%10));
    . ^& e  F' u4 m" a8 R' u: |
  151.     DS_Buff[2] = temp;               //时: o) p: g; r: v( L5 `1 q. `8 x

  152. / ?' U% W$ s1 a+ @$ H
  153.     DS_Buff[3] = week;               //星期
    , T6 s- F) J1 z+ m1 ^6 b( k

  154. 9 W3 h! }2 ^& q4 l
  155.     temp = ((day/10)<<4|(day%10));
    * q% w. h3 J: T% I4 @! G( a' H
  156.     DS_Buff[4] = temp;               //日1 K5 O9 @4 m4 w: g6 g% U* g4 ^
  157.     temp = ((month/10)<<4|(month%10));& \0 b% p) q# ~& H2 a* r3 m
  158.     DS_Buff[5] = temp;               //月
    % O: @; H5 s& k& k: L6 F
  159.     temp = ((year%100)/10<<4|(year%10));
    8 Z- ?2 Y* a3 N( s
  160.     DS_Buff[6] = temp;               //年
    6 v# t. B2 i/ a& I/ j
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    ( y% B) a, a9 L2 G+ Z- i. }* h, Z
  162. }* {+ d9 X* S- @1 K$ A( J* \# H; e0 q
  163. 2 |' H& y! D5 ]/ x0 T
  164. ) q% j7 q# w+ q+ E4 V* D" o
  165. /****************************************************************************************** 2 T" l  [" V  c( Z
  166. * 函数名称: DS1307_BuffToData()3 L) T9 r2 C* A
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中- `( A% F: M4 S
  168. * 输    入: 无6 Q+ v2 U( ]+ M  O, g) D
  169. * 输    出: 无
    7 j% }4 e  T4 N9 j5 {" e
  170. ******************************************************************************************/
    , E6 G3 L1 P/ P# W
  171. void DS1307_BuffToData(void)/ q+ W$ ]8 ]) j! n. c* [0 f
  172. {
    ' y8 b" H& u" D. W1 q' d) w
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志' W! {! _. ?9 n2 [% G8 \4 `) v
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
    ) u/ ^( V$ U1 g' t  A6 g8 X3 Y4 F& E
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)! `# S" @8 u3 L
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    + F  c4 l5 D9 W2 ?  Z+ V
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    6 C" Z9 w3 v' _) Y8 G: ]& h. {# v
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
    + t- t5 h9 [4 o! k3 c! m
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    # q" q% T7 |% I) r
  180. }$ t! j! P8 Q& a" G1 n3 Y" W' w
  181. ' q* F4 {$ V1 y" ~; a
  182. /******************************************************************************************
    6 T- v, [  N* h  d: X. _
  183. * 函数名称: AT24C32_I2C_Read()
    8 s2 \3 e5 H5 t( _
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)
    3 e. `# s, V. \+ @$ [
  185. * 输    入: adrr(起始地址),size(读取的字节长度)* W: x" A% [' s1 S6 `
  186. * 输    出: 无" D# D) S% E8 L
  187. ******************************************************************************************/1 H3 b- l; Y6 h: K. W& R# p
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)
    6 z* M+ g$ I! x8 s3 o8 [- F9 j
  189. {
    3 O$ p) y4 e# p
  190. 3 V; C5 L% a3 ~: o0 h$ b
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)+ k7 J  y+ c' g/ D+ Y9 q; Z
  192.     {6 Z3 M- |0 v7 Z) {: q+ n
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)+ Q5 F& k! t, @9 a
  194.         {3 I" r. {4 n' v3 J3 L/ l
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");6 g0 @" Z' }6 O, v$ D0 F. G: e
  196.         }' R1 o$ t9 U3 i! V, g
  197.     }
    ) |& i4 Z+ I. t3 s* `5 w
  198. 9 E6 D6 {7 d3 G4 U& h
  199. }
    6 ~( p4 I8 K7 Z2 i+ k' j; g& i
  200. $ k9 L# D: t3 c/ w  h
  201. /******************************************************************************************
    : ]+ K/ U/ E$ _& g; c8 t
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    9 A, x) x  Q+ b  Z
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)+ o# J% w+ f' D6 v
  204. * 输    入: adrr(起始地址),size(写入的字节长度)9 k+ C3 Q9 E3 z5 `4 w
  205. * 输    出: 无
    ! S: L" J6 i& w6 R# W. E
  206. ******************************************************************************************/
    # K* m0 @: F+ E' j
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)9 X7 k" |& Y; C1 y6 {" e
  208. {
    9 K9 g4 r  ]1 _
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)$ B- {9 Z9 B2 `0 v0 V
  210.     {
    4 |& r: S; j* q- O& J0 H
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    : G* }; `4 g) ?; N+ M, k6 K( r$ T
  212.         {
    . T# Y( O5 ~/ [9 l9 J" H7 E+ x$ u
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    / f: a2 Z# D, A% @: x0 t
  214.         }
    3 @0 y. y7 H0 D
  215.     }
    4 Q- x1 U" C) n5 N
  216. ' I6 o8 u+ Z3 Y3 J9 \
  217. }
复制代码

* c! q% ]; ^! `- P( d
3 @; l7 ~) ~# o
' M8 P# d8 W3 v1 c0 r
$ D! D, b2 `3 w0 }9 Q+ b4 M- Z- w* t1 x9 _, q& N
赞 收藏 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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版