我编写了一个使用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模拟器上运行此代码时,我没有得到任何输出,但在代码中轮询正常工作以应用延迟。
我想知道我做错了什么以及如何解决它。
答案 0 :(得分:1)
我认为你没有正确地生成开始条件等等。从数据表(第183页):
TWI传输的第一步是发送START条件。 这是通过将特定值写入TWCR,指示 用于传输START条件的TWI硬件。要写的是哪个值 稍后描述。但是,设置TWINT位很重要 在写的价值。向TWINT写一个清除标志。 TWI 只要TWCR中的TWINT位置1,就不会启动任何操作。 应用程序清除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
这与您的代码非常不同。我从数据表中的样本开始,然后从那里开始。