5266|4

5

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

请教AVRMega128访问DS3231SN数据不正确原因 [复制链接]

最近搞个板子,使用Mega128访问DS3231SN,可是数据读取始终为0,不知何故,请大家帮忙看一下代码,看看哪有问题,谢谢。
上拉电阻为10K。

 

 

 

#ifndef _ds3231_h
#define _ds3231_h
//====================================================================
#define RST_On CLR_BIT(PORTB,PB6)
#define RST_Off SET_BIT(PORTB,PB6)

#define GET_SDA GET_BIT(PINA,PA3)
#define SDA_High SET_BIT(PORTA,PA3)
#define SDA_Low CLR_BIT(PORTA,PA3)
#define SDA_In CLR_BIT(DDRA,PA3)
#define SDA_Out SET_BIT(DDRA,PA3)

#define SCL_High SET_BIT(PORTA,PA2)
#define SCL_Low CLR_BIT(PORTA,PA2)
#define SCL_Out SET_BIT(DDRA,PA2)
struct DS3231_DAT
{
    uchar year;
uchar month;
uchar day;
uchar hour;
uchar minute;
uchar second;
    float temperature;
}*ds3231;



void I2C_Start(void)
{
    SDA_Out;
SDA_High;
SCL_High;
delay_nus(5);
SDA_Low;
delay_nus(5);
SCL_Low;
delay_nus(5);
}

void I2C_Stop(void)
{
    SDA_Out;
SDA_Low;
SCL_High;
delay_nus(5);
SDA_High;
delay_nus(5);
}

uchar I2C_Write(uchar dat)
{   
    uchar i,ret;
SDA_Out;

for(i=0;i<8;i++)
{
    SCL_Low;
delay_nus(5);

    if(dat&0x80)
{
    SDA_High;
LED_ON();
}
else
{
    SDA_Low;
LED_OFF();
}
delay_nus(5);

SCL_High;
        delay_nus(5);

dat<<=1;
}

//read the ack bit
SDA_In;
SDA_High;
SCL_Low;
delay_nus(5);
SCL_High;
delay_nus(5);
ret=GET_SDA;
SCL_Low;
delay_nus(5);
return ret;
}

void I2C_Write_byte(uchar add,uchar data)
{
    //I2C_Start();
I2C_Write(0xd0);//Write mode
I2C_Write(add);
I2C_Write(data);
//I2C_Stop();
}

uchar I2C_Read(uchar ackBit)//ackBit: low for ACK, high for None ACK
{
    uchar i,dat=0x00;

    SDA_In;
    SCL_Low;
delay_nus(5);
for(i=0;i<8;i++)
{
    SCL_High;
        delay_nus(5);
dat|=GET_SDA;

dat<<=1;
SCL_Low;
        delay_nus(5);
}

//Send ACK
    SDA_Out;
if(ackBit==0)
{
    SDA_Low;
}
else
{
    SDA_High;
}

SCL_High;
delay_nus(5);
SCL_Low;
delay_nus(5);
SDA_In;
return dat;
}

uchar I2C_Read_byte(uchar addr,uchar ackBit)//ackBit: low for ACK, high for None ACK
{
    uchar dat;
//I2C_Start();
I2C_Write(0xd1);//read mode
I2C_Write(addr);
dat=I2C_Read(ackBit);
//I2C_Stop();
return dat;
}

void Ds3231_Set_Time(uchar year,uchar month,uchar day,uchar hour,uchar minute,uchar second)
{
    I2C_Start();
I2C_Write_byte(0x00,num2BCD(second,10));
I2C_Write_byte(0x01,num2BCD(minute,10));
I2C_Write_byte(0x02,num2BCD(hour,10));
I2C_Write_byte(0x04,num2BCD(day,10));
I2C_Write_byte(0x05,num2BCD(month,10));
    I2C_Write_byte(0x06,num2BCD(year,10));
I2C_Stop();
}

void DS3231_init(void)
{
    OE_On;
SDA_Out;
SCL_Out;
SCL_High;
SDA_High;

I2C_Start();
I2C_Write_byte(0x0e,0x00);//enable oscillator
I2C_Write_byte(0x0f,0x00);
I2C_Stop();

//2011-8-10 12:11:10
Ds3231_Set_Time(11,8,10,12,11,10);

}

