Embedded 通过ATmega16中的I2C访问RTC(DS1307)

Embedded 通过ATmega16中的I2C访问RTC(DS1307),embedded,microcontroller,i2c,avr-gcc,real-time-clock,Embedded,Microcontroller,I2c,Avr Gcc,Real Time Clock,我已经编写了一段代码,使用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)|

我已经编写了一段代码,使用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);
}
}
#包括
#包括
#定义F_CPU 1000000UL
无效rtc_init(无效)
{
TWSR=0x00;
TWBR=0x47;
TWCR=0x04;
}
无效rtc_启动(无效)
{

TWCR=(1除其他外,我认为您没有正确生成启动条件。从数据表(第183页)中:

TWI传输的第一步是传输启动条件。 这是通过将特定值写入TWCR,指示 TWI硬件传输启动条件。要写入的值是 但设置TWINT位很重要 在写入的值中。将一写入TWINT将清除标志。TWI 只要设置了TWCR中的TWINT位,就不会启动任何操作。 应用程序清除TWINT后,TWI将立即 启动启动条件的传输

数据表中有一个详细的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
TWCR=(1)