一直 无法接收到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 ;
}
一周热门 更多>