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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:, u' b+ J' R2 y6 b$ B' K
I2C_Bus_Ok.jpg / z; B8 @/ _% g2 N5 E

- r- ^# }% [3 e    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:) `* K* a1 X2 `2 a* Y  U6 H% a1 o
  1. /******************************************************************************************
    6 o" G4 [9 Q; z% ~8 R
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)2 S/ }0 b$ s6 d' g/ K
  3. * 功能说明: 写数据到DS1307
    0 U6 M4 N9 Y1 L
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)# D% h" z2 A- d$ Z/ ~, Y
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误9 v  k8 Z5 t- F- F7 o0 l8 c# E
  6. ******************************************************************************************/1 u+ L3 p/ _' u) ^
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    6 d8 p5 `- {/ y8 z% l
  8. {6 \; \+ w1 d( z7 Q3 L, U1 h9 M
  9.     uint8_t addr = 0;$ X7 n" s: X2 {( s4 n8 g
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
    3 _. r" S5 ~7 C7 Z
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址- a5 z3 G0 ]0 E5 m0 b# S* k9 M: b
  12.        
    : I1 t0 u: Z5 Q) p8 a
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)& B3 t( a7 H- o. Q4 y
  14.     {
    , f7 Y# _* Y9 m. _
  15.         return 1;
    ' y$ _$ s" z; x2 c# S1 q( r( n
  16.     }$ K! h$ y( n0 l. x& ^% i3 [# m) K
  17.         return 0;
    : s9 c; W* x, M  x" \
  18. }
    ! x; c0 @5 D0 O7 _2 A+ Q

  19.   G1 F: U  H8 Z! Y8 F; Z
  20. /******************************************************************************************   f# K5 G$ J$ r9 B: S$ g
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)7 Q, O6 ]/ V2 u
  22. * 功能说明: 从DS1307读出数据. z# O6 g# `' v$ r9 Y4 @
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)' H& U; W+ z7 C% V
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
    # t% l# h6 Y( h* x
  25. ******************************************************************************************/$ i5 Y' @0 }5 c; x8 a- s; g
  26. uint8_t DS1307_I2C_Receive(uint8_t size). l! j& G$ T1 [. z& x
  27. {; q1 G8 b( W, S5 }6 P9 R. U
  28.         uint8_t addr = 0;
    ' @. T1 n! P  D' @4 w
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    ' u* L( J3 J4 e  c
  30.         . V) h  g2 F; [/ p" }
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)6 L" [4 k3 n* W3 B% l
  32.     {
    % f0 q. U7 K/ _2 ?  ?* h9 Z4 d4 h
  33.         return 1;% W9 p+ x4 U& q, i) Y! D7 K$ ]( r
  34.     }
    # h& x& R$ _( N
  35.     if(size == 1){               //检查DS1307是否需要初始化
    % [1 C8 q( j1 i* X; M
  36.                 if(DS_Buff[0]>127){
    5 _( V" l* N, H8 L
  37.             year = 2019;7 b2 q- K$ j7 Z7 c/ k3 B
  38.                     month = 9;" a/ i( l% E3 {% w
  39.                     day = 18;6 Q% [$ n6 f1 H" l  @
  40.                     week = 3;1 ?: r+ b% ]5 \5 m+ m5 J
  41.                     hour = 9;
    2 Z  K! r9 {% N2 A3 `
  42.                     minute = 1;9 O: s$ {$ M+ `" a2 ?& F9 |" q* m
  43.                 # |5 {- t7 a9 N: K6 d% g
  44.             DS1307_DataToBuff();8 y- p! b9 _5 \6 Q. Q
  45.                         DS1307_I2C_Transmit(8);
    % [1 w' v$ ]0 b
  46.                 }
    & B. q6 d2 b2 y% K  G; w
  47.         }# z1 ~( z- v2 W1 v8 j* T
  48.         else{# l2 B  @5 V9 B& Z3 F0 h
  49.             DS1307_BuffToData();, l' }  R) q' V  @! l4 p9 \
  50.     }
    ! x  S, n3 R! B  ~- C2 o) x
  51.         return 0;        . v3 D" b! r, e& w& Y& j
  52. }6 l, R! \/ g/ C5 O3 S' z9 D3 x
  53.                  
    4 W0 L# N- _: F) j9 w/ u" j. x1 l
  54. /******************************************************************************************
    5 h9 Y9 m% G$ ?9 P/ w
  55. * 函数名称: DS1307_I2C_Read()
    9 B3 [& ]2 J+ C
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    8 }7 `0 Q/ q0 C  V
  57. * 输    入: 无
    6 k( t8 R! @) Q! d. K) z
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误2 G) P9 b0 b) Q* G5 O0 T" k8 {
  59. ******************************************************************************************/
    # |* w# J5 T6 ~* Q* t  ^
  60. void DS1307_I2C_Read(void)
    7 {+ P! e+ F  u" ?3 v+ q
  61. {: M' _- e# B& x% h0 B9 h
  62. ( q7 w' s( F. i  [  H) [8 J, n% y
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)$ j+ O$ Y7 i$ r! ~
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)8 @* ^3 N) V0 `9 E* |
  65.     {
    2 {2 W$ M7 X% H) M* O' v- j6 ~; x
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    2 M* B$ e6 _! M% c5 R
  67.         {
    , ?" g# r) ]& j# @" ]$ t
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");
    + l0 Q2 k2 s' ]7 v4 J& A& g7 ?
  69.         }) h/ C- b) C" L0 X
  70.     }
    - n$ S! |7 Z/ Q; s

  71. 7 r5 i2 e  w% D8 @
  72.         DS1307_BuffToData();
    2 x! z8 `* Z/ @# ?2 t; m+ O! O1 x4 f
  73.        
    2 r9 j! S! @7 j; p0 w
  74. }
    0 S* Z: Z+ M8 s: v
  75.   ]  j% k' [; Y3 e# q# t
  76. /******************************************************************************************
    ' g1 _/ [4 i5 H' y, l7 C: v
  77. * 函数名称: DS1307_I2C_Write()  h3 w) Z" U* K6 e" b8 ^8 |# @
  78. * 功能说明: 将当前的日历数据写入DS13071 S' _7 o8 O) O$ X9 v
  79. * 输    入: 无! e/ ~5 Z% m* a
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误
    ! Z8 Y8 X7 @& ?$ U0 U" Y
  81. ******************************************************************************************/! L9 O5 ~) `% q: [; e8 B
  82. void DS1307_I2C_Write(void)' p) J" U* q* n6 _1 a' P
  83. {" Q7 C4 i- P) r6 E
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中% A8 ]" h$ p. O4 {! _/ H& |
  85.        
    : l! |+ Z8 R9 N! c% }/ d% l* H  I; C
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    / h1 p! K, f& x* I; x$ _1 S/ [2 O
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)  A% Z; f/ r9 \) y- R3 R7 u
  88.     {
    $ E; Y! n9 ?; L5 l
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)0 w. C( a. k7 y$ b
  90.         {
    ( r; ]- t# w$ z6 [- Y
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    2 l6 s. B. S% j4 h' _
  92. //                        return 2;$ F3 [% A( A# f% j- `% s
  93.         }1 E; y0 [  S' V$ f+ Z6 L) x$ Q
  94.     }. b( {8 e- i0 c5 S# J  u% Z* j+ [+ m# }
  95. //        return 0;0 Z) n# \2 N+ C. O: ?$ {
  96. }
    6 l& e  i0 ]% z/ {
  97. . X% F' Y0 h# Z
  98. /******************************************************************************************
    4 p$ ^  s" M2 p) B
  99. * 函数名称: DS1307_Chick()9 g+ c* p' }' F/ J! f' _
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
    1 M) P4 p* O2 T# k+ \
  101. * 输    入: 无( h! ?: U5 J- |$ g- }
  102. * 输    出: 无9 K  {0 b% U( l, {% ?: W7 Y+ b
  103. ******************************************************************************************/& o/ U+ g# I7 r" N) G$ S6 e
  104. void DS1307_Check(void)
    + y' E' x2 [2 ]/ i) r/ g8 X+ P! s' A
  105. {
    9 Z7 g) |( z, b

  106. ; {# G  B& o: {: W
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");% W* W5 S6 p' G/ }6 i
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    ) E, a9 z! w9 y6 ~2 t- P; @
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK). s4 S7 v. X* G
  110.     {) N- x, `3 P/ j& y
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)7 M% a/ }) J# j7 _9 J
  112.                 {
    ! P7 j1 t; b" Z
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    $ k7 Y- ^' I5 S
  114.                 }
    " E2 H  z$ N1 }( G+ S- l
  115.         }1 F9 I: g, y$ I3 \) Q! V
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
    . c& |# n( j+ G
  117.         if(DS_Buff[0]> 127){
    8 v) h' @% u) d9 I) ?7 m2 d5 G
  118.         year = 2019;
    5 t/ k' Q7 ]2 m/ @
  119.                 month = 9;# i: R# ~* D( {5 S1 a. a- L* C
  120.                 day = 18;
    1 R, o& g$ j( ?8 r: X* u3 O
  121.                 week = 3;/ ^$ ~( X3 J9 {/ f7 p$ O) S
  122.                 hour = 9;* B% J- L5 H8 i+ N
  123.                 minute = 1;6 w! F6 u- M9 S
  124.                
    " @# h) J$ `& z  G; M
  125.         DS1307_DataToBuff();& b& H& b5 H0 D

  126. ! Y! C7 `( A5 L- p. W9 q
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)1 b, V5 l6 U, }
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    5 B3 N, y% l& B8 w$ o
  129.         {
    + s* }+ ~/ {3 T6 K4 y
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# }' t& F( F1 _5 g
  131.             {
    5 A: Y6 S. z$ J
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");$ Q! n8 W0 \/ W6 v" c6 H, T/ F# ?
  133.             }
    " L  L% K4 l) n' [/ D
  134.         }/ J" i0 v$ j0 K
  135.         }
    / i# D( Q1 C) j2 c5 a
  136. }
    % N. X0 d  G% }
  137. & I2 M( n+ ~5 u
  138. /******************************************************************************************
    3 {* u- ]4 r/ r, x
  139. * 函数名称: DS1307_DataToBuff()
    , g, Y+ o  X2 E3 ~+ Q
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中
    7 l9 |& N: a( A
  141. * 输    入: 无! d" [3 g. C3 Y, k" U; w% ~
  142. * 输    出: 无
    7 k; N$ U# O3 I9 W: s
  143. ******************************************************************************************/
    $ ?2 ]4 b8 v# g
  144. void DS1307_DataToBuff(void)' {4 F$ M* y+ X) T4 I  A
  145. {8 Y) C- v- l5 V
  146.     uint8_t temp;
    . l3 s7 ^' W- z
  147.         DS_Buff[0] = 0;                  //秒
    ! {9 T, R6 X8 F; P
  148.     temp = ((minute/10)<<4|(minute%10));- X! P1 z. S  m
  149.     DS_Buff[1] = temp;               //分
    9 g/ O+ j" D0 j+ {5 L! H, i* Q2 D
  150.     temp = ((hour/10)<<4|(hour%10));( R7 d  \/ [! I/ W1 Z" ^8 {; M
  151.     DS_Buff[2] = temp;               //时
    , n3 ~3 A" M  ?" @1 b* `: S4 s* J

  152. 9 s; W+ d6 o3 ~8 k- h6 o/ s8 B# A5 P
  153.     DS_Buff[3] = week;               //星期
    . S% t0 G# }8 C) }5 F

  154. ! C2 v1 u$ t( y- g$ f
  155.     temp = ((day/10)<<4|(day%10));
    : \& E9 R" ^# h* @1 n
  156.     DS_Buff[4] = temp;               //日- R& Q8 L. l2 Y$ S' m
  157.     temp = ((month/10)<<4|(month%10));3 d, ^' Y1 a( i
  158.     DS_Buff[5] = temp;               //月4 l+ p: H6 K  e- E* h
  159.     temp = ((year%100)/10<<4|(year%10));- ^. a% f" V& @
  160.     DS_Buff[6] = temp;               //年
    ) X: N% R' M  d5 i
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    & |7 X( l2 _/ x4 `+ s5 c
  162. }# }+ m! W% F5 E8 k! O

  163. . m8 Q# Z! o2 J- q! e: i

  164. - v- ?& l: V, P; |
  165. /****************************************************************************************** & ^0 m; t* z7 s8 D5 t
  166. * 函数名称: DS1307_BuffToData()
    4 u0 W3 @2 V; `: `/ _9 z( I
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中
    . z: A& I/ l, K5 Q: v- P  C' o
  168. * 输    入: 无& I, ~. L6 `. U# ?3 {6 o2 B
  169. * 输    出: 无
      z$ {2 ^/ C7 O7 a9 n, J0 m
  170. ******************************************************************************************/8 j6 X/ E8 r, j- S) U
  171. void DS1307_BuffToData(void)& k! F& W& u' @& j
  172. {
    ) d7 j0 A0 R6 t6 @( T; S' \
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
    # Z  S' d" Z: }' K1 \# t
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)+ R0 P1 m) Z) T) [: X2 D
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
    : q0 @5 D1 V  ?/ J2 U4 a2 E
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位); p4 o/ f0 z" v* e% _- c5 P
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    - h( L" V( B" P) ^( c  v5 N0 m
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
    , U8 T9 t; W* g- Z0 m% N  X
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年; ~. m0 w2 k, B1 `
  180. }/ k3 x6 Z+ `5 z% e% r/ P
  181. ; H1 J/ H7 x* R$ i* K
  182. /****************************************************************************************** 2 r+ n* C( V, S0 P+ ^; S, F7 F4 t
  183. * 函数名称: AT24C32_I2C_Read()
    & z8 W. V  t+ j7 a' M4 y% {
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)' i2 k! S9 q2 Q& [8 y% Y) [
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    , h. i. X- Z- w& G7 Q0 c
  186. * 输    出: 无! u5 Q# [" s0 V
  187. ******************************************************************************************/7 K- `/ e7 v% }/ @' A% L
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size). _1 g: a. O# Y; k* g
  189. {8 P% w' m( U" [& P" S4 a

  190. 1 W6 D8 X7 H- V6 t" K" V
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)/ B" _2 C. T" `) ?
  192.     {/ a! t, Q7 @: _5 t1 V/ p' H
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    , e3 l5 X8 a& W0 H. `; b( Q
  194.         {6 M+ P9 x% |% |/ _  M+ E$ q7 M; k
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");! O2 H2 u( {6 t5 p" N6 P" P  |2 c
  196.         }9 f% V: Y9 G( N0 O* g
  197.     }
    $ s4 w) v; V% N, c& l

  198. # W- A2 c8 a# c$ r( i; r# [4 W9 H; N
  199. }
    $ P; Y5 `  Y0 ~! ^% I
  200. ' z4 N" L, \7 E+ X$ |' h
  201. /****************************************************************************************** 8 y' Z5 V# l8 P' f  |. ^  u
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size); {+ h9 v! K3 r; V# t
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
    , |, w7 n" ]; X: x9 S
  204. * 输    入: adrr(起始地址),size(写入的字节长度)+ d6 R8 ?2 A  R4 i5 ^9 ?/ F
  205. * 输    出: 无) e5 y: W6 R' k# [, u& L
  206. ******************************************************************************************/5 F% b( `  T8 B$ a
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    5 l) ]- r* R' M, o
  208. {7 {+ O, p) i; U% d: A$ ?
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    ) R- r- M4 I: V9 Q2 t9 w) ^
  210.     {
    ' ^; J+ i* s  d1 \. B: m
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)8 z0 Q% E: i: q) o
  212.         {) b! X- a" }+ C9 M$ |$ @- y/ D
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");* ]2 L  d/ }( g# Y  q0 E- ^
  214.         }
    4 @" O* b$ \  X$ L
  215.     }  n& z& d! {' K8 U4 C2 L2 b* G
  216. ; W+ V) C% y+ j. T# s" g& o  T$ L
  217. }
复制代码
7 e9 h/ R- A# l7 Y3 |5 H' W
: q8 S' J/ b  m" m3 a

- t$ D: }0 ]4 o* a; D; S
: e/ c  M6 p! w' G$ s# t" A" j1 E: m8 x% l7 q6 O+ 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 手机版