#define F_CPU 11059200
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <util/delay.h>
unsigned char buf[8];
const unsigned char seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
unsigned char id = 0;
void seg_scan(void)
{
unsigned char i;
unsigned char n = buf[id];
for (i = 7; i >= 5; i--)
{
PORTC = ~_BV(i);
PORTA = seg8[n % 10];
_delay_ms(3);
PORTA = 0xff;
n /= 10;
}
n = id;
for (i = 1; i <= 1; i--)
{
PORTC = ~_BV(i);
PORTA = seg8[n % 10];
_delay_ms(3);
PORTA = 0xff;
n /= 10;
}
}
void read(unsigned char addr)
{
TWCR |= _BV(TWSTA) | _BV(TWINT); // 開始信號
while ((TWCR & _BV(TWINT)) == 0); // 等待發送完畢
TWCR &= ~(_BV(TWSTA) | _BV(TWINT)); // 清除開始信號標誌, 同時要保證TWINT未被寫1, 以免執行了新的操作
TWDR = 0xa0; // 器件地址+寫信號
TWCR |= _BV(TWINT); // 開始發送
while ((TWCR & _BV(TWINT)) == 0); // 等待發送完畢
TWDR = addr; // 存儲單元地址
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
TWCR |= _BV(TWSTA) | _BV(TWINT); // 再次發送開始信號
while ((TWCR & _BV(TWINT)) == 0);
TWCR &= ~(_BV(TWSTA) | _BV(TWINT));
TWDR = 0xa1; // 器件地址+讀信號
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
// 連續讀三個位元組
TWCR |= _BV(TWEA) | _BV(TWINT); // TWEA=1: 接收時發送的是應答信號, 告訴器件需要更多數據, TWINT=1: 開始接收
while ((TWCR & _BV(TWINT)) == 0);
buf[addr] = TWDR;
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
buf[addr + 1] = TWDR;
TWCR &= ~_BV(TWEA); // TWEA=0: 接收的是最後一位元組數據, 發送非應答
while ((TWCR & _BV(TWINT)) == 0);
buf[addr + 2] = TWDR;
TWCR |= _BV(TWSTO) | _BV(TWINT); // 結束信號, TWSTO是自動清除的
}
void write(void)
{
unsigned char i;
TWCR |= _BV(TWSTA) | _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
TWCR &= ~(_BV(TWSTA) | _BV(TWINT)); // 清除TWSTA, 同時要保證TWINT未被寫1
TWDR = 0xa0;
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
TWDR = 0; // 存儲單元地址
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
// 寫入8位元組數據
for (i = 0; i < 8; i++)
{
TWDR = 100 + i * 10 + i;
TWCR |= _BV(TWINT);
while ((TWCR & _BV(TWINT)) == 0);
}
// 結束
TWCR |= _BV(TWSTO) | _BV(TWINT);
_delay_ms(1); // 等待24C08存儲器擦寫完畢
}
int main(void)
{
TWBR = 3;
TWSR = 2;
TWCR |= _BV(TWEN); // 開TWI
write();
read(5); // 第5~7位元組
read(0); // 第0~2位元組
read(3); // 第3~5位元組
TWCR &= ~_BV(TWEN); // 數碼管要佔用PC口, 所以將TWI關掉
TIMSK |= _BV(TOIE1); // 開定時器中斷
sei(); // 開總中斷
TCCR1B |= _BV(CS12); // 定時器256分頻
DDRA = DDRC = 0xff;
while (1)
seg_scan();
}
ISR(TIMER1_OVF_vect)
{
id = (id + 1) % sizeof(buf);
}