最近搞个板子,使用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
此帖出自
小平头技术问答
下面是主函数
void main(void)
{
//init ds3231
Ds3231_init();
Ds3231_Set_Time(11,8,6,9,10,20);
Uart0_SendStr(" System time set OK. ");
while(1)
{
I2C_Start();
Uart0_SendStr(" Control Register=");
Uart0_SendStr(num2Str2(I2C_Read_byte(0x0e,0)));
Uart0_SendStr(" Status Register=");
Uart0_SendStr(num2Str2(I2C_Read_byte(0x0f,0)));
Uart0_SendStr(" Year=");
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(' ');
I2C_Stop();
}
}
[ 本帖最后由 doleph 于 2011-8-7 11:13 编辑 ]一周热门 更多>