打印
[51单片机]

I2C通信———求大神看一下问题到底出在哪?

[复制链接]
4021|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
鼹鼠|  楼主 | 2013-11-14 23:35 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 鼹鼠 于 2013-11-14 23:58 编辑
#include<reg52.h>
#include<INTRINS.H>

typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;

sbit SCL = P3^7;
sbit SDA = P3^6;

void Delay(void)
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
}

void InitI2C(void)
{
        SDA = 1;
        SCL = 1;
}

void I2CStart(void)
{
        SDA = 1;
        Delay();
        SCL = 1;
        Delay();
        SDA = 0;
        Delay();
        SCL = 0;
}

void I2CStop(void)
{
        SCL = 0;
        Delay();
        SDA = 0;
        Delay();
        SCL = 1;
        Delay();
        SDA = 1;
        Delay();
}

void I2CSend(uint8 byte)
{
        uint8 mask;
        uint8 i,j;

        mask = 0x80;
        for(i = 0;i < 8;i--)
        {
                SCL = 0;
                Delay();
                if((mask & byte) == 0)
                {
                        SDA = 0;
                }
                else
                {
                        SDA = 1;
                }
                mask >>= 1;
                Delay();
        }

        SCL = 0;
        SDA = 1;
        Delay();
        SCL = 1;
        j = SDA;
        Delay();
        SCL = 1;
}

uint8 I2CRead(void)
{
        uint8 byte;
        uint8 i;

        byte = 0;
        for(i = 0;i < 8;i--)
        {
                SCL = 0;
                SDA = 1;
                Delay();
                SCL = 1;
                Delay();
                byte <<= 1;
                if(SDA == 1)
                {
                        byte |= 0x01;
                }
                Delay();
        }
        SCL = 0;
        SDA = 1;
        Delay();
        SCL = 1;
        Delay();
        SCL = 0;
        return byte;
}

uint8 I2CReadAck(void)
{
        uint8 i;
        uint8 byte;

        byte = 0;
        for(i = 0;i < 8;i--)
        {
                SCL = 0;
                SDA = 1;
                Delay();
                SCL = 1;
                Delay();
                byte <<= 1;
                if(SDA == 1)
                {
                        byte |= 0x01;
                }
                Delay();
        }
        SCL = 0;
        Delay();
        SDA = 0;
        Delay();
        SCL = 1;
        Delay();
        SCL = 0;

        return byte;
}

uint8 read_eeprom(uint8 addr)
{
        uint8 databyte;

        I2CStart();
        I2CSend(0xa0);
        I2CSend(addr);
        I2CStart();
        I2CSend(0xa1);
        databyte = I2CRead();
        I2CStop();

        return databyte;
}

void write_eeprom(uint8 addr,uint8 databyte)
{
        I2CStart();
        I2CSend(0xa0);
        I2CSend(addr);
        I2CSend(databyte);
        I2CStop();
}

void UART_init(void)
{
        SCON = 0X50;
        TMOD &= 0X0F;
        TMOD |= 0X20;
        TH1 = 0XFD;
        TL1 = 0XFD;
        TR1 = 1;
}

void UART_send_byte(uint8 dat)
{
        SBUF = dat;
        while(!TI);
        TI = 0;
}

void main(void)
{
        uint8 addr = 0x00,databyte = 0xe4;
        uint8 c = 0;
        uint16 i;

        UART_init();
        InitI2C();
        while(1)
        {
                write_eeprom(addr,databyte);
                for(i = 0;i < 1000;i++)
                {
                        Delay();
                }
                c = read_eeprom(addr);
                UART_send_byte(c);
                addr++;
                databyte++;
                if(addr == 0xff)
                {
                        addr = 0;
                }
                if(databyte == 0xff)
                {
                        databyte = 0;
                }
                for(i = 0;i < 1000;i--)
                {
                        Delay();
                }
        }
}
这个是主程序。。。新手求大神!!!

相关帖子

沙发
cjseng| | 2013-11-14 23:41 | 只看该作者
delay里面再加一个nop试试。

使用特权

