5560|17

39

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

求大神帮忙呀,IIC快疯了 [复制链接]

我用MSP430G2553的任意两个端口作为SCL,SDA进行IIC对24C02EEPOM的写入与写出。可是调试了好几天了,都没成功。大神快来看看吧!!!!
我把文件上传了,是TXT格式的,在IAR中打开调试。。。
/*用P.2--> SCL  P1.3-->SDA
在其上面输入输出高低电位**************/
#include
#include
#define SCL_H P1OUT|=BIT2
#define SCL_L P1OUT&=~BIT2
#define SDA_H P1OUT|=BIT3
#define SDA_L P1OUT&=~BIT3
#define uchar unsigned char
#define uint unsigned int
/*******************************************
函数名称:delay
功    能:延时约15us的时间
参    数:无
返回值  :无
********************************************/
void delay(void)
{
   uchar i;
   for(i=0;i<30;i++)//大约5uS延时
    ;
}
/*******************************************
函数名称:start
功    能:完成IIC的起始条件操作
参    数:无
返回值  :无
********************************************/
void start(void)
{
SCL_H; //起始状态是SCL和SDL上面的信号都为高
        SDA_H;
delay();
SDA_L;//起始状态关键信号
delay();
SCL_L;
delay();
}
/*******************************************
函数名称:stop
功    能:完成IIC的结束条件操作
参    数:无
返回值  :无
********************************************/
void stop(void)
{
       SCL_L;
       SDA_L;
       delay();
       SCL_H;
       delay();
       SDA_H;//结束状态关键信号
       delay();
}
/*******************************************
函数名称:ack_0
功    能:完成IIC的(写数据)成功判断条件操作,从24C02芯片发送一个0,
让主机即MSP430单片机进行判断
参    数:无
返回值  :无
********************************************/
void ack_0(void)
{     
      uint i=0;
      SCL_L;
      delay();
      P1DIR&=~BIT3;//改变P1.3的端口状态,设置P1.3为输入端口
      SCL_H;//时钟线为高电平,用于检测SDA的数值
      delay();
      while((P1IN&BIT3)&&(i<300))
      i++;   
      return ;
}
/*******************************************
函数名称:Nack_1()
功    能:完成IIC的(读数据)成功判断条件操作,主机即MSP430单片机发送一个1,
让芯片24C02自己进行判断
参    数:无
返回值  :无
********************************************/
void Nack_1()
{
     SCL_L;
     SDA_L;
     delay();
     SDA_H;//给SDA线上发送一个高电平,让EEPOM自己去判断
     delay();
     SCL_H;
     return;
}
/*******************************************
函数名称:write1byte()
功    能:向IIC总线发送一个字节的数据
参    数:wdata--发送的数据
返回值  :无
********************************************/
void write1byte(uchar date)
{      
        uchar i;
        SCL_L;
     for(i=8;i>0;i--)
{      
                SCL_L;
  if(date&0x80)
                {
                  SDA_H;
                }
  else
                {
                  SDA_L;
                }
                delay();
                SCL_H;
                delay();
                date<<=1;//将数据左移一位
         }
         
return;
  
}
/*******************************************
函数名称:read1byte
功    能:从IIC总线读取一个字节
参    数:无
返回值  :读取的数据
********************************************/
uchar read1byte(void)
{
uchar  read_data=0x00,i;
        uchar flag;
   
for(i=0;i<8;i++)
{
  SDA_H;
  delay();
                P1DIR&=~BIT3;
                delay();
                SCL_H;
  delay();
  flag=(P1IN&BIT3);//P1.3输入的值
  read_data<<=1;
  if(flag)
                read_data|=0x01;
                SCL_L;
  delay();
}
            P1DIR|=BIT3;
    return read_data;
}
/*******************************************
函数名称:24C02write_byte()
功    能:通过IIC总线给24C02中写入数据
参    数:24C02要写的地址,要写入的数据
          //24C02芯片共有255个字节,从0x00~0xff
返回值  :无
********************************************/
void _24C02write_byte(uchar adrr1,uchar number)
{
      uchar adrress1=0xa0;//这个要看相应的要传芯片的地址和写入模式
            start();
            
            
            write1byte(adrress1);//发送从接收器的地址
            ack_0();
            
            write1byte(adrr1);//发送从接收器的某个地址开始写入
            ack_0();
            
            write1byte(number);//发送具体的数据
            for(uint m=0;m<10000;m++)
            {;}
            ack_0();           
            stop();
}
/*******************************************
函数名称:24C02read_byte()
功    能:通过IIC总线将24C02中相应地址的数据读入单片机MSP430中
参    数:24C02要读出的地址//24C02芯片共有255个字节,从0x00~0xff
返回值  :有
*******************************************/
uchar _24C02read_byte(uchar adrr2)
{   
    uchar   temp;
    uchar   adrress2=0xa0;//这个要看相应的要传芯片的地址和写入模式
            start();
            
            write1byte(adrress2);//控制字节,从接收器的地址
            ack_0();
   
            write1byte(adrr2);//发送地址字节
            ack_0();
            
            adrress2=0xa1;
            start();
            
            write1byte(adrress2);//控制字节,从接收器的模式
            ack_0();
            
            temp=read1byte();
            for(uint q=0;q<10000;q++)
            Nack_1();
            
            stop();
            return temp;
            
}
/*******************************************
                  主函数
*******************************************/
void main(void)
{
    uchar adrr1=0x00;
    uchar number=0x0f;
    P2SEL=0x00;
    P2DIR=0XFF;
    P2OUT=0X1F;
    _24C02write_byte(adrr1,number);
  
    for(uint i=0;i<50000;i++)
    {;}
    P2OUT=_24C02read_byte(adrr1);
}