void getDs3231Temp(void)
{
    uint hValue,lValue;
uchar sign;
float temp;

I2C_Start();
//check if bus is busy
while(I2C_Read_byte(0x0f,0)&0x04);
//write convert cmd
I2C_Write_byte(0x0E,0x20);
//wait until busy=0 and conv=0 
while((I2C_Read_byte(0x0f,0)&0x04)||(I2C_Read_byte(0x0E,0)&0x20));

//read high byte
hValue=I2C_Read_byte(0x11,0);
//get sign
sign=hValue&0x80;
//remove sign
hValue=hValue&0xef;

//read low byte
lValue=I2C_Read_byte(0x12,1)>>6;
//combine the temp code

I2C_Stop();
temp=hValue<<2|lValue; 
//add sign
if(sign>0)
{
    temp*=-1;
}

ds3231->temperature= 0.03125 *temp;//convert to degree
}

void getFullTimeNow(void)
{
    I2C_Start();
ds3231->year=I2C_Read_byte(0x06,0);
ds3231->month=I2C_Read_byte(0x05,0);
ds3231->day=I2C_Read_byte(0x04,0);
ds3231->hour=I2C_Read_byte(0x02,0);
ds3231->minute=I2C_Read_byte(0x01,0);
ds3231->second=I2C_Read_byte(0x00,1);
//getDs3231Temp();
I2C_Stop();
}

uchar getYear(uchar ackBit)//ackBit: low for ACK, high for None ACK)
{
    return I2C_Read_byte(0x06,ackBit);
}


uchar getMonth(uchar ackBit)
{
    return I2C_Read_byte(0x05,ackBit);
}


uchar getDay(uchar ackBit)
{
    return I2C_Read_byte(0x04,ackBit);
}


uchar getHour(uchar ackBit)
{
    return I2C_Read_byte(0x02,ackBit);;
}

uchar getMinute(uchar ackBit)
{
    return I2C_Read_byte(0x01,ackBit);
}

uchar getSecond(uchar ackBit)
{
    return I2C_Read_byte(0x00,ackBit);
}

void resetTime(void)
{
    RST_On;
delay_nms(250);
RST_Off;   
}


//====================================================================
#endif

最新回复

3口应是if(dat&0x08).  详情 回复 发表于 2015-11-26 11:53
点赞 关注
 

回复
举报

5

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

下面是主函数

 

void main(void)

{

    //init ds3231

    Ds3231_init();

   

    Ds3231_Set_Time(11,8,6,9,10,20);
    Uart0_SendStr("\nSystem time set OK.\n");

 

    while(1)

    {

         I2C_Start();
         Uart0_SendStr("\nControl Register=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x0e,0)));
         Uart0_SendStr("\nStatus Register=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x0f,0)));

         Uart0_SendStr("\nYear=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x06,0)));
         Uart0_SendStr(",Month=");
   Uart0_SendStr(num2Str2(I2C_Read_byte(0x05,0)));
         Uart0_SendStr(",day=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x04,0)));
         Uart0_SendStr(",Hour=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x02,0)));
         Uart0_SendStr(",Minute=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x01,0)));
         Uart0_SendStr(",Second=");
         Uart0_SendStr(num2Str2(I2C_Read_byte(0x00,1)));
         Uart0_Send('\n');   

         I2C_Stop();

    }

  

}

[ 本帖最后由 doleph 于 2011-8-7 11:13 编辑 ]
 
 
 

回复

785

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
不知楼主最后是怎么解决问题的呢   我现在调STM8+DS3231SN  也是读不到数据  很悲催啊,程序是从51上移植过来的,51的已经批量使用  
 
个人签名我从不担心我努力了不优秀,只担心优秀的人都比我更努力。如果你无法忍受孤独,就不要追逐梦想。每一个优秀的人,都有一段沉默的时光。在那一段时光,你付出了很多努力,忍受孤独和寂寞,不抱怨不诉苦,最后渡过了这
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

4
 
if(dat&0x80) 是不是对映SDA口线!
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

5
 
3口应是if(dat&0x08).
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
报名最后2天:ADI 最新低功耗 MCU 及其解决方案详解
直播时间:3月20日(本周四) 上午10:00
活动奖励:双肩包、充电宝、小夜灯

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 5

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表