请教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
|