评论回复
板凳
鼹鼠|  楼主 | 2013-11-14 23:47 | 只看该作者
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?I2CREADACK?I2C
Program Size: data=12.0 xdata=0 code=357
creating hex file from "I2C"...
"I2C" - 0 Error(s), 1 Warning(s).
这个是编译是出的问题 有一个警告
我用的是stc89v51rc的单片机 I2C用的是24lc02的芯片 程序的目的是把写进EEPROM的数据读回来然后送给调试串口调试助手正常的情况下调试助手应该显示的是01 02 03......fe ff 00 01 循环 但我的串口调试助手一直显示的是01 01 01......01 01  弄了好几遍了 一开始还出现过00 00 00 ......01 01 01 ...00 00 等

使用特权

评论回复
地板
鼹鼠|  楼主 | 2013-11-14 23:51 | 只看该作者
cjseng 发表于 2013-11-14 23:41
delay里面再加一个nop试试。

编译时提示警告是出在16行...但我找了下 想想问题应该不在16行 那个地方我加了个_nop_();还是一样的结果

使用特权

评论回复
5
鼹鼠|  楼主 | 2013-11-14 23:56 | 只看该作者
这个是串口调试助手上的

QQ图片20131114233247.jpg (161.64 KB )

QQ图片20131114233247.jpg

使用特权

评论回复
6
cjseng| | 2013-11-15 00:28 | 只看该作者
本帖最后由 cjseng 于 2013-11-15 00:33 编辑

步子迈的太大!
印度发射一个火星探测器,一年后没有到达火星,你说是什么问题?
你要先看看发射时,火箭有没有离开发射架,过两天再看看有没有进入环绕地球轨道,过段时间再看看有没有离开绕地轨道。。。

你可以把问题分解成几步来测试:
1.写进01,读出来,程序里自己比较一下,如果相同,亮个灯或者蜂鸣器响一声;
2.写进02,读出来,程序里自己比较一下,如果相同,亮个灯或者蜂鸣器响一声;
3.连续写进01、02、03、04...读出来,程序里自己比较一下,如果相同,亮个灯或者蜂鸣器响一声;
4.串口发送01、02、03、04、05...,看串口调试助手接收是否正常;
5.以上都正常,连起来测试。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
鼹鼠 + 1
7
ballack_linux| | 2013-11-15 01:26 | 只看该作者
你那个警告只是提示你I2CReadAck(void)这个函数你定义了但是没有调用!!
还有你的I2CSend(uint8 byte)函数里面那个for循环语句中忘记加SCL = 1了!!
给你一份测试过的代码:(没加串口打印),你比对着看看.
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P2^0;
sbit scl=P2^1;
void delay_ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void delay()
{;;}
void init()
{
        scl=1;
        delay();
        sda=1;
        delay();
}
void start()
{
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}
void stop()
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}
void reply()
{
        uchar i=0;
        scl=1;
        delay();
        while((sda==1)&&(i<200))i++;
        scl=0;
        delay();
}
void unreply()
{
        sda=1;
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
}                 
void write_byte(uchar dat)
{       
        uchar i;
        scl=0;
        delay();
        for(i=0;i<8;i++)
        {       
                if(dat&0x80)
                sda=1;
                else sda=0;
                dat<<=1;       
                 scl=1;
                delay();
                scl=0;
                delay();
        }
        sda=1;
        delay();
}

uchar read_byte()
{
        uchar i,num;
        scl=0;
        delay();
        sda=1;
        delay();
        for(i=0;i<8;i++)
        {
                scl=1;
                delay();
                num<<=1;
                if(sda)
                {
                        num++;
                }                          
                scl=0;
                delay();               
        }
        return num;       
}

void main()
{
        init();
        start();
        write_byte(0xa0);
        reply();
        write_byte(255);
        reply();
        write_byte(0xaa);
        reply();
        stop();
        delay_ms(100);

        start();
        write_byte(0xa0);
        reply();
        write_byte(255);
        reply();
        start();
        write_byte(0xa1);
        reply();
        P1=read_byte();
        unreply();
        stop();
        while(1);
}
          


使用特权

