OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 24819|回复: 14

STM32 IO口模拟I2C控制DS3231 一直调不通

[复制链接]

4

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-7-7
在线时间
0 小时
发表于 2013-8-9 11:05:27 | 显示全部楼层 |阅读模式

 一直 无法接收到ACK信号  从设备一直无反应  我单独给SDA拉高 置低 IDR是有反应的  我买了5个DS3231的时钟模块 那个模块式5V供电 经过一个稳压二极管 变成3.3v给芯片供电的  SDA SCL 上拉电阻都是10K 附件里有 DS3231的驱动程序 和 模块的原理图 从昨天到今天 在网上下了3个修改后都不行 昨天晚上 自己又重写了一个 从设备的ACK 信号一直没有响应  所以对时钟模块的读写操作 都是无效的 后来感觉是时钟芯片拽不动STM32的IO口 所以 就换了下上拉电阻  1K 4.7K 10K都换过 还是不好使 群里有朋友说 实在不行 就换成STM32的外设I2C   小弟实在是晕菜了 之前搞24c系列的模拟I2C也没这么困难过  求大家 给小弟支支招 
附件里 有 程序和模块原理图
我主程序里是这样写的
 GPIOA->CRL&=0x00ffffff;
 GPIOA->CRL|=0x22000000;//0x22000000; //SCK SDA
 delay_ms(100);
   I2cByteWrite(0xD0,0x0e,0); 
   I2cByteWrite(0xD0,0x0f,0);
后面就是读 时分秒


//////////////驱动程序
#include <stm32f10x_lib.h>
#include "delay.h"
#include "DS3231new.h" 

#define SCL_H  GPIOA->ODR|=1<<7
#define SCL_L  GPIOA->ODR&=~(1<<7)

#define SDA_H  GPIOA->ODR|=(1<<6)
#define SDA_L  GPIOA->ODR&=~(1<<6)

#define SDA   (GPIOA->IDR & 1<<6)

extern u8 year,month,date,hour,minute,second;

 

u8 BCD2HEX(u8 val)   //BCD转换为Byte
{
    u8 i;
    i= val&0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;
   
    return i;
}

u8 B_BCD(u8 val)//B码转换为BCD码
{
  u8 i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}

