我用89C51访问24C02无反应.
24C02时钟接P1.7,数据接P1.6,A0 A1 A2接地
执行函数:I2C_Write(0xA0,0x01,0);I2C_Read(0xA1,0x01,&c);都直接返回0
24C02.H
- #ifndef __24C02_H__
- #define __24C02_H__
- #ifndef uchar
- #define uchar unsigned char
- #endif
- #ifndef uint
- #define uint unsigned int
- #endif
- #ifndef ulong
- #define ulong unsigned long
- #endif
- #define I2C_TIMEOUT 255
- #define CTRL_BASE_ADDR_I2C 0x90
- #define I2C_CLK_PIN 7
- #define I2C_DATA_PIN 6
- //Extern Function
- bit I2C_Read(uint I2C_Addr,uint Byte_Addr,uchar *c);
- bit I2C_Write(uint I2C_Addr,uint Byte_Addr,uchar dat);
- //Internal Function
- void I2CSend(uchar dat);
- uchar I2CRecv();
- void I2C_Start();
- void I2C_Stop();
- void I2C_ACK();
- void I2C_NOACK();
- bit I2C_CHK_ACK();
-
- #endif
24C02.C
补充一点:
我是用Proteus仿真的.89C51时钟为24MHz
Proteus有一个IIC的接收端模拟控件
LZ可以先把你的IIC口连到上面,看你的S,P等等信号是否正确
24M时钟,最好就那些延时的地方都稍微加大一点。。呵呵,不过我对Proteus一直不放心。。。
我在proteus上面也仿真过这个,邮箱地址给我,我发给你~~
我在上传中,帮忙两个都发下,谢谢
yuchongjike@163.com;
amethystyu@msic.com.cn
能否帮忙看下程序方面是否有问题.(咱先不管时钟多少).
我从网上下载了一个I2C的程序,从书上也找了一个I2C的程序都不行.
不知道和Proteus里面的24C02的属性设置是否有关(我是直接把元件拖出来就用的.).
命令:
Write(0xA0,0x00,'T');
Write(0xA0,0x01,'E');
Write(0xA0,0x02,'S');
Write(0xA0,0x03,'T');
Write(0xA0,0x10,'O');
Write(0xA0,0x11,'K');
用Proteus的I2C窗口查看:
S A0 N 00 N 54 N P
S A0 N 01 N 45 N P
S A0 N 02 N 53 N P
S A0 N 03 N 54 N P
S A0 N 10 N 4F N P
S A0 N 11 N 4B N P
查看I2C的内容均为FF.
这里的N说的是没有应答?????24C02没应答????
I2C只要完全按照时序来 一般没什么问题, 下面是个PIC上的程序,调试成功的。
- /****************************************************/
- /*杭州晶控电子有限公司 */
- /*http://www.hificat.com */
- /*EEPROM读写演示程序 */
- /*目标器件:PIC16F877A */
- /*晶振:4.0MHZ */
- /*编译环境:MPLAB V7.51 */
- /****************************************************/
- /****************************************************************************
- 包含头文件
- ****************************************************************************/
- #include
- /****************************************************************************
- 数据定义
- ****************************************************************************/
- #define address 0xa
- #define nop() asm("nop")
- #define OP_READ 0xa1 // 器件地址以及读取操作
- #define OP_WRITE 0xa0 // 器件地址以及写入操作
- /****************************************************************************
- 端口定义
- ****************************************************************************/
- #define SCL RB4
- #define SDA RB5
- #define SCLIO TRISB4
- #define SDAIO TRISB5
- /****************************************************************************
- 共阴LED段码表
- ****************************************************************************/
- const char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
- /****************************************************************************
- 函数功能:延时子程序
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void delay()
- {
- int i;
- for(i=0;i<100;i++)
- {;}
- }
- /****************************************************************************
- 函数功能:开始信号
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void start()
- {
- SDA=1;
- nop();
- SCL=1;
- nop();nop();nop();nop();nop();
- SDA=0;
- nop();nop();nop();nop();nop();
- SCL=0;
- nop();nop();
- }
- /****************************************************************************
- 函数功能:停止信号
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void stop()
- {
- SDA=0;
- nop();
- SCL=1;
- nop();nop();nop();nop();nop();
- SDA=1;
- nop();nop();nop();nop();
- }
- /****************************************************************************
- 函数功能:读取数据
- 入口参数:
- 出口参数:read_data
- ****************************************************************************/
- unsigned char shin()
- {
- unsigned char i,read_data;
- for(i=0;i<8;i++)
- { nop();nop();nop();
- SCL=1;
- nop();nop();
- read_data<<=1;
- if(SDA == 1)
- read_data=read_data+1;
- nop();
- SCL=0;
- }
- return(read_data);
- }
- /****************************************************************************
- 函数功能:向EEPROM写数据
- 入口参数:write_data
- 出口参数:ack_bit
- ****************************************************************************/
- bit shout(unsigned char write_data)
- {
- unsigned char i;
- unsigned char ack_bit;
- for(i = 0; i < 8; i++)
- {
- if(write_data&0x80)
- SDA=1;
- else
- SDA=0;
- nop();
- SCL = 1;
- nop();nop();nop();nop();nop();
- SCL = 0;
- nop();
- write_data <<= 1;
- }
- nop();nop();
- SDA = 1;
- nop();nop();
- SCL = 1;
- nop();nop();nop();
- ack_bit = SDA; // 读取应答
- SCL = 0;
- nop();nop();
- return ack_bit; // 返回AT24Cxx应答位
- }
- /****************************************************************************
- 函数功能:向指定地址写数据
- 入口参数:addr,write_data
- 出口参数:
- ****************************************************************************/
- void write_byte(unsigned char addr, unsigned char write_data)
- {
- start();
- shout(OP_WRITE);
- shout(addr);
- SDAIO = 0; //在写入数据前SDA应设置为输出
- shout(write_data);
- stop();
- delay();
- }
- /****************************************************************************
- 函数功能:向指定地址读数据
- 入口参数:random_addr
- 出口参数:read_data
- ****************************************************************************/
- unsigned char read_random(unsigned char random_addr)
- { unsigned char read_data;
- start();
- shout(OP_WRITE);
- shout(random_addr);
- start();
- shout(OP_READ);
- SDAIO = 1; //读取数据前SDA应设置为输入
- read_data = shin();
- stop();
- return(read_data);
- }
- /****************************************************************************
- 函数功能:显示子程序
- 入口参数:k
- 出口参数:
- ****************************************************************************/
- void display(unsigned char k)
- {
-
- TRISA=0X00; //设置A口全为输出
- PORTC=table[k/1000]; //显示千位
- PORTA=0xEF;
- delay();
- PORTC=table[k/100%10]; //显示百位
- PORTA=0xDF;
- delay();
-
- PORTC=table[k/10%10]; //显示十位
- PORTA=0xFB;
- delay();
- PORTC=table[k%10]; //显示个位
- PORTA=0xF7;
- delay();
- }
- /****************************************************************************
- 函数功能:主程序
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void main()
- {
- unsigned char eepromdata;
- TRISB=0X00;
- OPTION&=~(1<<7); //设置RB口内部上拉电阻有效
- TRISC=0X00;
- PORTB=0X00;
- PORTC=0xff;
- TRISA=0X00;
- eepromdata=0;
- write_byte(0x01,0x55); //向0x01地址写入0x55(85)的数据
- delay();
- write_byte(0x02,0xaa); //向0x02地址写入0xAA(170)的数据
- delay();
- eepromdata=read_random(0x02); // 读取其中一个地址内的数据来验证
- while(1)
- {
- display(eepromdata);
- }
- }
感谢beyongmind大哥.已经好了.
偶在比对一下执行过程,还是要找出原程序的问题.
你再看一下时序图,在每次用完后是否保证信号的下次有效性。
bit I2C_Read(uint I2C_Addr,uint Byte_Addr,uchar *c)
{
I2C_Start();
I2CSend(I2C_Addr & 0xFE);
读的话 地址的方向位 应该 置1, 你置0了 不对