评论回复
8
鼹鼠|  楼主 | 2013-11-15 12:05 | 只看该作者
ballack_linux 发表于 2013-11-15 01:26
你那个警告只是提示你I2CReadAck(void)这个函数你定义了但是没有调用!!
还有你的I2CSend(uint8 byte)函数 ...

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P3^6;
sbit scl=P3^1;
void delay_ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void delay()
{;;}
void init()//I2C初始化函数...
{
        scl=1;
        delay();
        sda=1;
        delay();
}
void start()//发送总线起始状态函数
{
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}
void stop()//发送总线结束状态函数
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}
void reply()//发送应答位‘0’函数
{
        uchar i=0;
        scl=1;
        delay();
        while((sda==1)&&(i<200))i++;
        scl=0;
        delay();
}
void unreply()//发送非应答位 ‘1’
{
        sda=1;
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
}                 
void write_byte(uchar dat)//I2C写入待发送字节函数
{        
        uchar i;
        scl=0;
        delay();
        for(i=0;i<8;i++)
        {        
                if(dat&0x80)
                sda=1;
                else sda=0;
                dat<<=1;        
                 scl=1;
                delay();
                scl=0;
                delay();
        }
        sda=1;
        delay();
}

uchar read_byte()//输出接收到的字节
{
        uchar i,num;
        scl=0;
        delay();
        sda=1;
        delay();
        for(i=0;i<8;i++)
        {
                scl=1;
                delay();
                num<<=1;
                if(sda)
                {
                        num++;
                }                           
                scl=0;
                delay();               
        }
        return num;        
}



void UART_init(void)//串口初始化
{

QQ图片20131115120447.jpg (89.63 KB )

QQ图片20131115120447.jpg

使用特权

评论回复
9
鼹鼠|  楼主 | 2013-11-15 12:25 | 只看该作者
ballack_linux 发表于 2013-11-15 01:26
你那个警告只是提示你I2CReadAck(void)这个函数你定义了但是没有调用!!
还有你的I2CSend(uint8 byte)函数 ...

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P3^6;
sbit scl=P3^1;
void delay_ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void delay()
{;;}
void init()
{
        scl=1;
        delay();
        sda=1;
        delay();
}
void start()
{
        sda=1;
        delay();
        scl=1;
        delay();
        sda=0;
        delay();
}
void stop()
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}
void reply()
{
        uchar i=0;
        scl=1;
        delay();
        while((sda==1)&&(i<200))i++;
        scl=0;
        delay();
}
void unreply()
{
        sda=1;
        delay();
        scl=1;
        delay();
        scl=0;
        delay();
}                 
void write_byte(uchar dat)
{        
        uchar i;
        scl=0;
        delay();
        for(i=0;i<8;i++)
        {        
                if(dat&0x80)
                sda=1;
                else sda=0;
                dat<<=1;        
                 scl=1;
                delay();
                scl=0;
                delay();
        }
        sda=1;
        delay();
}
uchar read_byte()
{
        uchar i,num;
        scl=0;
        delay();
        sda=1;
        delay();
        for(i=0;i<8;i++)
        {
                scl=1;
                delay();
                num<<=1;
                if(sda)
                {
                        num++;
                }                           
                scl=0;
                delay();               
        }
        return num;        
}

void UART_init(void)
{
SCON = 0X50;
TMOD = 0X02;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;
}
void UART_send_byte(uint dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}

void main()
{
uint c;//定义一个变量c
UART_init();//串口配置函数
        init();//配置模拟I2C的IO口
        start();//发送总线起始状态
        write_byte(0xa0);//写入-发送首字节,选择写操作
        reply();//发送一个应答位0
        write_byte(255);//写入-数据所要存储的地址0xff;
        reply();//发送应答位
        write_byte(0xaa);//写入-所要存储在地址0xff中的数据(0xaa);
        reply();//发送一个应答位
        stop();//发送停止信号
        delay_ms(100);
//EEPROM读数据操作
        start();//起始信号
        write_byte(0xa0);//写入首字节,选择写操作
        reply();//等待发送应答位
        write_byte(255);//写入数据的存储地址
        reply();//等待发送应答位
        start();//重新发送起始信号
        write_byte(0xa1);//发送器件EEPROM的地址并选择读操作
        reply();
        //P1=read_byte();
   c = read_byte();//将读出来的数据给变量c
  UART_send_byte(c);//发送回调试助手
        unreply();//发送一个非应答位1
        stop();//发送结束
        while(1);//让程序停在这里
}
首先非常感谢指教!!!仔细的看了一下你的程序,尤其是返回应答位和应答位用子函数的形式写出来,写程序的思路更清晰,还有程序中的代码更简洁(我那个程序是一个老师在实际工程中的应用总结的方法)。我在这个程序中加了一个返回都调试助手的代码,我的分析是一开始是将0xaa存放到地址0xff的内存单元中,串口上读出来的应该是0xaa 可是我的串口调试助手上读出来的确实这个  。。。什么原因?