最新回复

感谢楼主!我这边刚刚用51改过来的代码运行成功了,好开心!原来学单片机那么有趣的!谢谢谢谢!哈哈哈哈哈  详情 回复 发表于 2013-11-24 19:15
 
点赞 关注(1)

回复
举报

39

帖子

0

TA的资源

一粒金砂(中级)

推荐
 

回复 沙发lcofjp 的帖子

我吧24C02时序看了,低电平的时候,SDA上面才允许有电平跳变,接受器件发送低电平,然后SCL会发一个高电平,稳定之后,P1.3口就会把数据读掉,进行判断。听了你的建议我把ack_0()程序后面加了句P1DIR|=BIT3。但是结果还是不尽人意呀。

点评

也就是说你现在的write1byte函数有问题,函数结束后,SDA可能高也可能低。然后再配合以后的时序的(配合你的ack_0,你自己想一下吧,会是什么结果),不可能正常工作。  详情 回复 发表于 2013-10-31 23:14
因为我说过了,你的错误可能不止一处,本身思路就有问题,I2C是OC上拉总线,除了输出数据的时候作为输出,其余时间一定要输入,保持上拉为高(如果你程序控制的好,可以只在输入的时候设置为输入上拉,但是目前你的  详情 回复 发表于 2013-10-31 23:09
 
 

回复

6040

帖子

205

TA的资源

版主

沙发
 
哦,不成功是正常的,要模拟时序的话,就要仔细的去研究时序,在什么时候高,什么时候低,什么时候输入,什么时候输出,什么时候延时等等都很重要。
先说说你的ack_0. 等待从设备回ACK的时候是SCL等于低的时候,你都拉高了,才去读,显然有问题,而且你读完ack状态,退出函数的时候,SDA还是输入吧,然后你“ write1byte(adrr2);//发送地址字节”都没把SDA设置成输出,这能写出去吗。当然问题可能不仅仅有这些,你把协议好好捋一遍吧。
坛子里有模拟I2C的例程,你可以参考一下,我就发过一个449读时钟还是传感器的来着,当然,你自己能写出来最好,这样收获最大。

点评

我吧24C02时序看了,低电平的时候,SDA上面才允许有电平跳变,接受器件发送低电平,然后SCL会发一个高电平,稳定之后,P1.3口就会把数据读掉,进行判断。听了你的建议我把ack_0()程序后面加了句P1DIR|=BIT3。但是结  详情 回复 发表于 2013-10-31 19:57
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
说下你做的实验是什么?还有你先做程序的运行结果是什么样子呢?
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

4
 
楼上说的对
 
 
 

回复

6040

帖子

205

TA的资源

版主

6
 

回复 5楼SF很厉害 的帖子

因为我说过了,你的错误可能不止一处,本身思路就有问题,I2C是OC上拉总线,除了输出数据的时候作为输出,其余时间一定要输入,保持上拉为高(如果你程序控制的好,可以只在输入的时候设置为输入上拉,但是目前你的程序做不到)。我觉得你还是参考一下别人可用的历程吧。
 
 
 

回复

6040

帖子

205

TA的资源

版主

7
 

回复 5楼SF很厉害 的帖子

也就是说你现在的write1byte函数有问题,函数结束后,SDA可能高也可能低。然后再配合以后的时序的(配合你的ack_0,你自己想一下吧,会是什么结果),不可能正常工作。
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(高级)

8
 

你参考一下我写的,调试通过

没仔细看你写的,参考一下我这个。前几天刚调试的,调试可以。 你对照看一下,分析你那为何不可以。
/*********************************************
实验:IO口模拟IIC,EEPROM之AT24C02,往24C02
      地址5、6处写入不同数据,读出写入数据,
      以LED显示读回数据。
      其他说明见头文件24C02new.h或24C02.h
编写:风的世界
时间:2013-10-30   
*********************************************/
#include
#define uchar unsigned char
#define uint unsigned int
#include"24C02new.h"

void delayms(uint x)
{
    uint a,b;
    for(a=x;a>0;a--)
      for(b=110;b>0;b--);
}
void main()
{
  WDTCTL = WDTPW + WDTHOLD;//关看门狗定时器
  uchar num1,num2;
  P1SEL = 0x00;
  P1DIR = 0xff;
  P2SEL &= ~(BIT0+BIT1);//P2.0  P2.1设置为普通IO口
  Byte_Write(5,0x55);
  delayms(10);
  Byte_Write(6,0xAA);
  delayms(10);
  num1=Random_Read(5);
  num2=Random_Read(6);
  while(1)
  {
    P1OUT = num1;
    delayms(800);
    P1OUT = num2;
    delayms(800);
  }  
}
/************IIC24C02初始化***************
========头文件:24C02.h================
说明:写操作、读操作仅仅是适用于24C02
      其他IIC芯片需另行编写。
      适用于430单片机
分析:以P2.0控制SDA,P2.1控制SCL方式编写
      欲改用其他IO控制,程序要修改处较多。
      采用宏定义端口方式灵活性较好。
连线:P2.0~SDA
      P2.1~SCL
编写:风的世界
时间:2013-10-30
************************************/

void delay()
{
  ;;
}
/*=============总线初始化==============*/
void init()
{
    P2DIR |= BIT0+BIT1;//P2.0  P2.1端口方向设置为输出
    P2OUT |= BIT1; //SCL=1,时钟线置高
    delay();
    P2OUT |= BIT0;//SDA=1,数据线置高
    delay();
}
/*==============启动信号===========*/
void start()  
{
    P2OUT |= BIT1;  //SCL=1
    P2OUT |= BIT0;  //SDA=1
    delay();//延时时间要大于4.7us
    P2OUT &= ~BIT0;  //SDA=0
    delay();//延时时间应大于4us
    P2OUT &= ~BIT1;  //SCL=0
}
/*============终止信号==========*/
void stop()  
{
    P2OUT |= BIT1;  //SCL=1
    P2OUT &= ~BIT0; //SDA=0
    delay();//延时时间应大于4us
    P2OUT |= BIT0;  //SDA=1
    delay();//延时时间应大于4.7us
}
/*============应答信号=============*/
void Ask()
{
    P2OUT &= ~BIT0; //SDA=0
    delay();
    P2OUT |= BIT1; //SCL=1
    delay();//延时时间应大于4us
    P2OUT &= ~BIT1; //SCL=0
    delay();
}
/*=============非应答信号============*/
void NoAsk()
{
    P2OUT |= BIT0; //SDA=1
    delay();
    P2OUT |= BIT1; //SCL=1
    delay();//应大于4us
    P2OUT &= ~BIT1; //SCL=0
    delay();
}
/*==========写一个字节=================*/
void write_byte(uchar Data)
{
    uchar i;//i用以计算发送的位数
    for(i=0;i<8;i++)
    {
      P2OUT &= ~BIT1; //SCL=0,SCL为低时,允许数据变化
      delay();
      if((Data<         P2OUT |= BIT0;//送1位数据
      else
        P2OUT &= ~BIT0;
      delay();
      P2OUT |= BIT1; //SCL=1,SCL为1时,要求数据稳定,将数据写入内存
      delay();
    }
    P2OUT &= ~BIT1; //SCL=0
    delay();
    P2OUT |= BIT0; //SDA=1,释放数据线
    delay();
}
/*=========读取一个字节=========
在每次SCL由0变1时,读取一位,
读8位,一字节
==============================*/
uchar read_byte()
{
    uchar i,temp;
    P2OUT &= ~BIT1; //SCL=0
    delay();
    P2OUT |= BIT0; //SDA=1
    delay();
    P2DIR &= ~BIT0;//SDA端口方向改为输入,因为此后要读入数据
    for(i=0;i<8;i++)
    {
       P2OUT |= BIT1; //SCL=1
       delay();
       temp<<=1;
       if(P2IN&BIT0)
          temp|=0x01;//获取P2.0口读回的数
       P2OUT &= ~BIT1; //SCL=0
       delay();
    }
    delay();
    P2DIR |= BIT0; //读完1Byte数据,SDA口方向设置为输出
    return temp;
}

/********写操作*********/
void Byte_Write(uchar address,uchar Data)
{
    P2DIR |= BIT0+BIT1;//P2.0  P2.1端口方向设置为输出
    start();//启动IIC
    write_byte(0xa0);//写器件地址,实验板上器件高4位为1010,低3位接了地,最地位为R/W,现在是写,最低位也为0
    Ask();
    write_byte(address);//写数据地址,即欲将该数据存放于何处,address在0~255取值
    Ask();
    write_byte(Data);
    Ask();
    stop();
}

/********读操作***********************
说明:随机读取,程序分析参见操作时序
*************************************/
uchar Random_Read(uchar address)
{
    P2DIR |= BIT0+BIT1;//P2.0  P2.1端口方向设置为输出
    uchar Data;
    start();
    write_byte(0xa0);//写器件地址,写,最低位为0
    Ask();
    write_byte(address);//广播数据存放的地方
    Ask(); //得到应答后开始读数据
    start();
    write_byte(0xa1);//器件地址最低位为read,为1,表明此时24C02将发送数据,MCU接收数据
    Ask();
    Data=read_byte();//读取数据赋给Data
    NoAsk();
    stop();
    return Data;
}

点评

已经搞好了,并且把我原来的代码修改好了。差之毫厘,失之千里。  详情 回复 发表于 2013-11-20 17:23
这两个礼拜有事,没上来看,还没试,但是无论无何,先要真诚的谢谢你。。。。现在就去调:carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnatio  详情 回复 发表于 2013-11-19 16:49
头文件名称改一下,对应就行。24C02new.h是另外的,没传。看这个就够了:)  详情 回复 发表于 2013-11-3 23:27
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(高级)

9
 

回复 8楼风的世界 的帖子

头文件名称改一下,对应就行。24C02new.h是另外的,没传。看这个就够了
 
 
 

回复

139

帖子

0

TA的资源

一粒金砂(高级)

10
 
IIC尽量用片子自带的资源,不要用模拟的IIC。我给你发一个MSP430FG4619的IIC程序,同时也给你一个MSP430FG4619上调通的模拟IIC程序。明天晚上发。

点评

亲,,,我在等你的程序呢。:congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate: :congratulate:  详情 回复 发表于 2013-11-19 16:57
 
 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

11
 

回复 8楼风的世界 的帖子

这两个礼拜有事,没上来看,还没试,但是无论无何,先要真诚的谢谢你。。。。现在就去调:carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :rose: :rose: :rose: :rose: :rose: :rose: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :carnation: :rose: :rose: :rose:
 
 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

12
 

回复 10楼小右派 的帖子

亲,,,我在等你的程序呢。
 
 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

13
 

回复 8楼风的世界 的帖子

已经搞好了,并且把我原来的代码修改好了。差之毫厘,失之千里。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

14
 

我也在做,不过是pcf8591的芯片

我也在做IIC,但是已经研究了三个星期了仍然没什么进展。能不能请楼主大大放下你的程序?我实在是无力了。因为我刚接触单片机也就一个月,所以实在是举步维艰。

PCF8591中文数据手册.pdf

282.67 KB, 下载次数: 2

点评

就是上楼那个大神给写的代码,只要把24CO2.H注释掉就可以了;不管哪个芯片,按照时序图来写,都能写成功的  详情 回复 发表于 2013-11-24 15:17
 
 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

15
 

回复 14楼JASON0916 的帖子

就是上楼那个大神给写的代码,只要把24CO2.H注释掉就可以了;不管哪个芯片,按照时序图来写,都能写成功的

点评

感谢楼主!我这边刚刚用51改过来的代码运行成功了,好开心!原来学单片机那么有趣的!谢谢谢谢!哈哈哈哈哈  详情 回复 发表于 2013-11-24 19:15
 
 
 

回复

5979

帖子

8

TA的资源

版主

16
 

点评

版主帮个忙吧,说说G2553的UART,搞了好久没弄出来。。。  详情 回复 发表于 2013-11-24 15:25
 
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 

回复

39

帖子

0

TA的资源

一粒金砂(中级)

17
 

回复 16楼chenzhufly 的帖子

版主帮个忙吧,说说G2553的UART,搞了好久没弄出来。。。
 
 
 

回复

11

帖子

0

TA的资源

一粒金砂(中级)

18
 

回复 15楼SF很厉害 的帖子

感谢楼主!我这边刚刚用51改过来的代码运行成功了,好开心!原来学单片机那么有趣的!谢谢谢谢!哈哈哈哈哈
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表