#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); }
|