QQ图片20131115120447.jpg (89.63 KB )

QQ图片20131115120447.jpg

使用特权

评论回复
10
鼹鼠|  楼主 | 2013-11-15 13:05 | 只看该作者
cjseng 发表于 2013-11-15 00:28
步子迈的太大!
印度发射一个火星探测器,一年后没有到达火星,你说是什么问题?
你要先看看发射时,火箭有 ...

#include<reg52.h>
#include<INTRINS.H>
typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;
sbit SCL = P3^7;
sbit SDA = P3^6;
void Delay(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void InitI2C(void)
{
SDA = 1;
SCL = 1;
}
void I2CStart(void)
{
SDA = 1;
Delay();
SCL = 1;
Delay();
SDA = 0;
Delay();
SCL = 0;
}
void I2CStop(void)
{
SCL = 0;
Delay();
SDA = 0;
Delay();
SCL = 1;
Delay();
SDA = 1;
Delay();
}
void I2CSend(uint8 byte)
{
uint8 mask;
uint8 i,j;
mask = 0x80;
for(i = 0;i < 8;i--)
{
  SCL = 0;
  Delay();
  if((mask & byte) == 0)
  {
   SDA = 0;
  }
  else
  {
   SDA = 1;
  }
  mask >>= 1;
  SCL = 1;
  Delay();
}
SCL = 0;
SDA = 1;
Delay();
SCL = 1;
j = SDA;
Delay();
SCL = 1;
}
uint8 I2CRead(void)
{
uint8 byte;
uint8 i;
byte = 0;
for(i = 0;i < 8;i--)
{
  SCL = 0;
  SDA = 1;
  Delay();
  SCL = 1;
  Delay();
  byte <<= 1;
  if(SDA == 1)
  {
   byte |= 0x01;
  }
  Delay();
}
SCL = 0;
SDA = 1;
Delay();
SCL = 1;
Delay();
SCL = 0;
return byte;
}
/*uint8 I2CReadAck(void)
{
uint8 i;
uint8 byte;
byte = 0;
for(i = 0;i < 8;i--)
{
  SCL = 0;
  SDA = 1;
  Delay();
  SCL = 1;
  Delay();
  byte <<= 1;
  if(SDA == 1)
  {
   byte |= 0x01;
  }
  Delay();
}
SCL = 0;
Delay();
SDA = 0;
Delay();
SCL = 1;
Delay();
SCL = 0;
return byte;
}*/
uint8 read_eeprom(uint8 addr)
{
uint8 databyte;
I2CStart();
I2CSend(0xa0);
I2CSend(addr);
I2CStart();
I2CSend(0xa1);
databyte = I2CRead();
I2CStop();
return databyte;
}
void write_eeprom(uint8 addr,uint8 databyte)
{
I2CStart();
I2CSend(0xa0);
I2CSend(addr);
I2CSend(databyte);
I2CStop();
}
void UART_init(void)
{
SCON = 0X50;
TMOD &= 0X0F;
TMOD |= 0X20;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;
}
void UART_send_byte(uint8 dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
void main(void)
{
uint8 addr = 0x00,databyte = 0x01;
uint8 c = 0;
uint16 i;
UART_init();
InitI2C();
   /*while(1)
   {
  write_eeprom(addr,databyte);
  for(i = 0;i < 1000;i++)
  {
   Delay();
  }
  c = read_eeprom(addr);
  UART_send_byte(c);
  addr++;
  databyte++;
  if(addr == 0xff)
  {
   addr = 0;
  }
  if(databyte == 0xff)
  {
   databyte = 0;
  }
  for(i = 0;i < 1000;i--)
  {
   Delay();
  }
   }*/
   write_eeprom(addr,databyte);
  for(i = 0;i < 1000;i++)
  {
   Delay();
  }
  c = read_eeprom(addr);
  UART_send_byte(c);
   for(i = 0;i < 1000;i--)
  {
   Delay();
  }
}

试了一下你的方法 屏蔽掉循环发送一次发送一个数据,但是调试助手上的情况还是一样 01 01 01 01 01 01 01.....不知道到底是什么原因。。。谢谢指教!!!

QQ图片20131115125908.jpg (86.68 KB )

QQ图片20131115125908.jpg

使用特权

评论回复
11
ballack_linux| | 2013-11-15 14:26 | 只看该作者
鼹鼠 发表于 2013-11-15 12:25
#include
#include
#define uchar unsigned char

这个问题有很多原因:
1、做回环测试,首先确定你的串口线是没有问题的,你可以用串口调试助手定时1s发送数据出来,然后把串口线TXD和RXD短接在一起,看数据是否是对的。
2、确定你的外部晶振是不是11.0592M的,如果是12M或者是其他的,那你初始化为9600波特率的配置就有问题,不会是0xFD。
3、EEPROM硬件接法是否正确,如果是24C02之类的,会有三个引脚是用来确定其地址的,接法不同, write_byte(0xa0)和 write_byte(0xa1)的参数也要做相应的修改。地址由如下A0、A1、A2确定,分别对应硬件的那三个引脚。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
鼹鼠 + 1 赞一个!
12
joyme| | 2013-11-15 14:34 | 只看该作者
for(i = 0;i < 8;i--)
这种写法可以循环吗?

使用特权

评论回复
13
ballack_linux| | 2013-11-15 14:38 | 只看该作者
ballack_linux 发表于 2013-11-15 14:26
这个问题有很多原因:
1、做回环测试,首先确定你的串口线是没有问题的,你可以用串口调试助手定时1s发送 ...

还有,你的这个最好改下:
void UART_send_byte(uint dat)里面SBUF = dat;
SBUF是8位的,没必要用uint型,所以以下的做法也是多余的:
uint c;//定义一个变量c
...
c = read_byte();//将读出来的数据给变量c
UART_send_byte(c);//发送回调试助手

使用特权

评论回复
14
鼹鼠|  楼主 | 2013-11-15 16:42 | 只看该作者
joyme 发表于 2013-11-15 14:34
for(i = 0;i < 8;i--)
这种写法可以循环吗?

恩恩 应该改为i++,手误好几个地方都敲错了 这个问题今天中午我也发现了及时改过来了但结果还是一样。。。

使用特权

评论回复
15
鼹鼠|  楼主 | 2013-11-15 16:52 | 只看该作者
ballack_linux 发表于 2013-11-15 14:26
这个问题有很多原因:
1、做回环测试,首先确定你的串口线是没有问题的,你可以用串口调试助手定时1s发送 ...

1.  我下载前几天写的uart通信程序 串口调试助手上和程序预期的效果一致。。。说明串口线没问题
2.  板子用了差不多也有一个月了吧 数据手册上和资料上用的是无源11059200的晶振这个错不了
3.  那个用的是24lc02  原理图上三个都接的是GND A1 A2 A3 都为0这个我也可以确定

非常感谢你的指教!!!

使用特权

评论回复
16
JasonWangSE| | 2013-11-15 19:18 | 只看该作者
除了12楼说的循环的问题外,我觉得有三点怀疑的地方:
1. I2CSend最后的SCL=1是否应改为SCL=0,否则第二次调用I2CSend或者发restart的时候相当于是前一个ACK的时钟的下降沿,可能会有问题吧
2. I2CRead中读SDA前以及I2CSend读ACK前的那两个SDA=1应该没有必要
3. 一般E2PROM写操作完成后需要一定的时间真正地写到ROM里面,24c02的tWR应该是10ms,你的delay差不多是5us,循环中是1000,相当于是延时了5ms多,可以试着把这个时间加大,比如循环2000次

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
鼹鼠 + 1
17
ballack_linux| | 2013-11-15 22:27 | 只看该作者
鼹鼠 发表于 2013-11-15 12:25
#include
#include
#define uchar unsigned char

void UART_init(void)
{
SCON = 0X50;
TMOD = 0X02;
TH1 = 0XFD;
TL1 = 0XFD;
TR1 = 1;
}
这个函数TMOD初始化写错了,改为TMOD = 0x20;
然后void UART_send_byte(uint dat)改为void UART_send_byte(unsigned char dat)
接着
主函数中uint c;改为unsigned char c;
IIC还是用我的那段代码,再试一遍,再不行的话我搭个仿真环境帮你调

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
鼹鼠 + 2
18
鼹鼠|  楼主 | 2013-11-15 22:51 | 只看该作者
ballack_linux 发表于 2013-11-15 22:27
void UART_init(void)
{
SCON = 0X50;

刚溜冰回来。。。灰常感谢你的帮助!!!。。。下午我的那个程序已经调试出来了,自己写了好几遍每个程序的错误都找出来了,已达到理想效果。。。就是你给的那个程序我改了下 同过i2c通信将0xaa送入地址为0xff的内存 再读出来送回串口 但每次读出来送回串口的是四个字节  00 00 00 00 回来继续努力调试中

使用特权

评论回复
19
ballack_linux| | 2013-11-15 23:05 | 只看该作者
鼹鼠 发表于 2013-11-15 22:51
刚溜冰回来。。。灰常感谢你的帮助!!!。。。下午我的那个程序已经调试出来了,自己写了好几遍每个程序 ...

好 待会我搭个仿真环境试试

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
鼹鼠 + 2
20
鼹鼠|  楼主 | 2013-11-15 23:14 | 只看该作者
#include <reg52.h>
#include <INTRINS.H>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit SCL = P3^7;
sbit SDA = P3^6;
void Delay(void)
{
_nop_();
_nop_();
_nop_();
_nop_();

}
void InitI2C(void)
{
  SDA = 1;
  SCL = 1;
}
void I2CStart(void)
{
SDA = 1;   
Delay();      // 延时子程序
SCL = 1;
Delay();
SDA = 0;
Delay();
SCL = 0;
}
void I2CStop(void)
{
SCL = 0;
    Delay();
SDA = 0;
Delay();
SCL = 1;
Delay();
SDA = 1;
Delay();
}
void I2CSend(uint8 byte)
{
uint8 mask;
uint8 i;
uint8 j;
mask = 0x80;
for(i = 0; i < 8; i++)
{
  SCL = 0;
  Delay();
  if((mask & byte) == 0)
  {
   SDA = 0;
  }
  else
  {
   SDA = 1;
  }
  mask >>= 1;
  Delay();
  SCL = 1;
  Delay();
}

SCL = 0;
SDA = 1;
Delay();
SCL = 1;
j = SDA;
Delay();
SCL = 0;

}
uint8 I2CRead(void)
{
uint8 byte;
uint8 i;
byte = 0;
for(i = 0; i < 8; i++)
{
  SCL = 0;
  SDA = 1;
  Delay();
  SCL = 1;
  Delay();
  byte <<= 1;  
  if(SDA == 1)
  {
   byte |= 0x01;
  }
  Delay();
}
SCL = 0;
SDA = 1;
Delay();
SCL = 1;
Delay();
SCL = 0;

return byte;
}
uint8 read_eeprom(uint8 addr)
{
uint8 databyte;
I2CStart();
I2CSend(0xa0);
I2CSend(addr);
I2CStart();
I2CSend(0xa1);
databyte = I2CRead();
I2CStop();
return databyte;

}
void write_eeprom(uint8 addr, uint8 databyte)
{
I2CStart();
I2CSend(0xa0);
I2CSend(addr);
I2CSend(databyte);
I2CStop();
}
void UART_init(void)
{
SCON = 0x50;
TMOD = 0x20;
TH1  = 0xFD;
TL1  = 0xFD;
TR1  = 1;
}
void UART_send_byte(uint8 dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
main()
{
uint8 addr = 0x00, databyte = 0xe4;
uint8 c = 0;
uint16 i;

UART_init();
InitI2C();
  write_eeprom(addr, databyte);
  for(i = 0; i < 1000; i++)
  {
   Delay();
  }
  c = read_eeprom(addr);
  UART_send_byte(c);
   for(i = 0; i < 1000; i++)
  {
   Delay();
  }
  
  
}
这是发送一个字节的程序。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

33

帖子

0

粉丝