void delay(u16 us)
{
   delay_us(us*7);
}
/************************START***************************/
void Start(void)
{
  SDA_H;
  delay(5);
  SCL_H;
  delay(5);
  SDA_L;
  delay(5);
}
/********************************************************/
/************************STOP****************************/
void Stop(void)
{
  SDA_L;
  delay(5);
  SCL_H;
  delay(5);
  SDA_H;
  delay(5);
}
/********************************************************/
/***********向I2C总线发送一个字节+接收一个ACK************/
void SendByte(u8 Dat)
{
  u8 i=0;
  u8 T_Data=0;
 
  setsda();//DDRD|=(1<<1);//输出
  SCL_L;
  delay(10);
  T_Data=Dat;
  for(i=0;i<8;i++)
    {          
 
          if(T_Data&0x80)
            SDA_H;
          else
            SDA_L;
          delay(5);
         SCL_L;
          delay(5);
          SCL_H;
          delay(5);
          T_Data=T_Data<<1;
          SCL_L;
          delay(5);
   }
  SDA_H;//释放总线
  delay(5);
  SCL_L;     /*********************/
  delay(5);//接收一个ACK,不做处理
  SCL_H;     /*********************/
  delay(5);

  SCL_L;
}
/********************************************************/
/**********从I2C总线上读取一个字节+发送一个ACK***********/
u8 ReceiveByte(u8 b)
{
  u8 i;
  u8 temp;
  u8 Dat=0;
/*
  SDA_H;
  delay(5);
  SCL_L;
  delay(5);
*/
  clrsda();//DDRD&=~(1<<1);//输入
  for(i=0;i<8;i++)
    {
          SCL_H;
      delay(5);

          Dat=Dat<<1;
          delay(5);
    if(SDA){temp=1;}
    else{temp=0;}
          if(temp)
            Dat|=0x01;
          else
            Dat|=0x00;
         delay(5);
         SCL_L;
          delay(5);
    }
  setsda();//DDRD|=(1<<1);//输出
 
  if(b)//每收一个数后发送ACK或nACK
    SDA_H;
  else
    SDA_L;
       
  delay(5);
  SCL_H;
  delay(5);
  SCL_L;
  delay(5);
  SDA_H;        //释放总线
  delay(100);
  return Dat;
}
/****************************************************/
/***********将一个字节写入DS3231指定的地址***********/
void I2cByteWrite(u8 device,u8 addr,u8 bytedata)
{
  Start();
  delay(5);
  SendByte(device);
  delay(5);
  SendByte(addr);
  delay(5);
  SendByte(bytedata);
  delay(5);
  Stop();
}
/****************************************************/
/************从DS3231指定的地址读一个字节************/
u8 I2cByteRead(u8 device,u8 addr)
{
  u8 Dat=0;
 
  Start();
  SendByte(device);
  delay(5);
  SendByte(addr);
  delay(5);
  Start();//Restart
  SendByte(0xd1);//读数
  delay(5);
  Dat=ReceiveByte(1);//只接收一个字节,所以发nACK
  Stop();
  return Dat;
}
/***************************************************/
/*********************读取时间**********************/
void Readtime(void)
{
  year=I2cByteRead(0xd0,0x06);  //年
  month=I2cByteRead(0xd0,0x05); //月
  date=I2cByteRead(0xd0,0x04);  //日
  hour=I2cByteRead(0xd0,0x02);  //时
  minute=I2cByteRead(0xd0,0x01);//分
  second=I2cByteRead(0xd0,0x00);//秒
}
/***************************************************/
/****************修改时间,BCD码输入*****************/
void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
{
  u8 temp=0;
 
  temp=B_BCD(yea);
  I2cByteWrite(0xD0,0x06,temp);//修改年
 
  temp=B_BCD(mon);
  I2cByteWrite(0xD0,0x05,temp);//修改月
  
  temp=B_BCD(da);
  I2cByteWrite(0xD0,0x04,temp);//修改日
 
  temp=B_BCD(hou);
  I2cByteWrite(0xD0,0x02,temp);//修改时
 
  temp=B_BCD(min);
  I2cByteWrite(0xD0,0x01,temp);//修改分
 
  temp=B_BCD(sec);
  I2cByteWrite(0xD0,0x00,temp);//修改秒
}

/****************************************************/
/****************读取时间 计算 并显示****************/
void get_show_time(void)
{
//year,month,date,hour,minute,second;

year=I2cByteRead(0xd0,0x06);  //年
year=BCD2HEX(year);


month=I2cByteRead(0xd0,0x05);  //月
month=BCD2HEX(month);


date=I2cByteRead(0xd0,0x04);  //日
date=BCD2HEX(date);
 

hour=I2cByteRead(0xd0,0x02);  //时 24小时制
hour&=0x3f;                  
hour=BCD2HEX(hour);


minute=I2cByteRead(0xd0,0x01);  //分
minute=BCD2HEX(minute);
 
 
second=I2cByteRead(0xd0,0x00);  //秒
second=BCD2HEX(second);
}

void setsda(void)
{
GPIOA->CRL&=0xf0ffffff;
GPIOA->CRL|=0x02000000;
}


void clrsda(void)
{
GPIOA->CRL&=0xf0ffffff;
GPIOA->CRL|=0x04000000 ;

}

DS3231模块电路图.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

22

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
295
金钱
295
注册时间
2012-11-11
在线时间
24 小时
发表于 2013-8-9 13:49:34 | 显示全部楼层
一般是模拟I2C的时序不符合要求,用示波器钳一下看看波形。前段时间在自己的板子上调试24C04,程序用的是原子的代码 ,调了好几天调不出来,能读但不能写。后来在原程序上的某些延时点调整了一下,就正常了。
回复 支持 反对

