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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:
* h% o% l1 G% s2 Q+ s: L  k I2C_Bus_Ok.jpg & q/ p3 u7 J' B+ c# {! D$ {  E0 [

  y+ g- a1 M! o4 X* R' R    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
# G! P& R: |) S2 q5 E1 O9 I# F
  1. /****************************************************************************************** . r* n: x8 |9 i7 t
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)" C) L3 a! w! R4 N  l& D) F4 u
  3. * 功能说明: 写数据到DS1307' N  b& H7 b# E6 A' x2 g$ H
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
    ( U7 V  c0 O/ G/ v" \* U0 j0 z
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误
    : u* z; f4 W$ V0 M; y
  6. ******************************************************************************************/
    7 X& i; e- z* \2 ^% S
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    5 W' J" S8 P4 ?4 a8 _' {0 ^
  8. {
    4 C3 m# v; m; K/ p, {* F8 g+ D
  9.     uint8_t addr = 0;) d* B- {% S8 D. @  }$ S7 Z
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
    # x# f# x8 q; e- G* I, E2 I
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址8 w( G2 H+ u$ @
  12.         ( B+ q! A( k& K+ P$ f
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)* I' c" s* c) X% d
  14.     {
    " R7 Z) B1 m. [! b% p! m4 w3 y
  15.         return 1;# g& U* H/ h5 R9 Q0 \5 U) L; ?: L& |
  16.     }' ~$ }0 ^/ k" |2 q; w% b0 e% Y
  17.         return 0;1 @0 v, `- d; _2 \
  18. }" G" |: T, c$ `

  19. . c; `. i3 L; x
  20. /****************************************************************************************** ( o# g9 L' K: \0 ^
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    # _6 \  p3 t2 V4 k1 ~
  22. * 功能说明: 从DS1307读出数据
    ( K% i' _9 A/ b9 D
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)  W$ J# }+ ~7 n) n. }, E+ f+ P1 B% H
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误, `+ U% s$ {& v! u" }( R
  25. ******************************************************************************************/
    ( c4 g' _! h/ f: A* ?) q* f
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    # t! e4 A) m! b2 h: v9 R1 l! g; L' D
  27. {3 V3 D8 j" D; k3 f0 k: Y
  28.         uint8_t addr = 0;
    & G; }% J. T/ U; O. z) \3 y9 a0 U
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址6 Z& \1 H! P- J. d( q9 }
  30.         6 n+ F) A4 a9 E3 O. o
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    - ?5 y% _' M/ u# E
  32.     {
    ; _3 ]! |+ {: k) r5 L( C
  33.         return 1;
    9 X; m- m: V  g0 i4 q+ l0 @! S% e5 c
  34.     }& _; s0 s* q' O" R8 k
  35.     if(size == 1){               //检查DS1307是否需要初始化
    ( P$ g6 e9 W0 H
  36.                 if(DS_Buff[0]>127){- f5 t* y! ?3 k) v
  37.             year = 2019;
    2 s: H0 g4 h1 d/ A( ^' H
  38.                     month = 9;. E2 _; |& Z6 `# V/ B
  39.                     day = 18;; ^9 T) q* z- @1 M  o5 @5 \
  40.                     week = 3;% q6 Y" l% I" C& R; q" d3 u
  41.                     hour = 9;6 o) T( d  v% ?$ g& z/ _
  42.                     minute = 1;7 k: z7 p) V7 c8 F
  43.                 / u: }# V' l0 r
  44.             DS1307_DataToBuff();' X0 P8 `. i& V( }: @& x4 U
  45.                         DS1307_I2C_Transmit(8);! v# O" R5 i1 M& {$ \# B' H% t, n- j3 C+ F
  46.                 }, T" D. D) M) O9 U  f# f
  47.         }* d9 B& p8 k6 ~* e
  48.         else{
    " H! g8 A, g: a- D* H& a0 t$ L* E
  49.             DS1307_BuffToData();
    ) M3 V% [: m; g6 \% u9 q
  50.     }
    " F7 |2 g8 t  i* K9 Q- B6 k
  51.         return 0;       
    + D: q/ t7 y' }+ k& C0 ~5 u; B2 L  v
  52. }
    ( h' v- m5 i0 `2 k- }4 J5 K0 Z
  53.                  ' h8 D7 L2 {( a5 r/ B0 T
  54. /******************************************************************************************
    ; }$ X, x( r7 g* l% f6 z
  55. * 函数名称: DS1307_I2C_Read()
    ! O/ O. p  o; e
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值. B) d! H4 d8 _9 A0 g+ j
  57. * 输    入: 无+ D3 P! N: ~  H4 O6 A* I9 S4 R6 a7 U5 e
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误
    # |$ Y! t" A' V2 s. B
  59. ******************************************************************************************/- Z6 P0 d1 I& G' |( d' _
  60. void DS1307_I2C_Read(void)
    7 h$ E) @/ L: M* [1 X& d% S
  61. {* e9 C' k8 b4 D4 r% ]8 I

  62. / @1 e% I4 J5 _
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    ) p2 G' G' l% F% M; j' i8 l
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)2 a1 H6 O2 Z' D  q# T! w4 o
  65.     {0 m7 l6 E/ J8 X  Y! y+ G
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)5 B8 h0 S6 ?) E
  67.         {
    ' i. I% o/ T# \
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");1 c" o! J$ [# _, i/ J; Z& T
  69.         }
    ! S0 p7 f/ h" z( U, j& A
  70.     }
    0 E  I4 w& ]  l' ]! z) k

  71. 2 O5 G; k: e. J8 E
  72.         DS1307_BuffToData();
    ; e2 g$ c# _; p3 ^0 W; ^
  73.        
    8 k& M! \, T3 Q+ K/ `
  74. }, U5 Y1 l! t9 q$ n

  75. . r# a+ J& C8 `+ n
  76. /****************************************************************************************** . z# u& {. @. d. ?8 q
  77. * 函数名称: DS1307_I2C_Write()6 }7 K5 R# R& R2 G
  78. * 功能说明: 将当前的日历数据写入DS1307" q7 g0 M% g* x9 x
  79. * 输    入: 无
      W5 W$ b7 K, b
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误- d5 ~9 G" ^, e: h7 @& y; ^
  81. ******************************************************************************************/
    5 y- w( ?8 y1 U" D2 q1 B7 g) ~
  82. void DS1307_I2C_Write(void)
    9 ~* V# W! u8 J& t5 o& G, W
  83. {  X) ]$ I8 R9 W. [
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中7 q7 K! h# j  ?+ s( N& @' y
  85.        
    & i- Z" M  S& ]' U$ N
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)% \. p2 ]+ x: |4 [, O1 L. a
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    & A) |% A& J4 Y' C0 J2 D9 B, R
  88.     {! S# M" F" b1 q
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    $ C, P, ?" ^; I% i6 y2 Q
  90.         {6 m9 v, J8 b' K+ r$ c! R8 H6 D: x
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");) _( N# @1 V  b/ r  j6 h" Z7 a
  92. //                        return 2;& C/ D8 l1 H3 N' R3 |, i
  93.         }6 T9 b# g3 h0 f3 y
  94.     }' v. r# U$ `6 T3 q3 V0 A
  95. //        return 0;
    $ E& F8 G4 a6 Z, H, V
  96. }
    ' _* t! _7 Z2 [5 k) O8 u8 }

  97. ; O) {/ Y) _9 f# T- @! B
  98. /****************************************************************************************** / {5 W5 F3 k  C# U* ^8 z4 q7 `! y6 g
  99. * 函数名称: DS1307_Chick()* a% W1 R1 \" b4 ]  A. h8 f
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化+ i0 N& ^5 E8 o
  101. * 输    入: 无& Y+ r5 }3 j5 c5 U- r* w
  102. * 输    出: 无+ f6 a* @9 Y) ]( u" a1 v0 t8 N8 a
  103. ******************************************************************************************/, o* w# L* \2 o% W% a
  104. void DS1307_Check(void)
    ' W% w: O# ]5 E% C1 N
  105. {8 K, H! {4 e& i5 p6 ]0 H9 r7 p
  106. % ^: @+ B. h* T; D. |  a% F
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");! K% I" C( d6 K# [/ j; q
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)7 h% E/ P, t: I! v- {
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)9 u2 F+ i0 _8 c% Z8 A. S" W
  110.     {8 z8 ^4 \: m+ U. A0 X/ n, c2 k4 k. `
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# N+ r2 |0 ~& X- h# d; v
  112.                 {% [  D/ e* n8 V2 h6 Y0 C7 Y
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");) y5 ]: w! f* G, M2 n
  114.                 }
    9 U, U  k& H+ `) p
  115.         }
    . v( q, f9 U/ y' M/ |, z
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
    ; u6 r( y/ S0 u4 W& ?2 \5 X* m
  117.         if(DS_Buff[0]> 127){5 H2 t2 @8 Y2 z. S
  118.         year = 2019;
    3 x/ X- q0 Y4 u7 |5 w0 Q
  119.                 month = 9;
    : O9 V: O1 X. t$ S
  120.                 day = 18;8 v5 v) @+ p8 F$ N) O% B
  121.                 week = 3;
    5 z0 J& A; V+ O0 l0 C" _. b$ u
  122.                 hour = 9;
    ) q6 z8 T9 `( u; M) P$ D
  123.                 minute = 1;2 D3 S: [) b% [: W1 n
  124.                
    # P" F: U$ K# d& E8 X
  125.         DS1307_DataToBuff();
    , h9 b) g. N  |/ p1 y
  126. 0 o3 f4 ^4 R3 P% p: I! b- k
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)0 k! U% J& Z* ]9 f
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    ' U# _6 s6 A" U. }- M! I& Z  z
  129.         {, q6 k* y# M9 }. ]" q% s8 ?6 J
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF), W& K# |* j9 e/ q
  131.             {" M4 R: X9 {! a' q1 m8 F/ E( d4 B& U
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");
    1 N6 W1 M# Z% E
  133.             }
    ! _& \! L9 s2 B# B# l
  134.         }
    & m7 }' s7 r* H1 d
  135.         }
    8 v8 g7 \# j5 _( I# D
  136. }
    ! }5 U8 L' |7 C# h

  137. ; ]: q! A) n0 {& L: k9 ^, ^5 f5 E4 ~
  138. /******************************************************************************************
    7 F2 i! j: [  T" v4 Y" ]
  139. * 函数名称: DS1307_DataToBuff()
    , B' G( A6 ]# X- a0 F
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中! }5 m3 f+ ^. e/ c1 y" E
  141. * 输    入: 无
    , k" `, S" \) a& s
  142. * 输    出: 无' y: ^9 p- Z* z8 J! Z0 B
  143. ******************************************************************************************/
    / S/ g, L- s) x, L8 P# O
  144. void DS1307_DataToBuff(void); {, \/ G- Z0 B/ Q, K
  145. {) V# A; N  b7 E" w1 b, v6 C
  146.     uint8_t temp;
    7 M# W2 ^3 F# _' q6 w
  147.         DS_Buff[0] = 0;                  //秒9 D5 x* R5 V+ i% K: a2 q; X
  148.     temp = ((minute/10)<<4|(minute%10));
    1 s0 W- G, p' Z, R! m
  149.     DS_Buff[1] = temp;               //分+ s+ A. W- F9 n4 I! }
  150.     temp = ((hour/10)<<4|(hour%10));. w; \$ [* P0 R; ^
  151.     DS_Buff[2] = temp;               //时
    9 [: A* M7 {) E: k# `
  152. . D2 H+ D! ?8 _' U6 F) x
  153.     DS_Buff[3] = week;               //星期
    * ?( _, O7 E& [% S! D
  154. 8 R) c: N, T; a- y) {
  155.     temp = ((day/10)<<4|(day%10));  k4 R* t, }/ g. ^
  156.     DS_Buff[4] = temp;               //日2 A  f4 a3 O4 z) _
  157.     temp = ((month/10)<<4|(month%10));
    6 w6 s4 n' Q7 d9 ]8 p+ q) K2 k/ d
  158.     DS_Buff[5] = temp;               //月
      M+ [1 N9 ^! \: r
  159.     temp = ((year%100)/10<<4|(year%10));
    " W) v% C) {1 r" w# ?- y5 K
  160.     DS_Buff[6] = temp;               //年
    , \1 m% R2 {0 U. s9 Z' ^: M
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    " R; |! N9 b* I3 S. J. Z$ l
  162. }
    0 }' x% z1 _5 L/ o' j" Z

  163. ! s; \# E" t, {$ }
  164. 0 n3 {9 C( _7 q+ O! m
  165. /****************************************************************************************** : _* Q* O4 a6 E
  166. * 函数名称: DS1307_BuffToData()" @5 y* p4 x( Y, V
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中  }/ W3 }# Z& k! l
  168. * 输    入: 无
    $ @, q5 e. k; o; m5 z, r
  169. * 输    出: 无
    7 w$ _: s! P: M0 i
  170. ******************************************************************************************/
    $ n# A/ q, M- s
  171. void DS1307_BuffToData(void)
      y6 i/ N- x% N/ j$ d- S
  172. {& f% u6 d% M% b* E. W9 L* T
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志' e+ ^4 P, Q2 Y4 O' D8 z8 m
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)6 p9 L- ], b6 Q% x; d2 R, d! H
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)' _) V, R4 }* e$ m. z3 }/ ^
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
      N% w: L7 ]2 k6 U: v# [7 X
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    3 i% F6 G- }! V0 T7 f* R
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
    ; n/ U% N: j8 |
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    3 j$ x! P( o4 z6 z
  180. }
    / v) k* O* ?# I' B
  181. # X- N  b, `7 `8 b" C
  182. /******************************************************************************************
    + A& R& T" \; S" D( a" m
  183. * 函数名称: AT24C32_I2C_Read()
    8 N' C- D- p8 m# w+ m  N
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中), H0 K5 s9 z* s1 O0 p6 d; l: f
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    4 B0 s3 f! l. i; m0 y
  186. * 输    出: 无1 H( e6 X- _6 B# Q7 j
  187. ******************************************************************************************/. _' C& ^+ y; p, w( ^
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)
    8 @9 ^( M) g  X+ M! K
  189. {" v; v, c6 G( B  A

  190. $ H7 _2 f- i- d& _0 }; ?( [
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)0 O' q2 B: }9 N% ]
  192.     {( d" O$ N6 f; b) o0 S* I' b, P
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF); g8 Q' B. k# D( ?  O' a/ G
  194.         {( @" W- E* _$ g' ~0 G( v
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");3 b2 B* N4 K. ]9 R; W# E
  196.         }# C, Z7 W" s6 B& ^% P; N% J4 n
  197.     }
    2 S2 Y0 L* Z3 O( ^- [+ d3 o
  198. 3 _9 o  I. H0 t; w
  199. }
    : y3 d9 i$ t' A2 {0 X
  200. . k; K( d4 v% F: o1 ~+ z
  201. /******************************************************************************************
    % t9 s. I5 i, h3 o" s( o$ d1 q# i
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)" U9 y) r0 |  N  s
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)' |8 p* {2 k- Y! q1 u
  204. * 输    入: adrr(起始地址),size(写入的字节长度)
    7 u( K7 X& r8 o7 [
  205. * 输    出: 无9 r7 F7 J( C! `$ @- @. X. {$ ?
  206. ******************************************************************************************/
    $ I# v$ r, t" F
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    9 }+ d7 N  u& c5 r6 t
  208. {
    7 b7 l/ K3 _" A, i
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)( p& h4 e' ?# z  f( T5 c$ d3 U1 W
  210.     {9 O* h( b' D" i
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)- m$ {7 n( G9 c( y& {. \) e7 q( B/ o
  212.         {
    % t4 ?8 g0 q& @0 G* R# d) F! S
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    5 v7 g$ v3 n$ D! u& y( O
  214.         }. S, ?) K; D3 n/ |# x" C$ U; Z0 W
  215.     }
    . m1 U0 I. d2 H7 R6 Z4 L
  216. 4 h6 f; q' F1 j/ h0 C
  217. }
复制代码

; |9 x: G) j; f
3 a) i! j, d6 b& K, s6 e* [5 }
( D2 B; n% m% j4 b( V5 |  c; S* g6 U+ y/ q$ X% q8 l7 h7 p" ?* z
% J4 H$ [+ b( {, Q7 h5 C. q3 K2 M3 ]
收藏 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 手机版