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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:, b0 m7 L$ L7 }  b5 ^; H
I2C_Bus_Ok.jpg   p4 t; N; `' Y, ~& M

8 m# @' m8 q/ o  i    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
9 i+ k  n1 s8 |. Q+ ]4 X) A
  1. /******************************************************************************************
      \& P0 }% ?  I& R5 u
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)
    ( Y8 O# i) ~- b+ t: ?
  3. * 功能说明: 写数据到DS1307" |: @6 T3 U3 k. `% @5 K2 B
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)/ G) X. q# V& p4 b' U& S
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误
    & D6 P$ N( K, O3 \
  6. ******************************************************************************************/
    . W2 @% x& t1 V5 \  Q7 b. H$ K2 {
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    9 ]* n, q1 r6 c; l
  8. {) R2 d$ Z8 c$ [( h$ q' ^
  9.     uint8_t addr = 0;
    4 w* J) L* e7 M$ j3 |* D+ _7 c
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中( d% }: ?4 V$ T# e8 m2 m
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址; E8 T* S" Q7 `. }2 W3 V2 V" A1 f
  12.         : b7 m4 U% g+ P. M  b& T2 r2 h
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)2 Z2 a, r7 M! F
  14.     {! j( Q" {$ b5 n6 s9 M  @( b: P
  15.         return 1;
    ' c8 F: v$ D. r0 K. x4 \( q. {
  16.     }
      B( ]5 u- f2 B/ f
  17.         return 0;
    & H+ ~* j0 t; M4 Y2 w5 Y
  18. }
    ; o/ k( O0 K9 d. J1 w5 A
  19. " @5 ?3 c  R  a/ T
  20. /****************************************************************************************** ; r6 C- B# `3 \* t- S) N% h. p
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    + U; z9 A  O  G) `
  22. * 功能说明: 从DS1307读出数据" P# }+ s2 `$ w9 l+ `
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)# J$ c( S7 w! S
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
    9 ], F, N# h' _
  25. ******************************************************************************************/8 t' H/ u0 }: F
  26. uint8_t DS1307_I2C_Receive(uint8_t size)7 @4 D" s: E! u* s+ p0 ?" D
  27. {
    ; J& X+ C0 X3 E1 A- `
  28.         uint8_t addr = 0;) k* B5 e# o, Y% R6 _0 N
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址! b5 g% P, @, _# \- W( A% X
  30.         ) t# \6 i( w9 R  g+ h. m
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    ! d$ M3 x2 {, v, J- G! t1 s; i
  32.     {
    5 Y: V& Q( O; f3 p* Y$ f
  33.         return 1;% t" f3 p4 C$ E4 R% \
  34.     }1 n7 e  W. l! d1 e: ^1 s
  35.     if(size == 1){               //检查DS1307是否需要初始化1 L/ z& T) }( N% z5 M+ Y
  36.                 if(DS_Buff[0]>127){+ v. v: Q- T" d5 A  J( z. g
  37.             year = 2019;1 V) Q" s2 O+ q# k
  38.                     month = 9;
      o! ]  j2 K: d/ V. S' ]. P2 u3 N
  39.                     day = 18;
    2 F7 c( O8 D) k& F, @
  40.                     week = 3;9 w4 [- S+ |' ?- S
  41.                     hour = 9;
    - `! }2 N% P$ U/ w. M( L/ I
  42.                     minute = 1;" t4 D1 F, |, ]
  43.                 5 ~5 c8 P" h. s1 J0 d' [
  44.             DS1307_DataToBuff();* a0 ~$ B; w  G
  45.                         DS1307_I2C_Transmit(8);; a; \& _! n. D5 C; w
  46.                 }+ r" E8 m2 X. w; i) \
  47.         }
    4 j+ ?" z: I$ A
  48.         else{
    $ _2 u! _9 s3 J9 {! I( q
  49.             DS1307_BuffToData();# s+ Y0 _/ T: ?) o. {4 E2 ]3 E$ t9 X
  50.     }6 v  j+ x5 f7 w0 v+ ?; l
  51.         return 0;        * V: n  |1 J4 S6 B$ @* R
  52. }
    / e8 A- S4 T+ ]0 n% N7 w
  53.                  : `  w7 b- K/ r! P/ D
  54. /******************************************************************************************
    ' r  y2 w- Q9 @+ \( O
  55. * 函数名称: DS1307_I2C_Read()( T, H' a, j$ e5 k; R+ A
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    ; K3 f6 l# @  |7 V* b( B3 e
  57. * 输    入: 无
    * C0 T8 q% K8 v( o0 s7 h
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误1 X  n. P" w, Q
  59. ******************************************************************************************/0 }: z( d. k8 u$ o/ q; W
  60. void DS1307_I2C_Read(void): N# E4 H1 S' @. b5 z
  61. {
    5 Z! S/ q& _$ {
  62. : b( u7 m! b: z- m/ K/ x' |0 A
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK). R" m: \; _# L1 v: e
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK): x3 s) `+ F2 X) d2 S% O, ?
  65.     {9 W; V6 A. l0 z) |
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    & Q) H8 A/ _" D4 [* x
  67.         {
    - H6 Z4 H0 G$ c! W0 Z' x
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");- h9 E4 F, m& U( x/ ~! I* c; M
  69.         }
    - U! K4 n% ?) l0 Y7 t
  70.     }' n5 o4 L3 |, ]- W
  71. - t2 t; ^2 _# z
  72.         DS1307_BuffToData();8 W) c$ r3 d# E6 H; t4 o
  73.        
    & M2 s# l; A+ h- X3 D8 g+ Z& a
  74. }( J4 o6 P2 w' A; Y! O
  75. : @3 j& R' }0 I9 ]! S: O
  76. /******************************************************************************************
    . ^0 T; i" w; K  Q% `( |: p
  77. * 函数名称: DS1307_I2C_Write()
    8 ~, a, o" T+ h7 y( }. T) j
  78. * 功能说明: 将当前的日历数据写入DS1307. @. ^. y1 y+ c# Y
  79. * 输    入: 无+ p% @: w7 K+ u6 c& v( P, p' e8 N
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误
    ; \' I9 k' I# j5 w2 C; V9 b/ f
  81. ******************************************************************************************/) p4 L4 T% s# R5 E) h
  82. void DS1307_I2C_Write(void)
    , z" G) `3 A7 D. t9 G& \
  83. {
      g  z; _* a4 l7 m) m- x
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中# I* U( P' j7 f8 c5 P& C
  85.        
    6 s6 k2 h$ T/ S- L
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    & u: Q- P9 J: I
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)- c9 V! E* ]# m  G+ c# d
  88.     {7 Q3 h4 C6 _& k
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF): q5 d) ^, n% o/ m. s& e* D
  90.         {
    ! o5 u$ w  L" s9 U1 P( o
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");1 K8 Q# g% P' [, ]& G- r% C# w
  92. //                        return 2;
    # S  v; Q6 v4 G9 ]
  93.         }% P/ N' \5 X& P) @! E* n
  94.     }
    / C) |1 }% _: K( @
  95. //        return 0;
    , M! i% b: s0 n1 C3 C6 _' q: T
  96. }/ o+ I3 a/ g& S1 P: w% d
  97. ; Q2 d7 Y' z; s9 w. {0 y
  98. /******************************************************************************************
    / r8 i% j; t6 K3 g2 }- u5 Z" U" B* f3 f
  99. * 函数名称: DS1307_Chick()1 `8 }9 k0 P5 E, ^& A: n
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化0 J, M+ b- d+ N- H
  101. * 输    入: 无  p- x) `# `) g/ F! i  N" H1 v
  102. * 输    出: 无8 J8 G3 l. S% w' P& W/ z
  103. ******************************************************************************************/3 F+ G$ o) H- V1 D+ q, m% a
  104. void DS1307_Check(void)6 ~: P8 m7 k) J$ C! y8 G0 x5 u1 ~
  105. {
    0 U& ?& o. M8 g5 i2 l  \

  106. ( O' l# X3 I& y* C" x' F  |- a/ |
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");9 V( Q1 c$ s$ l6 C6 G1 ?3 v
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)& K" W! E" ^' ?: H9 z5 k
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)
    & S# M) l" k# ]9 s' k
  110.     {; L: h$ D9 `# O4 K& _$ g
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    + Y' A9 P! Y; h3 |  x  @8 \, O; y
  112.                 {  l' L1 P8 s# t+ f
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    6 f1 c8 r( G' A, @1 g* j( \4 i
  114.                 }
    # ~- M; `1 O/ B+ o: }
  115.         }
    2 @) a/ }$ j. a
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);+ j1 @1 P  J+ {3 a: V3 R' O
  117.         if(DS_Buff[0]> 127){- n- D% U7 ]& b0 R. \
  118.         year = 2019;
    7 O$ T9 h7 q# u5 O: m
  119.                 month = 9;
    0 T4 k6 r2 d3 i: ]- r, G' f0 d
  120.                 day = 18;& c0 h$ F! t* \; N
  121.                 week = 3;& N9 I4 u' ?. J" D" |* @: t, H6 m
  122.                 hour = 9;
    8 l1 I3 [* z; q' f2 h. A! e
  123.                 minute = 1;- E1 \3 h% [9 H4 t7 S" ~
  124.                
    - b) I3 H: \# {
  125.         DS1307_DataToBuff();/ |7 n5 R3 C1 ?0 H6 ]3 F
  126. , d2 f: q- v/ C! @# Q/ `
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)6 a9 S& @: _- v. p; v
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    , `3 F; \5 O9 A: b5 Z
  129.         {$ W9 Y* q- D$ k. M" Q, ~
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    8 `$ h* |# B$ P5 l/ U5 T
  131.             {
    0 q" s) Q0 j) L$ K# h
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");( N) c5 R* Y- R4 H' a2 \; z2 n7 f: l( \
  133.             }
    & w! a8 d6 e0 k
  134.         }
    ! t" g8 c/ L3 ^! s# x
  135.         }( u! I: o- D) s9 u9 g
  136. }% i. w; j7 ?+ p
  137. ; T& Q6 q- M% U) U% X0 @. p: t4 Y
  138. /******************************************************************************************
    ! F" @6 i! q# ?- D: M
  139. * 函数名称: DS1307_DataToBuff()2 K# b; e# W/ b8 ^" K. m8 o
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中, c6 G7 |* |. L9 o
  141. * 输    入: 无
    , _1 |" v6 j: K$ {
  142. * 输    出: 无
    5 z; C3 a: ~) b4 @2 f9 O. k1 F
  143. ******************************************************************************************/0 f" ~1 g0 U: L0 B3 a: w
  144. void DS1307_DataToBuff(void)
    0 K- J& \. }7 L1 B
  145. {
    2 ~  U4 a2 O, a% Z  R! |7 R
  146.     uint8_t temp;6 r' e+ y% t, |$ ~
  147.         DS_Buff[0] = 0;                  //秒
    # w) E2 N- q5 l* R! R  r
  148.     temp = ((minute/10)<<4|(minute%10));
    , L+ Y% e2 s, B4 C' j
  149.     DS_Buff[1] = temp;               //分  Q/ o- c; W" |
  150.     temp = ((hour/10)<<4|(hour%10));4 R9 _. o6 x0 s  h0 @
  151.     DS_Buff[2] = temp;               //时2 j5 _% I3 P" ]. S
  152. # P  U1 C; H2 @+ k( R4 t2 R# _
  153.     DS_Buff[3] = week;               //星期
    3 s& _, L0 E  V; ]3 j3 R
  154. * x6 ^- X, s: m6 R6 @- R- Q- d9 M" I
  155.     temp = ((day/10)<<4|(day%10));/ n5 ]: v6 b8 B
  156.     DS_Buff[4] = temp;               //日
    7 p$ W  J& o5 X1 e+ x% `1 r
  157.     temp = ((month/10)<<4|(month%10));* q5 S3 D% e& g+ S% K
  158.     DS_Buff[5] = temp;               //月
    % ~# N0 V% D) ~6 v6 o' O- R
  159.     temp = ((year%100)/10<<4|(year%10));% G1 @9 w$ _: {, u! G* a: m
  160.     DS_Buff[6] = temp;               //年
    1 Z* _  [4 z1 n! {/ @
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波4 s8 W, {2 b( _: B$ Q8 i+ o
  162. }$ u+ s2 S5 X# g- k  L

  163.   F+ ?7 x; |- Y

  164. / S" O0 r* i7 X" P* p
  165. /****************************************************************************************** ) U7 k( s. m) g: y+ U" K) P
  166. * 函数名称: DS1307_BuffToData()
    ' `% W" s8 R/ i6 v& Q) c& B7 P# D' h) A
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中
    2 o# s7 J4 e% p% N
  168. * 输    入: 无; P3 S& m7 T6 B5 a$ Y1 G: N7 a/ A
  169. * 输    出: 无
    " m% ?0 r1 G. Z& b3 d
  170. ******************************************************************************************/9 ]( K6 q( f4 M2 l/ V3 a$ m) P* T- T
  171. void DS1307_BuffToData(void)
    3 ^3 q1 Z6 O" ^! ^+ L
  172. {; i6 k1 A' }% n
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志* R! z1 W8 r0 ?. m  e! `6 p
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)1 X, b  W: `' i3 N
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)' G1 t% J/ B7 g% ^6 O( J8 Q1 L
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    ) |7 d4 S% I* G. O
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)/ Q% C1 w  R; r# j
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位). b% C5 F" p) h3 U5 ]3 R5 E
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    2 `/ }3 r, S* Q8 a7 T
  180. }
    ! t) ]: O7 f' C. L. ]6 K

  181. , s# |7 Z5 K# a- |% z( v; E/ H
  182. /****************************************************************************************** / i& @  H2 K: t/ `; H7 {4 A
  183. * 函数名称: AT24C32_I2C_Read(), c" p; p4 E' L7 J8 X. S
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)
    / h2 i$ l- ~4 C: q; J
  185. * 输    入: adrr(起始地址),size(读取的字节长度)  v/ n0 |" B$ Q! y7 W4 u- ]
  186. * 输    出: 无
    # U0 k3 b, d0 `- q) y$ c
  187. ******************************************************************************************/
    + h: I  l5 |% v) q5 d8 r
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)
    & U6 _- ^. e' e2 q4 d2 i$ V
  189. {
    + N/ n$ V( b7 D! }' W# _

  190. * p+ l2 O9 X& a- C
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    0 Y, x1 x' e; T" }( k* V
  192.     {
    ; Y: a: m6 L' c: T9 U8 f
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    ! v. `" x7 ?$ S+ E
  194.         {
    5 O( ~; ^! V$ M
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");% ^' [8 R' V. D' l, |( ]$ E) Z
  196.         }
    % m' ?- `+ j/ E( B% U0 Z5 g% o
  197.     }; G$ C# |+ a2 S" Y, k

  198. % N0 U* b+ S, o0 Y- g8 r/ r; [# V
  199. }
    . q+ P; w) E5 p) p4 D! Q4 b

  200. . R' ?3 _% p0 ]9 Y7 I
  201. /******************************************************************************************
    % O7 ~) S( Y1 {1 r0 l9 U9 p
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    1 @0 R2 X( V# {7 K
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
    / F1 z$ f. N% g0 ?! ]
  204. * 输    入: adrr(起始地址),size(写入的字节长度)$ g; v! [; q0 d& B* w# [7 W- |
  205. * 输    出: 无
    7 C( [( S9 b7 N( R7 E# H
  206. ******************************************************************************************/+ |% ?% o+ J: B- ]
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    * g% M  v  R! J4 z9 T" x9 D
  208. {: E- ]. n. H+ R# Z
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    9 D4 z$ p# E" }
  210.     {3 U# e6 t! [6 \  S9 D' @
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    6 k( S- |( e0 m& f
  212.         {5 A9 w3 V4 f+ F1 p& R# V
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    0 a7 e8 B1 H9 F3 h7 }
  214.         }
    . Q# v9 |% _- e2 D+ e
  215.     }2 N+ r; J& a0 y. H9 |
  216. 0 P5 B/ t6 `0 Q& N8 v
  217. }
复制代码
9 a, ]9 n' ^  n
6 n1 C6 v6 P( S0 h  {; N5 U, g
) W1 z. m+ v; C
, W+ R0 U6 P( K2 ?3 a

0 u* x+ B8 A1 Q7 f; F2 k" z
收藏 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 手机版