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

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

[复制链接]
老牛洋车 发布时间:2019-9-20 21:19
    之前完成了GPIO模拟I2C驱动DS1307和AT24C32之后,便继续测试如何使用硬件I2C。在热心版主和坛友的帮助下,经过几天的反复测试,硬件I2C也基本完成,在阻塞方式下完成了对DS1307和AT24C32的操作,下图为测试过程:
& R" H6 O1 v& ]5 T I2C_Bus_Ok.jpg # w% i6 r8 L' B

6 t3 ]& O9 {+ a5 e' W7 ^' b    屏幕下部的日期和时间是从DS1307芯片读取的,利用systick的毫秒中断进行秒计时,每分钟读取一次DS1307的日期数据,并用秒、分、时数据对AT24C32进行一次先读后写的操作,读出的数据(也就是上次写入的数据)显示在倒数第三行,当前写入的数据显示在倒数第二行。对DS1307读取数据交替采用HAL_I2C_Master_Receive()和HAL_I2C_Mem_Read()函数,读写的代码如下:
) G; \; P) N! p9 V4 T1 V  G* s2 v
  1. /****************************************************************************************** . L: [4 ^8 S! w- L% B
  2. * 函数名称: DS1307_I2C_Transmit(uint8_t size): B7 B  \! T1 ^, [
  3. * 功能说明: 写数据到DS1307
    8 s. d4 S2 z; n+ l5 Y) u9 w$ y
  4. * 输    入: size 数据个数(要写入数据在全局数组DS_Buff中)( Z8 t1 ?0 n0 E/ J' |* u$ z+ O
  5. * 输    出: 0 = 成功写入  1 = 写数据过程中出现错误
    6 n/ d% Q8 x5 x5 g' y0 P
  6. ******************************************************************************************/
    * n9 t! }* f2 L6 ~2 u# f7 ~
  7. uint8_t DS1307_I2C_Transmit(uint8_t size)
    " Q+ s" A& R& h; [
  8. {
    1 T4 O$ n% j% X* `
  9.     uint8_t addr = 0;/ m* N# i* m* x) P1 t  ?& C* H* Q7 A& B
  10.         DS1307_DataToBuff();      //将时间及日期数据转换到Buff数组中6 b2 r5 c# }5 e% p$ H, ^- k9 X, ~
  11.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    ; a' {; Z5 l& \6 O
  12.        
    ! z' D2 d1 M  q" J& N0 \
  13.         if(HAL_I2C_Master_Transmit(&hi2c1,0xD0,(uint8_t*)DS_Buff ,size,10000) != HAL_OK)
    . \- o$ M$ O1 E* P5 q0 ^
  14.     {9 K) v) `9 O# h& u# B+ A4 F
  15.         return 1;
    4 y# W' [# E8 q; A9 `2 z2 W. p6 W9 s' B
  16.     }
    6 u$ M* }4 J, T0 h- P5 H
  17.         return 0;) i  H) {0 r5 I
  18. }
    : a8 b) i" J% ^9 p

  19. 0 r4 P1 ?, |0 I0 R, v7 G/ V" S1 M
  20. /****************************************************************************************** & h/ b2 J  Q7 D
  21. * 函数名称: DS1307_I2C_Receive(uint8_t size)
    2 h# ^  ]; P' D6 Y4 g
  22. * 功能说明: 从DS1307读出数据
    , m/ s4 G. R3 m# L' Y  ?
  23. * 输    入: size 数据个数(读出的数据在全局数组DS_Buff中)* |% B' u7 t! l' }3 s
  24. * 输    出: 0 = 成功读出  1 = 读数据过程中出现错误
    2 x, F& G# o2 a# ?
  25. ******************************************************************************************/
    ' L9 f: ]0 J0 b8 ~4 [  S# ^
  26. uint8_t DS1307_I2C_Receive(uint8_t size)
    * \' k5 F! w# {) D" P/ i
  27. {
    3 O8 Z2 V  e! u% W: y* r
  28.         uint8_t addr = 0;
    ' S" Z5 K; l, W: f9 F9 r
  29.         HAL_I2C_Master_Transmit(&hi2c1,0xD0,&addr,1,10000);//发送起始地址
    / Q$ f, c, G' j+ N% I
  30.        
    % M6 Q* ]; i# @2 p5 G
  31.     if(HAL_I2C_Master_Receive(&hi2c1,0xD0,DS_Buff,7,10000) != HAL_OK)
    0 d2 p+ o$ n3 [- J* B& W" ?' U
  32.     {* @. u5 l) E+ Z1 y0 ?; x: ~) M
  33.         return 1;) J, b( q8 s$ {; y( K; Q
  34.     }3 E6 i) w& ?3 y3 a  F/ W6 w
  35.     if(size == 1){               //检查DS1307是否需要初始化
    3 ]7 H9 t" ?% f
  36.                 if(DS_Buff[0]>127){
    0 {; S* P: I2 d7 o% r
  37.             year = 2019;* Y0 c" r# v! h- d' t, v
  38.                     month = 9;
    ! n1 {! x7 Z" i; v
  39.                     day = 18;) j! X1 G# m% D/ n% g3 g/ x2 @4 q# ~
  40.                     week = 3;. H7 D; _1 x* ?$ `
  41.                     hour = 9;
    3 G  r& Z# x4 S( M3 Z
  42.                     minute = 1;8 H" c5 P6 t% i
  43.                 3 \5 B' H8 l; v8 x
  44.             DS1307_DataToBuff();
    # ]( @1 a' j; s: E: o! T0 M
  45.                         DS1307_I2C_Transmit(8);# k7 C7 b% |+ I5 ^: d
  46.                 }" _- R) `/ @. N( e; e$ X, O
  47.         }
    7 C1 H) R' Y9 z/ \  q6 n
  48.         else{
    6 t2 g  g  R# R3 l
  49.             DS1307_BuffToData();* Z% f% J, ^- C2 i/ D0 q5 w
  50.     }
    ' h( {! P; L0 @# p2 r" V( |
  51.         return 0;       
    1 @$ i+ _  }& Q0 N7 J6 j
  52. }
    : W6 w: e- u" O) h# k( G6 P
  53.                  
    8 c3 U* A9 f/ W; _8 w# k
  54. /****************************************************************************************** ; m5 q: Y  d7 n. ]( ?$ r$ n& d  ?
  55. * 函数名称: DS1307_I2C_Read()! g2 I7 V: e4 F  ^& F' m/ z% ?
  56. * 功能说明: 读DS1307的日历数据,并转换为各自的变量值  ]3 f2 M7 ], E8 b2 H& M
  57. * 输    入: 无
    2 y, y3 P) n5 ]" C2 R5 K, @
  58. * 输    出: 0 = 成功从DS1307获取数据  >0 = 从DS1307获取数据过程中出现错误
    ( ?$ i! ?% j! C1 ?  z6 Y  K
  59. ******************************************************************************************/0 T& |7 h4 D0 x1 G* M1 J6 k
  60. void DS1307_I2C_Read(void)$ w; s% b- I7 C) }: _
  61. {9 k, d" q6 G/ T* R

  62. % f2 O- j7 \* I! M0 p
  63.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)
    + s" I" {  }/ J, k
  64. //        while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)3 d' J% n$ Z7 E; \, `$ n
  65.     {
    0 z( _" F( X# f" G5 \& @* |/ D; `. |
  66.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    ( n+ P5 u% F4 S* ?5 m; p
  67.         {
    ( y# c9 w4 L, b' M. y
  68.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Read_Error!");: K( C% Z, k5 N' I9 T5 H$ Z
  69.         }3 a. g! d: s& x- h* b
  70.     }
    . \  K2 M; R6 X
  71. $ Z9 t9 s& x' t  O+ [4 I- g8 f
  72.         DS1307_BuffToData();: r& r. Y8 j: t
  73.        
    5 O: J+ u* w9 C/ r
  74. }
    ; D0 Q, X' \7 D8 u4 b  _0 v

  75. 5 J' |& y0 [- C# S& K( c0 K5 H
  76. /******************************************************************************************
    ! T" P7 K; e# n
  77. * 函数名称: DS1307_I2C_Write()- |" f8 ]! v( @1 h
  78. * 功能说明: 将当前的日历数据写入DS1307/ t4 j) |3 X. w+ f
  79. * 输    入: 无8 F/ _3 B- u( J, H' a- e
  80. * 输    出: 0 = 成功写入数据  >0 = DS1307写入数据过程中出现错误- b9 e7 |$ c: |% z) s0 C* ]* u
  81. ******************************************************************************************/$ O, h% [0 A- w7 f0 f
  82. void DS1307_I2C_Write(void), _7 @8 N( s0 }" p( i. c. O$ O9 c
  83. {4 C7 K. `0 J: |7 ?: A
  84.     DS1307_DataToBuff();           //时间日期数据转换存入Buff数组中
    / H, N  h6 B# }; v9 Y
  85.        
    & ^# e( ^- ~( f7 V
  86.     while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,7,10000) != HAL_OK)# y+ @- N9 {/ i) X: b- W/ ^
  87. //    while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 7, 10000) != HAL_OK)' T4 [2 p& d; X" j; |! ^
  88.     {! t8 L% c: Z3 g% T
  89.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    7 K8 i. ~6 p+ q. l. Z4 _
  90.         {
    4 a& j) w6 ?+ [$ Z0 [4 i( h9 ~
  91.             LCD_write_ASCII(0,3,1,(uint8_t *)"DS_Write_Erro!");
    9 t. p9 P* w+ d" w
  92. //                        return 2;
    - X0 P# K: X6 k
  93.         }/ G1 T3 K  M1 S+ I6 b1 Q
  94.     }0 ]' D6 _1 n7 o! |& l8 \
  95. //        return 0;
    9 ^/ S; Z0 e* p: S' |
  96. }4 D- H  t6 D. B1 ]/ l6 n* U

  97. # ?3 F% v! V) P- d1 f' y
  98. /****************************************************************************************** / I1 V1 E5 ~; U. c$ i" U* }; `
  99. * 函数名称: DS1307_Chick()% {4 I% d: U% u" `7 ?& D+ C
  100. * 功能说明: 检查DS1307是否已经初始化,若未初始化则用特写日期进行初始化
    5 K, F1 J$ q  }( U3 v+ ^. ?
  101. * 输    入: 无# q  Q( O4 [; \. q4 @
  102. * 输    出: 无
    7 k1 J! d. Z0 `! e
  103. ******************************************************************************************/8 G1 u6 {  h* a  [; n3 j
  104. void DS1307_Check(void)! z. T# k/ z. i
  105. {
    & y* e) y7 u6 u- d0 v

  106. & u; y; I4 b+ J+ i5 z; c1 V; Q
  107. //        LCD_write_ASCII(0,3,1,(uint8_t *)"Check_Begin...");
    ) v, ^4 @  S, |3 Z# ?( v
  108.     while (HAL_I2C_Mem_Read(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)
    6 O# j0 T% p/ Q7 @$ v1 h- j
  109.     while (HAL_I2C_Master_Receive(&hi2c1, 0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)
    6 u" D/ k! G, n: ~
  110.     {# ^- P/ e" w! W
  111.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    1 L; I: n4 R( Z1 V' E  e* _1 A
  112.                 {
    ! z* _( W& D* x& j
  113.                     LCD_write_ASCII(0,3,1,(uint8_t *)"CheckReadErro!");
    $ i( K; @! f1 {2 V: P0 T& u4 H
  114.                 }) ~( M6 b7 p# p! \( N# e
  115.         }
    + m# C, E, ?' o: [
  116.         LCD_write_value(0,4,3,0,1,DS_Buff[0]);# R& O8 _  {% r) S
  117.         if(DS_Buff[0]> 127){7 I, S# n: M' i" x# Y. C4 o
  118.         year = 2019;: u  Y0 ?: e7 R
  119.                 month = 9;& M+ e1 k1 _$ C3 ~- y1 p* }
  120.                 day = 18;9 A4 w  |! E$ j. o, Z
  121.                 week = 3;9 \; u9 o0 d  k9 L7 H- U0 v8 K
  122.                 hour = 9;
    ) J* ^& o( _9 M* [0 I; i' I
  123.                 minute = 1;& o1 Z& Y2 a9 ^8 H- X9 B
  124.                
    . |- o/ [+ N/ N# a# e
  125.         DS1307_DataToBuff();
    : z: L' r0 G) V$ D) [

  126. & j2 \3 _/ C2 {# W0 y8 c8 a8 v7 G
  127.         while (HAL_I2C_Mem_Write(&hi2c1,0x00D0,0,I2C_MEMADD_SIZE_8BIT,(uint8_t*)DS_Buff,1,10000) != HAL_OK)6 X. S) j+ {/ J- Y7 l0 _
  128. //        while (HAL_I2C_Master_Transmit(&hi2c1, 0, (uint8_t *)DS_Buff, 8, 10000) != HAL_OK)
    : W0 H1 O0 f. u8 r
  129.         {
    6 ?$ t: W9 y+ x5 ~. K' c
  130.             if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)2 {% r; }% B$ ~, C: u
  131.             {
    2 }0 Z8 d* o* m3 \/ ~! Q
  132.                 LCD_write_ASCII(0,3,1,(uint8_t *)"CheckWriteErr!");2 ]! r5 P/ q6 T3 Y8 T* a
  133.             }% Q3 i6 M1 t4 N$ [, P! M
  134.         }- Q. D- P, U' d8 c) d' J
  135.         }
    5 w- w7 Y3 v4 A
  136. }
    ; I' \8 ^1 l6 {
  137. 7 p  b" ~( t; H" i7 `
  138. /******************************************************************************************
    . G: d3 x& R% ]
  139. * 函数名称: DS1307_DataToBuff()
    $ P0 v5 C0 ?, O% L4 l9 x
  140. * 功能说明: 将时间日期变量数据转换到数组Buff中' p3 f4 f- ^2 P) P( m7 E
  141. * 输    入: 无
    8 x; H- `% i# ?* V9 c% D
  142. * 输    出: 无
    6 A% B- s% k1 U/ b6 P! r
  143. ******************************************************************************************/
    1 N, m" D* O/ N% w8 f% C
  144. void DS1307_DataToBuff(void)4 L; h' J9 ]) E" Z* r. F* h5 U
  145. {9 q& N4 V+ f1 V& e& T
  146.     uint8_t temp;
    : w, o6 i+ m6 w, R  k: [! ~8 u
  147.         DS_Buff[0] = 0;                  //秒1 k+ |; c* s6 M/ I8 {
  148.     temp = ((minute/10)<<4|(minute%10));
    ! f1 R6 z6 H2 {" C$ ^  a
  149.     DS_Buff[1] = temp;               //分
    / f- N5 Z& a" J7 y7 D  x
  150.     temp = ((hour/10)<<4|(hour%10));  m9 M* c4 j1 n
  151.     DS_Buff[2] = temp;               //时
    ' N% U7 Y& U6 c8 A) S

  152. 9 `4 V4 w1 a( c
  153.     DS_Buff[3] = week;               //星期
      }7 t4 L) a0 ^. ^" A

  154. 5 f5 C2 z/ e/ S, w" _/ w
  155.     temp = ((day/10)<<4|(day%10));
    * N0 R8 h- O, `: J1 t$ z# m/ f6 ]
  156.     DS_Buff[4] = temp;               //日
    4 k+ V! z/ N# o3 e$ d
  157.     temp = ((month/10)<<4|(month%10));
    1 G' ]- b% ~( I. F$ s3 R! W
  158.     DS_Buff[5] = temp;               //月$ U1 B1 j; y, e6 Y' L  o6 ]$ L
  159.     temp = ((year%100)/10<<4|(year%10));. L* N" S% P9 K, E- C8 t/ k4 ~
  160.     DS_Buff[6] = temp;               //年# a2 b7 x; J1 S5 R
  161.     DS_Buff[7] = 32;                 //0010 0000 = 允许按1Hz输出方波
    ! g/ N( H+ p  N+ s
  162. }
    2 p5 ~  Q: B8 W

  163. . ^5 V, b1 M: w: {

  164. $ o, u/ e" J# B6 F: b* D1 \) ~: L
  165. /****************************************************************************************** + S. x* p5 V% o# g+ Y; F
  166. * 函数名称: DS1307_BuffToData()
    & r+ G/ O, x9 n8 J4 D" P, }" x
  167. * 功能说明: 将数组Buff数据转换到时间日期变量中
    " _6 v: d' W3 W6 V: H- s
  168. * 输    入: 无' K! J. i1 e' t# e& j; a/ k3 J3 D7 Z
  169. * 输    出: 无1 j$ @  u5 k1 ~6 x
  170. ******************************************************************************************/1 m! [3 i* x0 t! h6 p; F3 l. J* A' c9 O* m
  171. void DS1307_BuffToData(void)
    6 e% o; R1 E8 z$ d" \
  172. {: W! {0 {# q% C5 O' m
  173.     second = ((DS_Buff[0]&0x70)>>4)*10 + (DS_Buff[0]&0x0F);//秒,屏蔽秒的第7位的标志* ~3 c0 q4 z  O* i, i
  174.     minute = ((DS_Buff[1]&0x70)>>4)*10 + (DS_Buff[1]&0x0F);//分(取低7位)
    8 k7 }% o' x  `) ]' w8 Q
  175.            hour = ((DS_Buff[2]&0x30)>>4)*10 + (DS_Buff[2]&0x0F);  //时(取低5位)
    6 X. f: X" m/ D' _, G
  176.            week = (DS_Buff[3]&0x07);                              //周(取低3位)
    + z6 m& ?4 y: P% w, z
  177.     day = ((DS_Buff[4]&0x30)>>4)*10 + (DS_Buff[4]&0x0F);   //日(取低6位)! {: B3 j' r$ o. R- J
  178.     month = ((DS_Buff[5]&0x10)>>4)*10 + (DS_Buff[5]&0x0F); //月(取低5位)- B; a: ]- ~* ]; S- o
  179.     year = 2000 + (DS_Buff[6]>>4)*10 + (DS_Buff[6]&0x0F);  //年
    # B, L' p' r" m/ g+ T+ a
  180. }
    + r, S, B) r8 X8 o. p' O+ b
  181. ; ~/ j# I5 i9 ~# S: F! U/ a# w
  182. /******************************************************************************************
    # f" Z8 B. h* Z, g  V6 `
  183. * 函数名称: AT24C32_I2C_Read()
    ' I, I  ~6 S! B/ [
  184. * 功能说明: 读取AT24C32的数据(存放在DS_Buff数组中)
    9 H* g! q6 i2 n- n/ ?
  185. * 输    入: adrr(起始地址),size(读取的字节长度)
    0 ?% j2 {. U+ l$ v& I
  186. * 输    出: 无# A  W  J! o2 a, W, F9 D
  187. ******************************************************************************************/
    + u" w) i. V! T$ j4 ?7 ]9 H
  188. void AT24C32_I2C_Read(uint16_t addr,uint8_t size)0 E$ ^9 R) |5 }4 K0 k" Z2 |% A* r! x% g
  189. {
    , p; d% D$ W  r: P+ N

  190. % K* x5 f1 Y4 a: i/ l" r2 q/ V$ r1 u
  191.     while (HAL_I2C_Mem_Read(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK)
    3 k' N, o8 t- |; h
  192.     {
    ) Y; ~$ p% N  y0 F0 D
  193.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)' @7 f: r1 M# p  C$ d
  194.         {! g( ?, Y, v3 ?0 h: w3 P+ X5 @; _
  195.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Read_Error!");- k$ B. L' O% J- Y+ j* Z
  196.         }# `8 T6 e* B/ c8 B1 A8 @; ?+ l
  197.     }
    ! W- v- K2 @+ K# d, {

  198. 1 O! L7 m4 H' D& V9 ?# _" V! S
  199. }+ r% Y  h( H' M% }, g* l
  200. ; E) l6 v$ I- ^6 M; A! H
  201. /****************************************************************************************** ( K) w1 H+ ^7 p) J& v) y) @
  202. * 函数名称: AT24C32_I2C_Write(uint16_t addr,uint8_t size)" W4 P9 z5 Z3 O. V
  203. * 功能说明: 写入数据到AT24C32(要写入的数据存放在DS_Buff数组中)" Q( ^! Q3 b) s3 G& D+ I0 V
  204. * 输    入: adrr(起始地址),size(写入的字节长度)
    2 R7 j# V! ^" h6 ~% `& T
  205. * 输    出: 无; x$ V- m% M6 T& J0 M2 d
  206. ******************************************************************************************/
    ! D, I) Z! c3 ^4 F& o# }$ H2 h$ s
  207. void AT24C32_I2C_Write(uint16_t addr,uint8_t size)
    5 _. j0 B) O. j# w! j
  208. {
      i% i" C4 I6 T* N5 d6 Y
  209.     while (HAL_I2C_Mem_Write(&hi2c1,0x00A0,addr,I2C_MEMADD_SIZE_16BIT,(uint8_t*)DS_Buff,size,10000) != HAL_OK), O$ n" K4 t9 ?; e$ b2 O/ P' F
  210.     {- s  L) Y9 \' W% {+ a) `+ ]
  211.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    % U7 K! G; v% W  F/ k
  212.         {
    * ~! w* J& d+ b3 P
  213.             LCD_write_ASCII(0,3,1,(uint8_t *)"AT_Write_Erro!");
    5 e: z; x. z8 }4 G' A  r
  214.         }& J( w2 q$ N% @' @: e8 X$ ?6 ^3 ?
  215.     }
    " I) u/ y+ n; O& J6 ^$ g8 H

  216. 4 Q& P, s4 e* Y  Q+ \8 Y# R
  217. }
复制代码

% n* E7 C6 w0 U5 d$ @" v+ ^3 c/ y  M* l* t* q6 i2 f
$ V" D5 F5 w# `9 D4 G2 y

) q9 K- a9 l( O# x9 E' w4 W
: u* ]" D& V% W" }* _( m7 M% D
收藏 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 手机版