2013-04-03 23 views
0

訪問RTC(DS1307)我已經寫了代碼中使用ATmega16單片機通過I2C訪問RTC(DS1307),我使用的編譯器AVR Studio的4通過I2C在ATmega16的

守則如下: -

#include<avr/io.h> 
#include<util/delay.h> 
#define F_CPU 1000000UL 

void rtc_init(void) 
{ 
TWSR=0x00; 
TWBR=0x47; 
TWCR=0x04; 

} 

void rtc_start(void) 
{ 
TWCR=(1<<TWEN)|(1<<TWSTA)|(1<<TWINT); 

while(TWCR & (1<<TWINT)==0); 

} 


unsigned char rtc_read(void) 
{ 
TWCR=(1<<TWINT)|(1<<TWEN); 
while(!(TWCR & (1<<TWINT))); 
return(TWDR); 
} 

void rtc_write(unsigned char data) 
{ 
TWDR=data;// sending address 
TWCR=(1<<TWINT)|(1<<TWEN); 
while(TWCR & (1<<TWINT)==0); 
} 

void rtc_stop() 
{ 
TWCR=(1<<TWINT)|(TWSTO)|(1<<TWEN); 
while(TWCR & (1<<TWINT)==0); 

} 

main() 
{ 
unsigned char sec,min,hr; 
DDRA=0xFF; 
DDRB=0xFF; 


rtc_init(); 
_delay_ms(1000); 

rtc_start(); 

rtc_write(0b11010000); // 1101000=adress of ds1307 and bit 0= write 
rtc_write(0x00); // pointing address location 00 i.e seconds 
rtc_write(0x00);// set sec=0 
rtc_write(0x00);// set min=0 
rtc_write(0x00);// set hr=0 

rtc_stop(); 


while(1) 
{ 

rtc_start(); 
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read 
rtc_write(0x00); // pointing address location 00 i.e seconds 
sec=rtc_read(); 
rtc_stop(); 
PORTA=sec; 
PORTB=0x01; 
_delay_ms(5000); 
rtc_start(); 
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read 
rtc_write(0x01); // pointing address location 00 i.e seconds 
min=rtc_read(); 
rtc_stop(); 
PORTA=min; 
PORTB=0x02; 
_delay_ms(5000); 
rtc_start(); 
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read 

hr=rtc_read(); 
rtc_stop(); 
PORTA=hr; 
PORTB=0b00000100; 
_delay_ms(5000); 
} 
} 

我已經成功地建立了上面的代碼。當我在PROTEUS模擬器上運行這段代碼時,我沒有得到任何輸出,只是輪詢代碼正常工作以應用延遲。

我想知道我做錯了什麼地方以及如何解決它。

回答

1

我不認爲你正在產生正確的開始條件,等等。從數據表(第183頁):

TWI傳輸的第一步是傳輸START條件。 這是通過向TWCR中寫入一個特定值來完成的,指示TWI硬件發送START條件。編寫哪個值是 ,稍後會介紹。但是,寫TWINT位的值必須設置爲 。寫一個TWINT清除標誌。只要TWCR中的TWINT位置1,TWI 就不會啓動任何操作。 緊接在應用程序清除TWINT後,TWI將 開始傳輸START條件。

有看起來像這樣在數據表中詳細C的例子:

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) //Send START condition 
while (!(TWCR & (1<<TWINT)));   // Wait for TWINT Flag set. This indicates 
             // that the START condition has been transmitted 
if ((TWSR & 0xF8) != START)    // Check value of TWI Status Register. Mask 
    ERROR();       // prescaler bits. If status different from 
             // START go to ERROR 
TWDR = SLA_W;       // Load SLA_W into TWDR Register. Clear 
TWCR = (1<<TWINT) | (1<<TWEN);   // TWINT bit in TWCR to start transmission 
             // of address 
while (!(TWCR & (1<<TWINT)));   // Wait for TWINT Flag set. This indicates 
             // that the SLA+W has been transmitted, 
             // and ACK/NACK has been received. 
if ((TWSR & 0xF8) != MT_SLA_ACK)  // Check value of TWI Status Register. Mask 
    ERROR();       // prescaler bits. If status different from 
             // MT_SLA_ACK go to ERROR 
TWDR = DATA;       // Load DATA into TWDR Register. Clear 
TWCR = (1<<TWINT) | (1<<TWEN);   // TWINT bit in TWCR to start transmission 
             // of data 
while (!(TWCR & (1<<TWINT)));   // Wait for TWINT Flag set. This indicates 
             // that the DATA has been transmitted, and 
             // ACK/NACK has been received. 
if ((TWSR & 0xF8) != MT_DATA_ACK)  // Check value of TWI Status Register. Mask 
    ERROR();       // prescaler bits. If status different from 
             // MT_DATA_ACK go to ERROR 
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Transmit STOP condition 

那是從你的代碼非常不同。我首先從數據表中抽取樣本,然後從那裏開始。