正在做的一个产品需要用TWI口读写24c16,直接copy了 AVR学习笔记上的一个使用查询方式读写24c16的程序,可是加进我的测试程序以后却怎么也不行???//AT24C16地址声明
#define EEPROM_BUS_ADDRESS 0xa0 //器件地址
//主机发送模式时各状态字的后续动作
#define TW_START 0x08 //开始信号已发出
#define TW_REP_START 0x10 //重复开始信号已发出
#define TW_MT_SLA_ACK 0x18 //写字节已发出并收到ACK信号
#define TW_MT_SLA_NACK 0x20 //写字节已发出并收到NACK信号
#define TW_MT_DATA_ACK 0x28 //数据已发出并收到ACK 信号
#define TW_MT_DATA_NACK 0x30 //数据已发出并收到NACK 信号
#define TW_MT_ARB_LOST 0x38 //丢失总线控制权
//主机接收模式时各状态字的后续动作
#define TW_MR_ARB_LOST 0x38 //丢失总线控制权,未收到应答信号
#define TW_MR_SLA_ACK 0x40 //读命令已发出并收到ACK
#define TW_MR_SLA_NACK 0x48 //读命令已发出并收到NACK
#define TW_MR_DATA_ACK 0x50 //数据已收到,ACK已发出
#define TW_MR_DATA_NACK 0x58 //数据已收到,NACK已发出
unsigned long E1_data=0,E2_data=0; //E1_data:机车牵引消耗电量,E2_data:机车再生制动电量
uchar count,count_1,count_2,flag; //标志位
void Initial_MCU(void); //Atmega16初始化程序
void Write_7219(uchar address,uchar data); //MAX7219地址、数据发送子程序
void Initial_7219(void); //MAX7219初始化程序
void Show_7219(unsigned long data); //计算8个数码管分别显示的数字
void I2C_Init(void); //I2C端口初始化
uchar I2C_Start(void); //发送起始信号
void I2C_Stop(void); //发送结束信号
uchar I2C_WriteByte(uchar data); //写一个字节
uchar I2C_ReadByte(uchar ack); //读一个字节
uchar EEPROM_ReadByte(uint add); //从固定地址读一字节
void EEPROM_WriteByte(uint add,uchar data); //向固定地址写一字节
void EEPROM_ReadPage(uint add,uchar n,uchar *data); //多字节读操作
void EEPROM_WritePage(uint add,uchar n,uchar *data); //多字节写操作
//I2C初始化函数
void I2C_Init(void)
{
TWSR = 0x00; //不分频
TWBR = 0x20; //波特率f(scl)=100kHz
TWAR = 0x00; //被控器地址寄存器
TWCR = (1 << TWEA) | (1 << TWEN); //允许ACK,使能I2C,PC0、PC1转换成SCL、SDA引脚
}
//I2C起始条件
uchar I2C_Start(void)
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); //清零中断标志位,发送START信号
while(!(TWCR & (1 << TWINT))); //检测中断标志,为1表明完成发送开始信号
return 1;
}
//I2C结束条件
void I2C_Stop(void)
{
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); //清零中断标志位,发送STOP信号
}
//向I2C写一个字节
uchar I2C_WriteByte(uchar data)
{
uchar ack;
TWDR = data; //发送数据写入I2C数据寄存器
TWCR = (1 << TWINT) | (1 << TWEN); //清零中断标志位,开始发送
while(!(TWCR & (1 << TWINT))); //等待发送完成
if((TWSR &0xf8) != TW_MT_SLA_ACK) //读取ACK信号
{
ack = 0; //没有返回ACK
}
else
{
ack = 1; //返回ACK
}
return ack;
}
//从I2C读一个字节 ACK时,应答,NACK时,不应答
uchar I2C_ReadByte(uchar ack)
{
if (ack)
TWCR = (1<<TWINT) | (1<<TWEA) | (1 << TWEN); // 读数据,并回送ACK
else
TWCR = (1<<TWINT) | (1 << TWEN); //读数据,并回送NACK
while (!(TWCR & (1 << TWINT))); //等待操作完成
return (TWDR); //返回读到的数据
}
//从固定地址读一字节
uchar EEPROM_ReadByte(uint add)
{
uchar data;
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add >> 8) << 1));
//发器件地址和页地址高三位
I2C_WriteByte(add);
// 发页地址低4位和页地址偏移量
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | 0x01);
// 发从机读寻址字节
data = I2C_ReadByte(0); //读数据,并发送NACK
I2C_Stop();
// 发停止信号
return data;
}
//向固定地址写一字节
void EEPROM_WriteByte(uint add,uchar data)
{
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add >> 8) << 1));
// 发器件地址和页地址高三位
I2C_WriteByte(add);
// 发页地址低4位和页地址偏移量
I2C_WriteByte(data);
// 写一个字节数据到24C16
I2C_Stop();
// 发停止信号
delay_nms(10);
// 等待10ms,保证24C16内部写操作完成再进行新操作
}
//多字节读操作
void EEPROM_ReadPage(uint add,uchar n,uchar *data)
{
uchar i;
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add >> 8) << 1));
//发器件地址和页地址高三位
I2C_WriteByte(add);
// 发页地址低4位和页地址偏移量
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | 0x01);
// 发从机读寻址字节
for(i = 0;i < n-1;i++) //读n-1个数据
{
*data = I2C_ReadByte(1); //读数据,并发送ACK
data++;
}
*data = I2C_ReadByte(0); //读 最后一个数据,并发送NACK
I2C_Stop();
// 发停止信号
}
//多字节写操作
void EEPROM_WritePage(uint add,uchar n,uchar *data)
{
uchar i;
I2C_Start();
// 发起始信号
I2C_WriteByte(EEPROM_BUS_ADDRESS | ((add >> 8) << 1));
// 发器件地址和页地址高三位
I2C_WriteByte(add);
// 发页地址低4位和页地址偏移量
for(i = 0;i <= n-1;i++)
{
I2C_WriteByte(*data++);
// 写一个字节数据到24C16
}
I2C_Stop();
// 发停止信号
delay_nms(10);
// 等待10ms,保证24C16内部写操作完成再进行新操作
}
主程序里加了:
I2C_Init();
EEPROM_WriteByte(0x01aa,0x5a);
E1_data=EEPROM_ReadByte(0x01aa);
我的测试程序原先一直运行正常,加了这个读写的程序以后好像就一直不停复位。。。。。查了好久查不出问题,求高手帮忙,急急急! |