|
发表于 2011-8-2 13:53:50
|
显示全部楼层
我有个简单的例子,不知道是否可以帮上忙
/*****************************************************
CodeWizardAVR V1.25.9 Professional
Chip type : ATmega48
Clock frequency : 8.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/
// TWCR 寄存器说明
// Bit 7 – TWINT: TWI 中断标志
// Bit 6 – TWEA: 使能TWI 应答
// Bit 5 – TWSTA: TWI START 状态位
// Bit 4 – TWSTO: TWI STOP 状态位
// Bit 3 – TWWC: TWI 写冲突标志
// Bit 2 – TWEN: TWI 使能
// Bit 1 – Res: 保留
// Bit 0 – TWIE: TWI 中断使能
#include <mega48.h>
#include <delay.h>
#include <nokia3310.h>
#define twi_start TWCR=0b10100101; //主机发出start信号
#define twi_data_run TWCR=0b10000101; //清除中断.启动.停止的标记/启动主机数据收或发
#define twi_data_run_ack TWCR=0b11000101; //清除中断.启动.停止的标记/启动主机数据收或发/应答使能
#define twi_stop TWCR=0b11010101; //主机停止/释放总线/TWI就绪
#define twi_status TWSR //TWI运行状态
#define twi_datas TWDR
unsigned char inbox[8], outbox[8], news[8]; //收件箱/发件箱/新信息
unsigned char twi_mode; //主机发送器=10/主机接收器=20/从机发送器=30/从机接收器=40
unsigned char n=0, x=0; //需要传输的字节的个数 x
unsigned char address_device, address_paga; //器件地址/器件内部的页地址
interrupt [TWI] void twi_isr(void)
{
lcd_puthex(twi_status); //监视TWI运行状态
switch(twi_status)
{
case 0x08: //start信号已发送
{
twi_datas=address_device+0; //器件地址+发送模式(SLA+W)
twi_data_run; //传输数据
break;
}
case 0x10: //重复start信号已发送
{
twi_datas=address_device+1; //器件地址+接收模式(SLA+R)
twi_data_run; //传输数据
break;
}
case 0x18: //SLA+W已发送,接收到ACK
{
n=0; //计数复位
twi_datas=address_paga; //页地址
twi_data_run; //传输数据
break;
}
case 0x28: //数据已发送,接收到ACK
{
if(twi_mode==20) {twi_start; break;} //再次发送start信号
if(n>=x) {twi_stop; break;} //数据发送完毕就发送stop信号
twi_datas=outbox[n]; //继续加载数据
twi_data_run;
n++;
break;
}
case 0x40: //SLA+R已发送,接收到ACK
{
n=0; //计数复位
if(x>1)twi_data_run_ack; else twi_data_run; //如果主机只接收一个数据就不需要返回ack信号
break;
}
case 0x50: //接收到数据 ACK 已返回(主机返回应答ACK)
{
news[n]=twi_datas; //保存接收到的数据
if(n+2<x) twi_data_run_ack; else twi_data_run; //接收到倒数第二个数据时就取消接收应答并继续接收
n++;
break;
}
case 0x58: //接收到数据 NO ACK 已返回
{
news[n]=twi_datas;
twi_stop;
break;
}
default:
{
twi_stop;
break;
}
}
}
//*******************************************************************************************************************
void main(void)
{
delay_ms(10);
lcd_init();
lcd_cls();
TWBR=32; //8MHz/(16+2*32)=100KHz
#asm("sei") //打开全局中断
while (1)
{
//写数组到AT24C02的指定页
lcd_gotoxy(0,0);
twi_mode=10; x=4; //主机:发送模式/需要发送的字节个数(不含地址和页2个字节)
address_device=160; address_paga=0; //器件地址和页地址
outbox[0]=1; outbox[1]=2; outbox[2]=3; outbox[3]=4; //更新发件箱的数据
twi_start; //主机发送start信号
delay_ms(10);
lcd_puthex(twi_status);
//连续读AT24C02指定页地址的数组
lcd_gotoxy(0,2);
twi_mode=20; x=5; //主机:接收模式/需要接收的字节个数(不含地址和页2个字节)
address_device=160; address_paga=0; //器件地址和页地址
twi_start;
delay_ms(10);
lcd_puthex(twi_status);
//将新信息复制到收件箱并显示
lcd_gotoxy(0,5);
for(n=0;n<x;n++) {inbox[n]=news[n]; lcd_puthex(inbox[n]);}
lcd_putchar(' '); lcd_puthex(TWCR);
while(1);
};
}
点击此处下载 ourdev_663552UERRDK.rar(文件大小:47K) (原文件名:M48读写AT24C02 001.rar) |
|