使用道具 举报

22

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
295
金钱
295
注册时间
2012-11-11
在线时间
24 小时
发表于 2013-8-9 13:57:18 | 显示全部楼层
我的板子上24C04与DS3231是同挂在一条I2C模拟总线上,24C04程序改好了,DS3231没有调。现在主要是在做界面,7吋800X480,等界面做得差不多了,再来搞实时时钟。STM32支持的RAM太小了,大屏无法实现流畅的滑屏特效。
回复 支持 反对

使用道具 举报

4

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-7-7
在线时间
0 小时
 楼主| 发表于 2013-8-9 15:34:59 | 显示全部楼层
回复【3楼】狼烟四起:
---------------------------------
恩恩  根据 原子哥 IIC协议 修改了下 现在已经正常了
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2014-1-5
在线时间
7 小时
发表于 2014-1-27 22:55:39 | 显示全部楼层
楼主你好,小弟刚好要用STM32 驱动DS3231,把你的代码移植过来,怎么弄都读不到数据,只读秒,全部是高电平,完全无数据,看波形也是一样,请问楼主你公布的代码是调试成功了的代码吗?
回复 支持 反对

使用道具 举报

1

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2012-9-3
在线时间
8 小时
发表于 2014-8-29 23:44:41 | 显示全部楼层
楼主的问题解决了吗?我用STM32F103模拟IIC操作DS3231成功了,采用秒中断方式,需要的话我就把程序传上来。
回复 支持 反对

使用道具 举报

39

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
399
金钱
399
注册时间
2014-11-7
在线时间
44 小时
发表于 2014-11-7 11:33:42 | 显示全部楼层
回复【6楼】jinfahua:
---------------------------------
5楼您哈,用硬件很难么?
再牛逼的梦想都禁不住傻逼的坚持!
回复 支持 反对

使用道具 举报

13

主题

276

帖子

0

精华

高级会员

Rank: 4

积分
697
金钱
697
注册时间
2014-6-20
在线时间
146 小时
发表于 2014-12-23 21:14:25 | 显示全部楼层
回复【4楼】qingtian305:
---------------------------------
楼主,您的代码是调试完成后的吗?我前一段也是用3231,调了好久也没搞定,51上运行好好的,一到ARM上就没反应了
回复 支持 反对

使用道具 举报

4

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-7-7
在线时间
0 小时
 楼主| 发表于 2015-1-12 09:17:56 | 显示全部楼层
回复【8楼】313668972:
---------------------------------
上面的代码是调试通的  可以用
回复 支持 反对

使用道具 举报

4

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-7-7
在线时间
0 小时
 楼主| 发表于 2015-1-12 09:18:41 | 显示全部楼层
回复【6楼】jinfahua:
---------------------------------
好哇 好哇
回复 支持 反对

使用道具 举报

3

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
87
金钱
87
注册时间
2015-6-10
在线时间
16 小时
发表于 2015-7-12 10:34:40 | 显示全部楼层
回复【2楼】狼烟四起:
---------------------------------
我现在遇见和你一样的问题,也是只能读不能写,请问你是调了那里的延时?调大还是调小?谢谢
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-8-19
在线时间
1 小时
发表于 2016-8-19 09:44:21 | 显示全部楼层
能给个程序的例子吗?
回复 支持 反对

使用道具 举报

8

主题

145

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2016-12-14
在线时间
75 小时
发表于 2017-1-5 17:25:39 | 显示全部楼层
同在调试DS32321
书山有路勤为径,学海无涯苦作舟!
回复 支持 反对

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11536
金钱
11536
注册时间
2014-4-1
在线时间
1313 小时
发表于 2017-1-5 22:45:55 | 显示全部楼层

这个芯片很好用,
不用加晶体,价格也便宜。



回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2021-2-18
在线时间
1 小时
发表于 2021-6-11 16:57:29 | 显示全部楼层
我用STM32F407的硬件可以读写,用模拟IIC协议调不通(24C 64又没有问题)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-22 16:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表