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

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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:: i/ }' f1 m/ C$ O
I2C_Bus_Ok.jpg 4 z$ G5 r. c, m3 H% F' l- h" g

1 @' ?# h" v. \6 ~, M8 W    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:" w' G  U  t3 U8 O
  1. /****************************************************************************************** * P0 v0 t, X+ y- W# k
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size)- F9 G$ ]( H6 c4 I2 }+ N
  3. * 功能说明: 写数据到DS1307
    ) f  J  G: v/ V, d$ Q' W, Y" q4 I
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)
    0 |- i1 T% L4 p2 Q0 s
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误
    . X& ]( s/ q/ u  B4 H
  6. ******************************************************************************************/- y) E" D* X% m% n5 v4 |% i$ u
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)" {8 G+ H! }! E6 _' f  Z2 j. ~. K
  8. {
    3 e& B8 j1 \  A2 t$ U
  9.     uint8_t addr = 0;
    5 @% P4 o" e4 D4 l  _$ _, q
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中! Z, K/ m1 i$ |$ R
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    7 v) _9 u- b/ t0 y* O' K2 L1 V
  12.         + w8 i& y1 a1 a" g+ C8 e5 l+ ^
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
    + J# D/ S2 o0 f6 r" _
  14.     {
    9 y2 w* n. M# O7 W' _' T9 @2 b
  15.         return 1;
    8 U' L3 N9 e7 I7 v5 V
  16.     }
    + q& Z7 U# F/ k$ T5 D
  17.         return 0;
    % W! y# J: V$ ~/ X
  18. }" |7 g" o1 h% u- u! S) @

  19. 8 G/ N( n+ ~5 B6 w& N( s  Q, c
  20. /****************************************************************************************** 0 r) a% Z9 d' u
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    ; s/ y: E8 O/ z$ _
  22. * 功能说明: 从DS1307读出数据
    6 e0 C) g) Z2 ~3 G
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)/ C7 N6 n" }' s. z& A- z
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误( h8 c( V  n1 b% Y
  25. ******************************************************************************************/
    4 Z5 r# ^# X- ?, ^9 H6 {* T
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    , ~, z# i+ @8 x1 h2 Z" K( `
  27. {8 m, q) K; L1 l/ Q( }% Q1 E
  28.         uint8_t addr = 0;
    . m& \% D2 l& j5 H2 U9 x! ?- ~
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    7 ]' r! c2 s2 L
  30.        
    ( h' n4 N- `' h% u. K
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)* K/ m. h% s- b/ O4 ^
  32.     {
    # m+ N9 A0 _  `/ @1 ^* R. Y
  33.         return 1;
    # ^. d. D3 b. y  N
  34.     }
    # R' @) m0 w. ^3 v
  35.     if(size == 1){               //检查DS1307是否需要初始化
    * f/ J! d- l/ Z* S1 \2 M4 g
  36.                 if(DS_Buff[0]>127){1 h* t2 B+ H% A3 V1 e& g7 V( c2 {
  37.             year = 2019;
      m8 e1 _7 _- c+ F
  38.                     month = 9;
    0 A3 W" U0 }- m' r+ D  k( ~
  39.                     day = 18;
    . t1 R- [0 G; M9 ~- B# F( A3 I
  40.                     week = 3;
    % H" L$ W9 H8 L1 F$ S1 E
  41.                     hour = 9;
    4 v2 s! d9 d4 x
  42.                     minute = 1;2 n8 o: q: t4 k$ N* n+ P0 P
  43.                
    8 t, y- v& y$ L
  44.             DS1307_DataToBuff();
    1 x8 V7 S9 t3 `; O. L; F
  45.                         DS1307_I2C_Transmit(8);* {' f' @" J  Q* z. @9 b
  46.                 }
    & d- m  d1 n/ F- i
  47.         }
    ) L$ G) c: p7 p/ r
  48.         else{& P/ J. q6 D3 O9 j* A& O1 k
  49.             DS1307_BuffToData();$ Q. _; u* m% B1 V- `
  50.     }" h. G1 O/ q; ^2 N4 [3 [, t
  51.         return 0;       
      k3 @& B! E: C9 h$ @! v1 J
  52. }
    * `0 K' O0 Z( U" m* A5 ?
  53.                  5 d" A2 t0 f3 \% _, O' ?* c$ y
  54. /****************************************************************************************** & z0 C' t* j3 q# F$ V8 _; C
  55. * 函数名称: DS1307_I2C_Read()8 n& S- h) l; ]1 K2 d* F4 \( h
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值
    # f3 l6 U6 O) j% G
  57. * 输    入: 无0 O! l+ C7 l) e
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误! G5 `% S* p$ z# j* t( x
  59. ******************************************************************************************/4 |0 f1 q& J6 D; {6 ^( u( E
  60. void DS1307_I2C_Read(void)! E) W4 V- a1 ]8 D- v9 S, S
  61. {/ b" C8 H1 F& N

  62. 2 @! m. b& d6 K) R9 S6 Y3 N# M6 [
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)( P- E8 r& ?3 R, T- i: z1 r; J' Y( ^
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)
    ; |0 U) C7 b3 V' u, m$ X
  65.     {
    ) o% Z( G0 e" G. u
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)7 C9 w+ j* W% G
  67.         {6 l/ k8 j6 X' d( E1 V+ c1 n
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");. M) @& K) L. m" U
  69.         }$ v6 Q' c% t% I9 ~8 z1 X
  70.     }7 w! i' Z0 D0 B

  71. ; M# U9 R; T2 P& c6 G2 T5 J
  72.         DS1307_BuffToData();% _) y  B) t- R2 b. a
  73.         ' K1 R( G8 E% h- W
  74. }8 X7 M, q1 f# U( a

  75. 4 V, J0 Q& p# @+ Y* D/ y* v1 r, E
  76. /******************************************************************************************
    / Y" c: _! t3 f5 X8 O4 V+ l( e
  77. * 函数名称: DS1307_I2C_Write(). ^; I$ q4 d2 \
  78. * 功能说明: 将当前的日历数据写入DS1307
    : k* ~8 @" ]$ n! c, H/ _/ V' x
  79. * 输    入: 无/ u3 A  t7 P- x' }+ G
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误/ G/ a( E# C" K, T) m. h; `+ C: a# n+ X
  81. ******************************************************************************************/
    ) |8 Z1 B+ b1 k' i2 x
  82. void DS1307_I2C_Write(void)
    1 C9 t& r) q! M4 w3 L
  83. {1 m8 ?3 I* [9 i1 o& D$ C/ w
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中
    * [: A$ q( F3 r; h: w' ]: `
  85.        
    / M2 i; H; l' m' m) E
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    / I& M. y  v% p* Y( x  i
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)3 h1 B! u8 p3 g" F0 k2 f! I* ?7 P
  88.     {
    3 H$ ^5 [( B5 a, t/ b( N
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    + [6 d- X$ g: @# l: {3 W* k! _
  90.         {0 |7 L0 C/ s9 G
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    5 [6 ^$ c, l( h' E+ K0 j
  92. //                        return 2;' O0 t4 q) T3 t& f
  93.         }& ~2 O) i5 b" v  W9 d2 v
  94.     }3 ]: h( r1 G2 q7 u# t2 {* o6 \8 j, u
  95. //        return 0;
    8 u! \4 N/ C0 Z7 v1 Z2 R% L( c1 y
  96. }0 N# c" }8 q4 P2 r/ e9 O

  97. ' a7 k1 W" [* E0 }" z; o
  98. /****************************************************************************************** $ c8 w( ~# e4 T& J, @' v
  99. * 函数名称: DS1307_Chick()5 t0 v! i/ j% `& P& z$ `0 s
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
    3 e: j8 r: ~4 }/ |( v$ y/ |1 q2 L
  101. * 输    入: 无2 d# p3 \+ J  T4 w
  102. * 输    出: 无
    / ]  I- }1 b: U; s3 p" v
  103. ******************************************************************************************/
    ' f1 J' Z& J! Y2 M+ J
  104. void DS1307_Check(void)
    $ w/ L; y3 p$ p: q! J" G) j
  105. {
    1 L) d4 A8 _9 s( q; ?/ h$ _

  106.   l9 L$ H  _4 N: ~$ v: o
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");* ~, h) v+ v3 l9 o8 C& E9 @- S: c
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    & K  [* h7 K3 l2 M. c
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)8 f! ?8 H  p; L! z+ i5 z2 j  y9 J
  110.     {
    % z# l8 |, ?4 r3 Q6 t/ h6 i& ~
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    0 X/ Q) E2 A* R& m
  112.                 {* h* S# n6 W/ X6 e
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");/ C5 _$ [  \8 N! d
  114.                 }% y& o# i. F3 B0 C' N1 e
  115.         }7 A! ~0 H  M+ X8 p' g8 n4 c
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);
    7 E+ _. ~  V; `/ m
  117.         if(DS_Buff[0]> 127){- _* x' U' i6 R4 X# G
  118.         year = 2019;% m/ R9 |# U. r5 [/ V7 D
  119.                 month = 9;) I4 y- j* ^( }0 o5 V) F
  120.                 day = 18;
    / w" m% x/ l: @
  121.                 week = 3;
    $ i! n  d1 c) d4 s
  122.                 hour = 9;
    0 Q7 S0 _- u/ Q. z+ d! P4 y
  123.                 minute = 1;" {$ A" A7 @2 X, u) A! m
  124.                 ! g/ e% ?( a  f+ D
  125.         DS1307_DataToBuff();
    3 r2 t0 x' s7 t" M9 Q

  126. : h7 h$ Z, F9 _! G8 O* Y- t
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)' n0 v% e& [9 w
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    ; R0 O/ Z- g: o9 P
  129.         {- S" p) \  s7 i4 S6 r: x
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    * D, {, O6 X/ e& V7 I
  131.             {
      ~/ k6 n5 g, ^; w; F9 K9 _
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");
    % U0 n% P9 z$ h3 [$ D  A1 u8 Q# Z
  133.             }" Z. X) J* k- A. ]" Y# M; B
  134.         }
    . u& F: a7 y, {
  135.         }
    & U9 h. R! n0 Z( e6 m
  136. }7 a( ]. x% Q1 e1 o: y

  137. * j3 P; m6 Q5 \0 n- H1 U+ r8 V
  138. /****************************************************************************************** : J+ G, [; ?. I( ?; D# T# P% B% o
  139. * 函数名称: DS1307_DataToBuff()) A& S0 s# s6 c# B! y
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中
    2 R! d! F0 Y# c/ ?- }  m
  141. * 输    入: 无3 O- e; v/ D0 N+ w: U' ^1 W: y
  142. * 输    出: 无" H) U4 n" [, u- t2 {' M
  143. ******************************************************************************************/
    0 W) H6 _& @6 x' y: h! T  L
  144. void DS1307_DataToBuff(void): C) r5 X6 B0 l8 n& o
  145. {- e; C" m; O: e7 |  B/ z' ?
  146.     uint8_t temp;
    8 l" \1 [  r) H) K- q3 \
  147.         DS_Buff[0] = 0;                  //秒
    : b# ?! {3 K: c5 l/ w
  148.     temp = ((minute/10)<<4|(minute%10));
    ' s8 y7 }5 U" h. X
  149.     DS_Buff[1] = temp;               //分
    * T' H/ ~+ f' e/ m
  150.     temp = ((hour/10)<<4|(hour%10));
    % C" o) a6 G6 m4 w- r
  151.     DS_Buff[2] = temp;               //时$ [# `. t* h' R3 s( A
  152. 1 b/ v% ^" E* k* @+ ], k9 G# n
  153.     DS_Buff[3] = week;               //星期# o; w7 {7 L5 s8 d) F; j7 u% O

  154. ( `/ H4 i/ [$ x2 b7 L- I8 U
  155.     temp = ((day/10)<<4|(day%10));. N' `6 m+ K. h: Q4 Z
  156.     DS_Buff[4] = temp;               //日+ \$ k# M/ |) q! o( |0 R
  157.     temp = ((month/10)<<4|(month%10));
    # L# N4 @/ |4 k8 ~
  158.     DS_Buff[5] = temp;               //月
    2 b9 |( k5 S9 A: M$ h0 ^5 ?# b
  159.     temp = ((year%100)/10<<4|(year%10));
    % |( D8 Y, J; v" Z9 ]- D
  160.     DS_Buff[6] = temp;               //年
    - Q1 l7 @+ h6 [8 \- `* `  t
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波7 }/ R9 W; X+ A' K: X/ c
  162. }  {' w! d7 K& ]9 v  Z
  163. . F3 w$ C  F% E8 t
  164. 5 x6 Q/ C$ v% B: N
  165. /******************************************************************************************
    # P) |/ S/ b  b$ h  G. P* A
  166. * 函数名称: DS1307_BuffToData()
    . V- X- L2 B6 n( A$ U9 P6 W2 b
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中0 S% \5 p3 j" U& s; o+ }- I
  168. * 输    入: 无
    ; K; Z( F) e$ C) r$ b6 ^$ M4 @
  169. * 输    出: 无. N3 O9 p( o4 g) o6 B& i
  170. ******************************************************************************************/' p' c! Q6 b! |' n4 b
  171. void DS1307_BuffToData(void)
      P3 D4 x0 i5 _. Q) C& \3 x
  172. {( ^4 w1 F  O" l3 `  Z
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志, [8 C6 x/ }) [7 O( y' D
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)5 `/ X" |! D+ g3 f! `2 D
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
      M; w. c# V) f/ Y' D8 P
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    8 Z: {5 l) T4 o" V/ R$ Y. J  }. q
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)
    + ?7 b4 @- v* @
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)
    " U5 y! g$ O; K4 [. z' ~
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    # C$ i7 N0 |6 L, ^
  180. }8 o0 i& a- I0 j0 e# k" o/ K# S
  181. 8 Q0 |$ l, O2 D4 i( X4 F2 F
  182. /****************************************************************************************** " A# n0 n9 P) p) ~* \
  183. * 函数名称: AT24C32_I2C_Read()
    ( W. }7 @5 h' }! Z+ F" j3 w( g
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)
    ( l, n0 x$ l2 a8 F
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    # `- B+ _! r3 h3 s0 e! Q4 G" C4 ~! U7 Z6 ]
  186. * 输    出: 无
    * [/ u! s: K9 q1 f/ ]# ~7 E# L+ l
  187. ******************************************************************************************/2 a+ e! H$ J/ q' W
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)5 ^$ ^3 Y& }# I0 \9 v
  189. {4 F: O  r" R5 b4 _4 C

  190. 2 o( J1 `! g) u: s0 S  x6 o1 P
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)9 ?, y# W0 l# U1 t! i3 X
  192.     {+ x- _7 S, c, ?* U  w0 W
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    4 g- H+ i3 ?  ]2 r, N
  194.         {& H) \) G, A* Y: v
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");2 J4 K# O, u# ^7 H$ K
  196.         }
    ( v* k  L" H* ~
  197.     }
    $ U: ^* ^* a6 p; G7 o
  198. 4 r2 T6 L, x5 E% F. x7 O
  199. }
    % O4 k3 s& \4 P1 b' H
  200. # k4 \8 u  s( \, {7 P0 O% p
  201. /******************************************************************************************
    ; E9 b4 y9 s" \/ t  F- r9 `
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)+ d' V' l- g& j
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)
    7 p# e' l3 T/ Y
  204. * 输    入: adrr(起始地址),size(写入的字节长度)' j6 S1 t& D9 J" a6 K8 B5 O
  205. * 输    出: 无. `" P; S7 `& o% n5 H# w; u# L
  206. ******************************************************************************************/
    & {6 X, H" U9 i
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)) A; `9 s4 p: @( ?
  208. {/ K% Z( y3 Z$ z/ B9 E& _$ q  p8 R
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    ( B- j6 C3 e7 x6 H3 f
  210.     {7 l( y+ i1 E5 {3 I% e  c
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)0 u# ~2 z+ y' @/ A! v
  212.         {: }3 Z+ f9 G5 r, m, c2 ?- l
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");. r0 Z; ?2 y+ h' g- h7 b3 U
  214.         }
      Q/ L& l. G; i5 }# T8 i& N) x
  215.     }
    ) Q6 x" i1 h5 v

  216. / B- ~7 U0 C1 I2 t: l
  217. }
复制代码

* a8 [  [8 e! D" Y9 k5 i, C' k( p% Z. K7 i/ U' h& x
- v: Z$ `" S5 Q# J* C1 K! ?
- x0 e, Z4 `3 @8 ?
. z+ `5 U# ]3 Y& B) E9 c
收藏 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 手机版