|
请高分帮忙解决一下我的问题:
1. 用以下程序读写24C16时出现问题了: 我调用 I2C_Write(read_data,0x0001,1); 用I2C_Read(read_data,0x02XX,1)读时XX是[01-ff任意数] 0001-00ff 地址范围 全是刚才写入的那个字节数据.
2.我调用 I2C_Write(read_data,0x0101,16); 按页写入的数据.结果15与16字节是0XFF,
3.我调用 I2C_Write(read_data,0x0201,16); 按页写入的数据.结果13,14,15与16字节是0XFF,
4.我调用 I2C_Write(read_data,0x0301,16); 按页写入的数据.结果11,12,13,14,15与16字节是0XFF,
5.一直调用 I2C_Write(read_data,0x0701,16); 按页写入的数据.结果就能写入2个正确的字节
是我的24C16地址的理解问题吗? 我是这么理解的,24C16一共有128页,一页为16字节, 那0页的地址范围是00-0F,1页的为10-1f......
以上问题我搞了一周了,也不行.高手们帮帮我吧.!!!注,数据是从网上搜索并修改的.
//MyIIC.C
#include <iom8.h>
#include "MyDelay.h"
#include "MyUSART.h"
,
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//变量声明
#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已发出
#define SET_1(a,b) a |= (1<<b)
#define CLE_0(a,b) a &= (~(1<<b))
//I2C初始化函数
void I2C_Init(void)
{
TWSR = 0x02; //不分频
// TWBR = 0x00; //波特率
TWAR = 0x00; //被控器地址寄存器
/*TWCR 寄存器*************************************************************************************
7 6 5 4 3 2 1 0
TWINT TWEA TWSTA TWSTO TWWC TWEN x TWIE
**************************************************************************************************/
TWCR |= 0x44; //允许ACK,使能I2C,PC0、PC1、转换成SCL、SDA引脚
}
//向I2C写一个字节
uchar I2C_Write(uchar *dat,uint addr,uchar n)
{
uchar addrl,addrh,i;
addrl = (uchar)addr;
// addrl = 0x02;
addrh = 0xa0 | ((addr >> 8) << 1);
TWBR = 14;//设置波特率
TWCR |= 0xa4; //清零中断标志位,发送START信号
while(!(TWCR & 0x80)); //检测中断标志,为1表明完成发送开始信号
if((TWSR & 0xf8) != 0x08)//启动总线失败
{
TWCR |= 0x94; // 停止
return 1;
}
TWDR = addrh ; //写从器件地址( 1010+页地址高三位+R/W)
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x18) //从地址+写信号发送失败
{
TWCR |= 0x94; // 停止
return 2;
}
TWCR &= 0xdf; //手动清START信号
TWDR = addrl;//子地址(24C16地址) 页地址低四位+第几字节
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x28) //数据发送失败
{
TWCR |= 0x94; // 停止
return 3;
}
for(i=0;i<n;i++) //向总线写n个数据
{
TWDR = *(dat+i);
// USART_Send(TWDR);
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x28) //数据发送失败
{
TWCR |= 0x94; // 停止
return 4;
}
}
TWCR |= 0x94; //停止位,并复位SDL与SCL线为普通IO口
delay_ms(10);
return 0;//操作成功
}
uchar I2C_Read(uchar *dat,uint addr,uchar n)
{
uchar addrl,addrh,i;
addrl = (uchar)addr;
addrh = 0xa0 | ((addr >> 8)<< 1);
TWBR = 14;//设置波特率
TWCR |= 0xa4; //清零中断标志位,发送START信号
while(!(TWCR & 0x80)); //检测中断标志,为1表明完成发送开始信号
if((TWSR & 0xf8) != 0x08)//启动总线失败
{
TWCR |= 0x94; // 停止
return 1;
}
TWDR = addrh; //写从器件地址(固定地址1010)
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x18) //从地址+写信号发送失败
{
TWCR |= 0x94; // 停止
return 2;
}
TWCR &= 0xdf; //手动清START信号
TWDR = addrl;//子地址(24C16地址)
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x28) //数据发送失败
{
TWCR |= 0x94; // 停止
return 3;
}
TWCR |= 0xa4; //重新启动总线
while(!(TWCR & 0x80)); //检测中断标志,为1表明完成发送开始信号
if((TWSR & 0xf8) != 0x10)//启动总线失败
{
TWCR |= 0x94; // 停止
return 4;
}
TWDR = addrh | 0x01; //写从器件地址(固定地址1010)
TWCR |= 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x40) //从地址+写信号发送失败
{
TWCR |= 0x94; // 停止
return 5;
}
for(i=0;i<n-1;i++) //读n个字节数据
{
TWCR = 0xc4;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x50) //数据接收失败
{
TWCR |= 0x94; // 停止
return 6;
}
*(dat + i) = TWDR;
USART_Send(TWDR); //用串口显示
}
TWCR = 0x84;
while(!(TWCR & 0x80)); //等待发送完成
if((TWSR & 0xf8) != 0x58) //数据接收失败
{
TWCR |= 0x94; // 停止
return 7;
}
*(dat + i) = TWDR;
USART_Send(TWDR); //用串口显示
TWCR |= 0x94; //停止位,并复位SDL与SCL线为普通IO口
// delay_ms(10);
return 0;//操作成功
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|