请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:
) n4 V: [3 C. q1 `) l I2C_Bus_Ok.jpg 3 m. U0 j+ n9 D) o% p

5 C( U0 ~8 N3 z    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
$ j$ j0 d0 h$ E6 R
  1. /******************************************************************************************
    4 @- l7 J5 n9 z4 I4 H1 e
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)
    / A" {9 `0 h4 O) A  ~& i
  3. * 功能说明: 写数据到DS1307
    ' m4 j4 a! y- Y3 ~, \( B5 H) x: t
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)0 ?+ M# E- E8 y# T6 N% \2 ^9 d% _
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误- E/ c% z: g2 N$ O( E/ R+ @) {, t
  6. ******************************************************************************************/
    ' r& Y! O3 a8 h
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    . A1 c: s: j1 X5 @& C: P
  8. {
    / Y0 n, s. z0 I1 U+ o- [+ K1 w
  9.     uint8_t addr = 0;
    0 `$ r3 X$ ]% Z
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中
    # g6 b0 l  {! {, G1 T! v
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    , e- X1 x+ X& {. U4 E* R' Q
  12.        
    9 R/ B  ?  D6 H0 F  f% x& K
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
    - I+ D2 l  N: Y5 e
  14.     {
    * N! m( I% J$ E1 W- J
  15.         return 1;7 H6 u# t/ a. Z! g7 C8 v8 v
  16.     }" I8 r: r" ]" ^7 M; U, m
  17.         return 0;% ~2 v( T/ @  Q) y" h9 W
  18. }
    : y2 s: X5 `' i$ r+ v9 i* p

  19. ! C$ s! O9 R$ z3 K  U/ E
  20. /****************************************************************************************** , _4 [) M% v4 L# P! |# Q
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)8 Q  x+ [9 y5 o6 X( J
  22. * 功能说明: 从DS1307读出数据
    ) j. L8 Q$ h; i1 Y
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)9 y# N6 v# E3 D1 ~' K6 j3 |
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误: f5 Q% p* j$ w& S: d2 O6 Q7 B# v3 ^
  25. ******************************************************************************************/% ]' H# d# _$ g( g# y5 K
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    " k& F5 X: {- M, e
  27. {
    9 V, @( D6 \. R/ V8 ]6 D
  28.         uint8_t addr = 0;
    % d: v; A+ X3 `0 X3 D8 s$ P
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    5 Y3 W5 D! L% C% g
  30.        
    . A9 j  ~/ E: I
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    3 A: j# d" g  ]$ B+ h. ]
  32.     {2 s0 ?8 x2 y9 X  @
  33.         return 1;
      f; b, b8 r) ^1 e# {  i
  34.     }5 l$ K2 f8 s) V- w4 v3 Z
  35.     if(size == 1){               //检查DS1307是否需要初始化( T0 D: [& Y4 v. T3 d
  36.                 if(DS_Buff[0]>127){; h( n9 k) `- R1 C* G3 {& I) b. m
  37.             year = 2019;, D, ~- v  h, [6 |0 K/ _
  38.                     month = 9;
    : j8 s& j" y3 a: Q+ }
  39.                     day = 18;0 r# w: x. y) q  Q
  40.                     week = 3;2 y: a" p7 y$ n' ]- K
  41.                     hour = 9;
    6 N5 l8 O. g- f( N) G, R
  42.                     minute = 1;$ A7 A; o( M* b: [* ^1 ?% D: h
  43.                 . Y) V" ]  o- o- o3 ~- i
  44.             DS1307_DataToBuff();& k3 ?6 d& ~8 P5 f5 r
  45.                         DS1307_I2C_Transmit(8);
    * O! c, D8 L. D4 d9 E1 \& |
  46.                 }$ F# m7 }8 \, ?+ ?, s
  47.         }6 @- I' f7 M: d( t9 b+ c
  48.         else{- z# ]0 D3 p3 m: k
  49.             DS1307_BuffToData();
    : ~$ V9 U  _6 ~7 \( y7 G3 ?' h# i
  50.     }
    5 q; B/ X2 m3 @% Y  B
  51.         return 0;       
    - c  ?) Z& q; _
  52. }
    0 b4 p% ?  t* D/ ^3 p2 L$ L
  53.                  8 x- X* D3 G. W% ]1 e0 X& X' n
  54. /******************************************************************************************
    8 k! l( r$ t' f% G) d; q* E
  55. * 函数名称: DS1307_I2C_Read()
    8 {: L; f$ x& h* x: }
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值% w1 q7 O9 q, v; c
  57. * 输    入: 无; K* f  \4 j; z' n
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误3 e7 r7 L; q8 \: [$ K9 y; o" X/ V& f
  59. ******************************************************************************************/
    & w9 ]- y7 P5 J% I
  60. void DS1307_I2C_Read(void), E: s* W! \9 T: Q7 E1 Q5 V
  61. {2 q( g0 P$ R4 h/ f

  62. + t! N/ r- P. N
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
      G) g6 u. K( f0 @0 E
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    $ A4 j" r+ j+ C- x" f6 Y
  65.     {
    # `$ x$ o7 {' |9 }' i7 q
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)  z1 T1 g* g6 X! f7 Z. N- L' s
  67.         {
    - Q( q$ ~8 m0 B9 l6 @: p
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");
    - y4 R; |* M, C9 z* r) p% b
  69.         }
    - k2 ~$ S; l1 R0 T5 _5 e
  70.     }
      v$ Y; Z$ a$ Z) `

  71. 4 R$ I% v) c7 _
  72.         DS1307_BuffToData();
    2 k5 q. ~( a5 X7 \6 T
  73.        
    ( D! l* B% ~) p& C
  74. }
    & G+ N. ~. I- T* E; `* R5 J( {

  75. : S  s' K5 u, N' v/ l/ L
  76. /****************************************************************************************** / M' ]4 M# M0 i2 H% h
  77. * 函数名称: DS1307_I2C_Write(): G( _( x4 g; z" O* x3 [: L9 \5 H. N
  78. * 功能说明: 将当前的日历数据写入DS1307
      X- {6 H( ?/ I  u( u7 W
  79. * 输    入: 无' }' y( [( W. e" q( T# V
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误# m  M8 _- C' B9 j2 ?+ d
  81. ******************************************************************************************/
    7 p% n4 z+ G) t
  82. void DS1307_I2C_Write(void)9 V8 e7 j# f' a- M0 [+ M! G5 y7 X
  83. {. V2 k" `- Y5 y. F( @
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中/ c+ m2 }2 B+ l. N
  85.         ) d* l4 `% d  o. z* F
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    9 Y4 A5 Y% }6 }; T/ l
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)  ~& ?1 u8 J+ ]4 I. U
  88.     {
    ! N9 Y* }/ E' E$ @5 X
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    2 B" ]' O3 m* o
  90.         {$ ?% F7 l7 m( N( ^
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    % z, c; s- S5 |# r
  92. //                        return 2;1 R3 E9 e2 M) c) [0 N
  93.         }
    2 Y: z8 F/ o1 x8 h( L
  94.     }( t: ]7 X$ P/ [1 k0 n* p3 G' T
  95. //        return 0;  U2 ?3 T3 ~2 g' \& h
  96. }# A) u. d/ @4 ]: l: \! `
  97. . s; z4 ?) I% a  X1 H7 E
  98. /******************************************************************************************
    # k+ F2 |4 y  D( i
  99. * 函数名称: DS1307_Chick()9 j; d5 `8 a: m% F' d- t
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
    % m' g+ W+ S3 @- I: X$ w
  101. * 输    入: 无
      g7 R+ f& n' n. A" q
  102. * 输    出: 无
    ) z7 W! Q- h  S* k( d5 a
  103. ******************************************************************************************/( s, r: \# c3 d$ j. u) b
  104. void DS1307_Check(void)4 `0 |& s, J2 z9 @& `; E
  105. {
    7 z8 v- t) p7 R/ p8 _" i
  106. ( d" y) k  p9 B  A3 `) `
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");# m: f/ s$ H, P
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    # i$ T/ h6 n2 U* n9 K1 X- X( m- U& l
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)" V* E# r/ c  M6 N6 Z0 T: Y
  110.     {0 s9 v7 |' M* X5 g  j
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)- I4 e% V- P; x3 y0 P2 v/ u: L$ u
  112.                 {2 \& W5 I/ E. h* p
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    - Y$ \* K/ x: @
  114.                 }0 }7 B$ F4 c. b3 u9 S5 w/ K
  115.         }
    2 A$ o# b6 F3 p! R% t4 C. S
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);- ~. Z! B# h9 v% _! a. b
  117.         if(DS_Buff[0]> 127){
    , V' N( M: i- G" p! X
  118.         year = 2019;! L9 X# H: ^: k7 V8 A1 L6 O
  119.                 month = 9;* _3 b6 G& b, q' \6 V; o8 ]# L
  120.                 day = 18;
      [# P7 K3 y/ Y  L* h" a1 B- e
  121.                 week = 3;
    6 o7 A! i" F: ^5 R5 w0 u. L$ M4 F% d
  122.                 hour = 9;
    % d8 C7 `: J% y( p
  123.                 minute = 1;( l5 _4 |2 I9 i9 z5 I
  124.                 1 N8 p* q0 p9 S/ D  N7 P4 X
  125.         DS1307_DataToBuff();
    & A3 L* W# L8 J: x
  126. : I3 Q! Y0 w* i% {
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)2 R$ f- X  _+ i  V/ ?. k* I  W
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)7 i% W8 v& o8 `; v& V  x  e
  129.         {
    - c! M/ W  ^' C. f, N4 q
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    6 [2 x! Y- P, Z
  131.             {
    5 q- p; r$ r8 Q, [
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");$ y% V5 U0 w# a
  133.             }
    0 ~1 T/ ]% a  p1 K8 V
  134.         }
    5 u( g+ @8 x6 W" n
  135.         }# F) U# l8 a% X. u
  136. }9 P; m0 R2 R1 b5 Y% |3 [+ q1 L

  137. # d; {2 B& l3 G3 a. R8 m
  138. /****************************************************************************************** & j* C9 H/ M% e/ b2 @9 c. e
  139. * 函数名称: DS1307_DataToBuff()+ N9 a/ R7 D2 j8 D$ u- N' b2 f: H
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中1 [7 D7 D7 J7 l1 U. {
  141. * 输    入: 无3 T3 A& y: T: S1 j6 M, h$ `
  142. * 输    出: 无
    . {. Q' x: @8 b" M8 L
  143. ******************************************************************************************/8 h% M' j* T2 O8 e! i
  144. void DS1307_DataToBuff(void)
    % V2 s6 L- |$ P- o9 `1 @
  145. {$ B; u6 F1 P6 ~4 l# L7 j& {8 Z
  146.     uint8_t temp;- P, o. n. @* i8 @" s/ A1 g$ ?
  147.         DS_Buff[0] = 0;                  //秒
    : v7 |# x1 V- c2 P  \
  148.     temp = ((minute/10)<<4|(minute%10));* n* a, H) ]: B; \3 q+ {" }+ y* S
  149.     DS_Buff[1] = temp;               //分: E$ L% _& ?( G' Q
  150.     temp = ((hour/10)<<4|(hour%10));
    . W% Q3 H9 N6 v; N7 T* p1 T- Q
  151.     DS_Buff[2] = temp;               //时+ ^  c+ F9 N: K0 n/ H: s
  152. & V- [4 `; N6 J; z* A
  153.     DS_Buff[3] = week;               //星期' u4 M: _$ e' u. J& ^) N

  154. ) Q* r$ z" |. I! v" W3 f* P
  155.     temp = ((day/10)<<4|(day%10));! \* \( Z6 ]2 E) Q0 o# u
  156.     DS_Buff[4] = temp;               //日; d" ~% H) ]/ _% V$ I% B. `6 z
  157.     temp = ((month/10)<<4|(month%10));  D" x& }+ I% G
  158.     DS_Buff[5] = temp;               //月
    - X: P: @5 X* r1 |, C$ s& v7 G) {
  159.     temp = ((year%100)/10<<4|(year%10));
    5 B% c, P( l7 \% L
  160.     DS_Buff[6] = temp;               //年- _/ t( l  k: ]; \5 n. e0 e
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    - l4 I7 Y+ s: c" R* f: U
  162. }! e7 D; |# A7 X: O9 K- R3 \

  163. + W/ i$ M' V: p/ a8 I( ?5 W

  164. # C$ F  g( Z4 D
  165. /******************************************************************************************
    * r( c* G* ]" K/ A$ T* q7 F* i# G
  166. * 函数名称: DS1307_BuffToData()& L, p+ J6 w1 d1 t5 c, E( G" S
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中
    8 U( s% U& Q1 e: ?
  168. * 输    入: 无! K# U# [0 K' L* _! Y) p
  169. * 输    出: 无
    ; |, P( |/ e2 q% Y3 u( Z9 u; q3 d
  170. ******************************************************************************************/( ?4 [6 \; B  N
  171. void DS1307_BuffToData(void)2 p) U. |: i3 F( x' a8 p
  172. {
    , Y8 m$ C+ J* F: ?0 I
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志
    / T" u% Z% ?$ E* ]0 C9 [  B  G8 p
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
    % B, ^% D  i5 L* U$ \* C' t. V
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
    3 A8 B! u3 f. Z% H
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    0 P; g( C  k3 o6 H+ Z& k
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)  v- P& O* r0 [
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)- ^, H! L! j, c4 }2 v
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年6 `( m0 D7 Q7 a( w9 P
  180. }
    0 \  ^: N, u& G, A  V) Z5 [3 x

  181. 1 A1 l: Y- W1 k0 _
  182. /******************************************************************************************
    $ e5 ^1 h# ]  ~" A  E; R
  183. * 函数名称: AT24C32_I2C_Read()
    7 C6 ^4 [3 ?4 J- P7 J8 ~
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中). [3 c# I% A- {' G; k; h! j
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    # J6 X0 m: f7 Y% {( X, P# i
  186. * 输    出: 无$ _! @" Z, G* X2 s. @; j8 `9 t4 B' u
  187. ******************************************************************************************/: v" F9 g, x0 N5 Q( O2 n3 @
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)4 Y% q( J9 V, U
  189. {6 k. K% s+ S- X7 n
  190. % i; J+ V9 B7 N
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    5 A# P7 N3 z; h4 c, S+ M. ~
  192.     {
    " i. f: o5 U/ b- j  ]
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    8 v' k* s. R* D3 A- I6 b, R; ?
  194.         {1 h9 |; d8 m5 ^" t, U% c- a
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");; b+ c  e/ g7 E3 T
  196.         }8 ?1 Z" w% R$ J4 D+ l- O) g! O" [
  197.     }
    + E5 _  V! `% _: r0 Y
  198. ) s2 L6 h$ ~: M( M, h2 g2 Z
  199. }
    0 u  L4 N+ C+ B) e2 A2 B  ?6 w3 P

  200. & ~, Z8 y% w6 W8 k
  201. /******************************************************************************************
    : w' `: R7 L2 J# m) q( _
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    , ^6 I: ]2 D5 N6 g: G3 Z0 c. ]$ s
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
      o" h8 ^7 `! L1 F8 K! Z
  204. * 输    入: adrr(起始地址),size(写入的字节长度)
    ! I, N" i2 Z0 `' ^( m. H
  205. * 输    出: 无) e/ S3 \$ A8 l9 e' F
  206. ******************************************************************************************/
    $ t& L8 s1 @0 _  X& P/ V
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    0 N1 e, h6 V# _7 s9 r* p  e  }
  208. {0 m" M! a3 g7 K7 g( I! W/ o2 u
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    % j' Q7 a9 o, P' k; q0 e- {
  210.     {; r* X0 L3 s5 o
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    4 f7 n1 o+ K2 b9 U4 @  P
  212.         {4 U/ ~& y9 }- z% h
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");* H, W7 |0 a3 ?% Y) i
  214.         }
    $ h6 _: S3 B! o1 V
  215.     }0 y: @3 R/ h( P
  216. 6 E# h9 R! A. i6 `5 F
  217. }
复制代码
) p' l, c9 }, V

# S* t2 c; G+ U7 r0 l
# Z# r0 I- C" D# y) i" g+ F+ ^' {$ r: B: W9 w' c

, Z6 Y& [  j. l' w3 P4 s
收藏 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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版