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

【STM32G4 NUCLEO G431RB】+ 尝试硬件I2C驱动DS1307

[复制链接]
老牛洋车 发布时间:2019-9-15 22:26
    一周来都在尝试驱动DS1307,在用GPIO模拟I2C驱动不成功之后,尝试用硬件I2C来驱动,将I2C相关的代码复制到项目中,编译通过后但仍没有成功驱动DS1307,用逻辑分析仪抓取时序,发现单片机发出了地址信号,但没有应答信号,为了排除DS1307模块的问题,我将备用模块焊好排针测试,第一次似乎通过了I2C读写,但返回的数据全是零,复位再测试又不行了。9 q7 Z5 K! e5 s% o8 j; w
I2CWriteAddrss_3.jpg
- O' ^4 o) a0 K( M; q- ?6 W* ^  A- a/ |! x/ J  p" B

7 e4 G* M1 f- Y$ B' v$ Z% Y    通过分析时序图,发现单片机在发出地址之前还发出了11110000数据,不清楚这个字节的含义。进一步分析发现I2C通讯时高位在前、低位在后,而我从网上搜索到的DS1307驱动代码的模拟I2C通讯却是低位在前、高位在后,明显不符合通讯协议。下面是时序图:
. _* j! Z1 g5 r4 ` I2CWriteAddrss_0.jpg 1 I. D0 Q( p# X- Z
7 \# i; ^# e2 m1 w( [
+ O4 g* _. }* @0 T. X
    测试时单片机在不断地循环发出地址数据:
' P1 _# p* j( X. f( { I2CWriteAddrss_1.jpg
6 u' J6 s- a1 ?# ?! n) S: e- e# f7 Q# J- a. p8 \8 t

/ q- [3 |. f0 F' j: Z I2CWriteAddrss_2.jpg
7 s" G) n2 d; G% p- }6 ]$ F7 p, {7 Q
' ~( E2 l! X" n, Z8 O, G
    硬件I2C对DS1307进行读写操作的代码如下,这个代码是参照范例写的,也不清楚是否会是代码有问题:, P0 k( O- A$ `
  1. /****************************************************************************************** ! S: C$ p% |2 y
  2. * 函数名称: DS1307_I2C_Read(). |( A; g: p% F
  3. * 功能说明: 从DS1307地址addr开始获取size个字节的数据,获取的数据存储在全局变量DS_Buff中1 i  l: T0 Q% [+ F
  4. * 输    入: uint8_t addr        获取数据的开始地址
    9 s* f2 Q6 H* }6 B
  5. *                        uint8_t size        要获取的数据个数(1~8)
    8 A1 w- J6 V; k" o. u$ k
  6. * 输    出: ui08    0=RET_OK 成功从DS1307获取数据  >0=从DS1307获取数据过程中出现错误/ A, C. j" l- A) J" K" \. d) {
  7. ******************************************************************************************/
    / P& r6 ~. l$ n1 v
  8. uint8_t DS1307_I2C_Read(uint8_t addr,uint8_t size)
    1 H6 Y1 S' Z! f2 [3 x- a, ^8 X, Z
  9. {7 d1 T- b) z7 |
  10.     DS_Buff[0] = addr;    //将要读取的起始地址发送给DS1307
    9 I) n: `6 f; \7 f5 z2 d
  11.     while (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS|0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)
    " P/ x4 ?7 ~' W# T
  12.     {7 n& B7 W7 J5 h
  13.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    ; D4 p+ O+ q* B+ L, k: L- q
  14.         {$ r0 b( s# z& C- o. c; E9 o
  15.             LCD_write_ASCII(0,3,1,(uint8_t *)"Read-Tr-ErrorA");
    " ?2 u" O1 m  Z. h
  16.                         return 1;
    8 k- I# q4 E' m, ^8 k; l
  17.         }4 J! W* ]# V0 u: h
  18.                 LCD_write_ASCII(0,4,1,(uint8_t *)"WriteAddr-ACK!");
    2 n# R! h8 |' N$ _9 [# Y# |
  19.     }6 _0 Y; f' M; X- B7 g3 |6 n
  20.     while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)I2C_ADDRESS|1, (uint8_t *)DS_Buff, size, 10000) != HAL_OK)
    4 B! g0 Y1 R! e, h& L* q+ H
  21.     {
    , ^" V( j0 Q. O3 ^
  22.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF), X* a7 y* P, `5 w
  23.         {
    ; k/ n2 O' A/ X* U
  24.             LCD_write_ASCII(0,3,1,(uint8_t *)"Read_Tr_ErrorB");
    0 [, M' H8 j* H+ R8 z# w
  25.                         return 2;
    4 t; E3 t" ?7 s1 d3 ]7 Q
  26.         }
    / ^" P* J3 Y9 |5 S
  27.     }
    ' k" o" A" }: @; f" T% n8 x0 Q  V
  28.         return 0;: Q6 p# ^  G# w! z& B' T
  29. }
    9 o2 T8 s4 z3 E: t0 N- M1 M
  30. " Q" ?  s' a) `( K8 B
  31. /******************************************************************************************
    2 w. O" U9 w) [. [
  32. * 函数名称: DS1307_I2C_Write()
    3 }4 _: X" Z2 r: d4 q5 G$ H2 d
  33. * 功能说明: 从DS1307地址addr开始写入size个字节的数据,数据存储在全局变量DS_Buff中
    ) n# g, E# r4 M- c3 ~: ]/ Q
  34. * 输    入: uint8_t addr        写入数据的开始地址% C/ ?0 ^$ d6 V1 K& Q$ R8 D
  35. *                        uint8_t size        要写入的数据个数(1~8)
    * M! c/ z; y3 u) u0 l! m
  36. * 输    出: ui08    0=RET_OK 成功写入数据  >0=从DS1307写入数据过程中出现错误) k* F( D' c% H  g
  37. ******************************************************************************************/5 D5 @% a- L2 M0 F. c: F3 M" R
  38. uint8_t DS1307_I2C_Write(uint8_t addr,uint8_t size)* O9 L5 }2 f" l& G& B
  39. {
    0 a9 S1 R- X% b% O, s4 v4 W
  40.     uint8_t i;4 h" h3 [3 g' A( L9 l+ Q
  41.         i = DS_Buff[0];# h* f5 q2 a- M5 R/ y2 d5 |
  42.     DS_Buff[0] = addr;    //将要写入的起始地址发送给DS1307
    9 L& U/ V. X7 A/ G
  43.     while (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS|0, (uint8_t *)DS_Buff, 1, 10000) != HAL_OK)
    3 H/ V; g; }  X1 c9 v. R. M2 }
  44.     {
    5 i- Z# {& {" y6 |: V# H
  45.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    5 p2 O% \' t) \# \) k  I$ O) P9 F5 c
  46.         {% m) `3 x# Y1 Z4 F1 c4 K
  47.             LCD_write_ASCII(0,3,1,(uint8_t *)"Write_Tr_ErroA");
    ' d3 o* C& ^7 l9 W; c6 C
  48.                         return 11;4 i7 H& |. U0 A% p( |) q
  49.         }
    + ]; V- c* w; Z5 L
  50.     }
    ; @$ U  f, ]8 C  |* p1 j* [. }, z
  51.         DS_Buff[0] = i;
    0 b/ K& f, x$ _
  52.     while (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS|0, (uint8_t *)DS_Buff, size, 10000) != HAL_OK)
    1 X: x) b, I) p5 ?' S  B3 w" i! d
  53.     {
      K3 B$ N; i3 P9 ?, l
  54.         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
    8 j5 Z, c; r# d" t0 U! u/ l7 i
  55.         {
    6 T& ?3 g$ D- u  W3 u0 z
  56.             LCD_write_ASCII(0,3,1,(uint8_t *)"Write_Tr_ErroB");
    " a6 y' R! R. l% \# F: x
  57.                         return 12;$ Q4 _& I5 N/ s. O; }
  58.         }
    : B  U+ U) J1 Q4 k+ n: ]* ^* J) ~" s
  59.     }
    ' Z( c# k( M9 C5 n( W; Q! ^! h
  60.         return 0;
    3 T4 v( _: k4 R
  61. }
    " C, s, n* h% _- Y2 X
复制代码
- M$ U% T& T6 I5 S
* i' |, g4 r( v; y; u
/ |( x* G, d0 h+ d
    不过我核对了DS1302的驱动程序,也是低位在前、高位在后通讯的,能够正常地读写,换句话说也许DS1302并不是标准的I2C。DS1307的I2C通讯时序尚未找到,但我这个模块是I2C总线除了DS1307外,还有一块AT24C32,而AT24C32是符合I2C通讯标准的,按理DS1307也应该同样符合。8 `4 U" b4 Z" A
    下一步准备继续测试GPIO模拟I2C,一定要设法成功驱动这块DS1307。
9 H' ]  D) H! M
; {. _0 ?/ f3 T' Z3 n) v; Y! w    为了驱动DS1307模块已经花费了一周多的时间,原来还准备测试驱动智能小车的都没来得及,轮子及电机已经买好了,但电机驱动板尚未配齐,只有等以后再测试了:
# \( C* A1 P, u2 l. V/ \8 X0 A SmartCar_0.jpg
4 b2 {- M$ D" j; `! {/ d3 r. Q  Y2 d- d
4 l. C- y3 Y3 y: E/ ^
赞 收藏 评论2 发布时间:2019-9-15 22:26

举报

2个回答
老牛洋车 回答时间:2019-9-16 09:18:29
    在分析了范例中I2C的时序图之后,尝试修改了原来下载的软件I2C的代码(如下图}。0 m( H/ n% K; @4 L, l6 i' k
& b( ~, }, ^. N3 m
I2CWriteAddrss_4.jpg ' U/ C- x$ A* j+ f
    现在正继续调试软件I2C,然后参照DS1307的数据手册来修改对DS1307的驱动。! g8 P) I7 v: I) q4 z
4 `- }! U; y/ W, S
老牛洋车 回答时间:2019-9-16 11:19:03
通过仔细查看数据手册,DS1307是按照I2C的通讯标准,但其速度不快,我用硬件I2C设置的是400K速率,太快了,DS1307跟不上。另外还发现了一个重要因素,DS1307的供电电压范围是4.5~5.5V,而我想当然地用了3.3V,难怪不能正常工作了。

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版