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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:
! ?, Q$ b: @0 M$ t2 Q I2C_Bus_Ok.jpg 4 y7 i: m& d; \( p' M$ W
9 Z: R# e( H: M6 n) h6 j: s7 m
    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:$ N4 ^( f4 R1 H; A
  1. /******************************************************************************************
    6 }/ N) e/ D2 f5 C5 y( T8 k
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)
    / k8 s0 J8 F% s( P
  3. * 功能说明: 写数据到DS1307
    + R3 E7 E- \4 f
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中): ~% T8 B$ |% L" _+ Y3 S
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误+ E0 C: o7 f3 b9 O3 \  z! l
  6. ******************************************************************************************/# \. J6 B; l8 y& J
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    + m/ ]. S/ x6 _/ x; \/ n
  8. {
    9 R* f  Q( T. \8 s) j. _1 `% M
  9.     uint8_t addr = 0;" }6 R( L- G& y' E8 n% l
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
    3 ^1 G( Y: b+ B2 H& v) m
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    " H- N. i( W6 X* _0 j+ X7 Z
  12.         1 l/ `* K; N4 c- @4 K
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)4 K/ y9 J) }: Q  ~1 j, D
  14.     {
    1 i3 s, L3 p7 ?7 K
  15.         return 1;
    $ s6 C) a+ Z) M( i+ o
  16.     }+ P/ M# j2 O' a; Q6 D4 C+ Q
  17.         return 0;
    , t* Q3 W8 ^2 D4 }) U/ r" ?8 X
  18. }
    5 X$ U% `& J6 x' U1 \. K
  19. / ~0 T$ A0 C$ C8 I( ^7 t
  20. /****************************************************************************************** , Y8 y! u. B6 Q
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    & J! t1 t% m9 m- p8 V6 N( c
  22. * 功能说明: 从DS1307读出数据
    ( l& I  o  c. `$ _
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)
    4 o$ p1 J. M. ~
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
    & {; o  `( X7 G
  25. ******************************************************************************************/, {# r) c& Q; i/ b( e+ I+ E
  26. uint8_t DS1307_I2C_Receive(uint8_t size); u7 ~! c4 N. U+ p# O6 Q/ k3 }
  27. {
    0 @' H4 L* m  n* E* T
  28.         uint8_t addr = 0;6 Q/ _: j9 W' t) a' ~  [
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    + n8 D+ a1 K6 s! A( {
  30.         7 @2 w# c, o7 C" k7 J
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)7 ?- @0 L# t$ N; M5 M
  32.     {
    - m7 \5 b5 t  i: x7 ^
  33.         return 1;
    $ f% a2 c+ z" J+ L
  34.     }
    " R% E' _1 O+ w$ v4 p
  35.     if(size == 1){               //检查DS1307是否需要初始化
    " M) C# j9 Q/ \4 o1 {3 F
  36.                 if(DS_Buff[0]>127){  f7 U& \( [/ e
  37.             year = 2019;& C- w# a* x% c9 M8 H6 U- I
  38.                     month = 9;
    7 b4 y; {6 p" E* J( n0 R
  39.                     day = 18;% @) ^3 B1 O( E1 L# X& j
  40.                     week = 3;  M% q' Y3 u' Y" b" H
  41.                     hour = 9;
    - G/ l, b5 }% P
  42.                     minute = 1;. E" u' X3 |6 j' C' T6 r
  43.                
    2 T* I2 b( [( O! h( C" Y$ k8 i3 x6 W
  44.             DS1307_DataToBuff();3 h, ?5 `) I0 Y" T0 x
  45.                         DS1307_I2C_Transmit(8);
    : z4 s, {/ ?3 ]+ G
  46.                 }# q3 g3 `$ o& ^; t) X9 l- }  V
  47.         }0 q2 J+ v1 u  X3 R4 V6 s
  48.         else{
    , a, V5 W2 J1 m" Y' i7 ~/ N( U+ l3 d: J
  49.             DS1307_BuffToData();# U, L1 h. H4 E2 _% ]
  50.     }' w" s" ?. r$ j4 @3 }
  51.         return 0;       
    ( L. Y1 _$ t/ K: Y6 V
  52. }: t8 c- h* Q4 S# s& U( y
  53.                  1 T' |* u- `8 ?: N
  54. /****************************************************************************************** . r& B( l( h+ V+ M" l% H$ h" e
  55. * 函数名称: DS1307_I2C_Read()# H9 d4 ]' w/ m$ d
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    3 G: ~) D, T3 e- w2 f: O+ u9 R  {
  57. * 输    入: 无5 A, m" J9 }2 M" P( {7 w! p) c# }
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误
    3 b3 C7 w$ c2 ?0 c
  59. ******************************************************************************************/) \/ E) U# B& j, e9 {" d- w
  60. void DS1307_I2C_Read(void)
    ! }6 c1 M# E" t* P! b3 y
  61. {
    ! Z" q; C' a" }* e
  62. / z# G  G& M9 x& |. u6 P
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    ) D& i6 V8 l7 l( b
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    , H+ ~$ U/ B% q$ Q  E+ R1 J! j4 I2 H
  65.     {
    7 ^( t; x7 m5 S# H- R& q
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)3 T0 b- [2 R  f- j. f
  67.         {
    ) u; l' m  J: O
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");: W4 H( M- c1 |. @! t5 x
  69.         }6 O* i# x( s; i4 S4 y  {. u
  70.     }; Z* d2 `0 u( D! `8 w1 I  q
  71. - i, t$ u4 _# y& K$ t8 W6 U1 c- F& s
  72.         DS1307_BuffToData();, c" B! w" f2 O) x5 P; M7 v
  73.         5 K% s0 w. F/ b
  74. }
    % J* U/ L, z( l, q3 o& j
  75.   G0 j$ q, O, a: Y$ {2 D
  76. /******************************************************************************************
    ; ?( u6 }- e! P" _5 I3 I+ N! N
  77. * 函数名称: DS1307_I2C_Write()
    5 O( {/ c& i) M6 i
  78. * 功能说明: 将当前的日历数据写入DS13076 T  N( O5 l* N
  79. * 输    入: 无
    ' ?/ W$ l4 v5 [. ~8 M  l$ A, K
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误$ _4 J, K' U" e0 K, Z* o: n. s
  81. ******************************************************************************************/  j3 X. X  l6 g, S* Q
  82. void DS1307_I2C_Write(void). E* X2 }* e& p9 P9 D8 K
  83. {
    4 X3 e% Z: ~) F0 M% G
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中
      h3 [9 ]* @% I. v  {. a
  85.         3 o4 K8 [" c) I* G( f
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)! k' ?) z  \7 X. S
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    9 |2 S9 f/ H' i! g1 w8 e3 z, R% H
  88.     {* S/ I2 i2 f% H& {3 G9 a
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)6 Y- k7 B" P% R/ N, b, X/ B
  90.         {! x  D/ i& J* H
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    ' [4 r1 f$ Y7 W8 V
  92. //                        return 2;. c0 [* f$ X7 |: K  [2 ^5 O
  93.         }! Y* m! x, H! n1 O  a4 j  U
  94.     }
    6 n. {5 R) |- [1 G& o/ `) |/ `" H
  95. //        return 0;
    2 g4 g3 ?, }, `6 v! B
  96. }4 d% ^. L4 F  @/ p: @# l7 @
  97. - ?$ I4 g6 U' u, R4 h) V8 q
  98. /******************************************************************************************
    # Q4 f/ m, E" e2 g
  99. * 函数名称: DS1307_Chick()! ~; ]$ K% q- k4 x5 G; x
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
    1 }$ k' C/ A$ z& Z
  101. * 输    入: 无+ G2 _8 J- v; N2 L% ]
  102. * 输    出: 无/ [3 H6 k$ c1 C/ l$ Y
  103. ******************************************************************************************/3 l' |. E" m  N" \
  104. void DS1307_Check(void)
    ; Q" Y/ Y7 z  R: Q
  105. {
    3 m) p- N- W% _$ |& q7 w9 n

  106. 5 j& C7 Z1 s1 \, W) Q
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");7 ]' k, H( \/ _! M% K; J
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    " g  I8 w3 b, N6 _! Z
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK). \- F9 u& g3 G
  110.     {
    ( g1 O* N6 ~2 V; J& x+ H0 i
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    ; Q5 Y1 o4 i2 g1 I) B
  112.                 {
    ' a; _) @5 v+ y+ I
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    $ C5 E, O9 }. R
  114.                 }2 O! M, T5 r& e3 B, P' C, s$ _
  115.         }
    6 h# D0 v6 ]2 W4 y! _# l
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);  N! w# j7 c* L% H
  117.         if(DS_Buff[0]> 127){; l2 ^, C. b, I' U1 J
  118.         year = 2019;/ A9 v0 f+ @- @
  119.                 month = 9;! a' w/ c5 W- ~
  120.                 day = 18;" v, V) o* U3 \7 c2 k
  121.                 week = 3;/ g, \' z( C4 {. w
  122.                 hour = 9;; U# Y0 Q: p9 b0 ~. y/ @
  123.                 minute = 1;& M5 k* c4 E/ v8 T# x2 b
  124.                 2 X, m; w- s* J( |. f) C
  125.         DS1307_DataToBuff();
    ! t) C( i; _1 F' v( v. p9 x4 z, z
  126. 7 d# v( e( q4 X( }  Z) G( Z9 W
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)' ?6 s" ^0 o5 T6 v. q
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)' A0 O/ e4 \5 N/ k6 S4 V8 W
  129.         {" {! b4 {# Z: D7 g8 n  O. x
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)7 e9 h0 A) j6 z+ W
  131.             {
    2 M6 `; r4 b0 C& U  f+ ^7 C- W
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");( K, J0 Q, e$ ?& H! t
  133.             }# `; ^* b. S7 S- F$ K" c
  134.         }6 |' m5 y3 G8 x% w
  135.         }" ]) w  F* n1 s2 a" b" |3 h; h2 }
  136. }
    / K! D, B. W0 I( v
  137. 5 d* T# K3 r: U' d& H3 R
  138. /******************************************************************************************
    5 ~$ Z' N  Y" u8 Z9 r
  139. * 函数名称: DS1307_DataToBuff()# ?) Q" [( b+ o  V- q( W
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中( e. s; m6 Z4 L+ y9 m8 n
  141. * 输    入: 无
    ( P  O9 V& x, d+ P6 c
  142. * 输    出: 无5 G" s5 k* p! Q0 D
  143. ******************************************************************************************/1 l+ U* C5 x. }! E; T
  144. void DS1307_DataToBuff(void)4 H& F' g1 M7 L5 u4 b+ ?1 v
  145. {+ v% [0 o$ y7 u
  146.     uint8_t temp;
    3 v' {7 g( f! {' q& B- U: b
  147.         DS_Buff[0] = 0;                  //秒
    8 c$ T% |: f& C/ U
  148.     temp = ((minute/10)<<4|(minute%10));
    - ~  `* I# [+ \0 S
  149.     DS_Buff[1] = temp;               //分
    % p1 g1 E. a: Q" @8 E7 Q
  150.     temp = ((hour/10)<<4|(hour%10));
    ) o; s7 _' P! Q- p: c9 e  \
  151.     DS_Buff[2] = temp;               //时8 c3 |/ l+ o& I0 F3 u3 Q1 U
  152. : i: c1 \2 @6 d- B& M2 j. w
  153.     DS_Buff[3] = week;               //星期4 O+ L) r* f$ E' Y0 R* e) t$ D. M
  154.   l; M8 Z7 S! n6 K: h
  155.     temp = ((day/10)<<4|(day%10));+ w( [& J$ x, G! L. P
  156.     DS_Buff[4] = temp;               //日
    1 L& n3 ~' H3 y9 u4 x  d) L
  157.     temp = ((month/10)<<4|(month%10));
    2 r' W0 Z% @: q# `4 }
  158.     DS_Buff[5] = temp;               //月9 y5 Y' {4 E6 A8 ?! m, M, T; M- F
  159.     temp = ((year%100)/10<<4|(year%10));! `- v# F( J9 D$ m2 C3 w. |% x
  160.     DS_Buff[6] = temp;               //年
    * p3 c; B- l$ [, f  s1 w# B6 |
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波+ J7 N6 A& \# L# p, B& X9 o) g; x
  162. }. P0 Q8 K- X2 i6 e! D
  163. $ R4 S" P. r! F8 y# b( M

  164. " t% E- R* X- C1 u
  165. /******************************************************************************************
    # b7 \6 c$ \* h- G1 K
  166. * 函数名称: DS1307_BuffToData()
    / z& d  j% _1 T/ ]0 ~; X8 ^  L7 {
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中
    ) C/ o7 ~! z7 E- B. m
  168. * 输    入: 无* H/ u, m1 P! U% f
  169. * 输    出: 无6 h5 o5 F; n; w4 }! c9 s+ S' @; ]
  170. ******************************************************************************************/
    0 R" i4 J- l5 k; t
  171. void DS1307_BuffToData(void)
    + X; k# u; Q  r' H
  172. {3 z' c! \- N/ E) i/ ?5 E
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
    - p+ J, Y- p! n- u
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)( T  l6 F0 ^' h6 o7 t9 ]6 R& }
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
    ' R' r8 k$ F4 g% I
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    ) ^2 m4 i( o2 b* Q
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    3 F) g; d5 K! c, Y
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)( L4 R& i+ E4 U# e- I6 E
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年, P. u" I( m' C5 h
  180. }5 Y1 h( y! t: ?8 Y+ s
  181. $ Y5 [' w: g7 o# z/ Y9 m) N
  182. /******************************************************************************************
    0 {" k8 Y% h5 ]7 q) N7 {
  183. * 函数名称: AT24C32_I2C_Read()1 X9 f- q$ J, d% F
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)1 B4 @+ X3 }# c) }0 T  l1 v+ G' t, b" o- O
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    $ v( q4 t$ i/ w6 ]$ e7 d
  186. * 输    出: 无6 o  y- b: l& X: R" i
  187. ******************************************************************************************/
    ; W% J. i; C, {1 i9 [/ ]; H
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)
    / j# C: h0 s( r- X8 V2 ?
  189. {
    2 f3 \7 l2 i  b
  190. # ?1 O  g& X3 {: i3 m- X& F! {/ E& N
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)0 o+ }/ t4 D8 r8 E9 `  z* W; A
  192.     {
    5 L! ~- E. t* E6 j
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    + u; @8 U/ Q0 N; T: ~
  194.         {% e: u  q  b$ V! l
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");
    * G6 \$ r. Q+ O. o' L3 O& o$ w# Y) j! u
  196.         }
    9 z( f# e2 x$ {# w- _9 w, M
  197.     }; M8 s5 Q$ A$ U$ ?* w
  198. . r, D$ t; r" w4 ]/ s. v7 X
  199. }0 E% M. |" ]: Z" j) M
  200. . s1 i3 P- C  H4 R7 L
  201. /******************************************************************************************
    ) o( q  F# `( L$ b9 D$ q
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    + i$ N# l7 }7 o
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中), S! Z/ ?7 `' f/ `
  204. * 输    入: adrr(起始地址),size(写入的字节长度)
    + a/ O, y/ [7 x* Z) q6 N# z4 L
  205. * 输    出: 无
    , P4 u' Y+ y9 b
  206. ******************************************************************************************/
    ' {7 e, J3 l+ @5 O3 V- X
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    7 ^! \2 f; K: Q  R/ H+ Q
  208. {' T, ~: P# p/ ~: Q& W# G  G
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    3 R( u. @! C7 l# l, b, m9 d7 f/ Y
  210.     {9 x) T" }2 y& E& a1 b9 K
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# Q% x" _0 N6 H5 v; X
  212.         {: A0 y0 Z( g# M; o5 q  M% `5 s
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    & T( ~* Y4 o( |, Z
  214.         }& {0 y: ~/ G( C7 q
  215.     }
    8 L( z2 {+ {$ K: L1 n

  216. ' J" C7 v) d& V6 W: L0 n/ f0 ^- ~
  217. }
复制代码

3 |2 W$ l6 j# h! y5 [- \% ]6 u& d# v: p  o. M6 [6 s+ j1 @2 P
3 K. p$ u$ B( J' u$ p
, F: g8 u7 K+ o# P- g

# e! u( u6 a! l% a& W) U8 n/ T
赞 收藏 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 手机版