0

我已经编写了一个代码来使用 ATmega16 通过 I2C 访问 RTC(DS1307),并且我正在使用编译器 AVR Studio 4。

代码如下: -

#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 模拟器上运行此代码时,我没有得到任何输出,但在代码中轮询正常工作以应用延迟。

我想知道我在哪里做错了以及如何解决它。

4

1 回答 1

1

我认为您没有正确生成启动条件等。从数据表(第 183 页):

TWI 传输的第一步是传输 START 条件。这是通过将特定值写入 TWCR 来完成的,指示 TWI 硬件发送 START 条件。稍后将描述要写入的值。但是,重要的是在写入的值中设置 TWINT 位。向 TWINT 写入 1 会清除该标志。只要 TWCR 中的 TWINT 位置位,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

这与您的代码非常不同。我将从数据表中的示例开始,然后从那里开始。

于 2013-04-03T20:30:29.167 回答