打印

IIC程序读问题

[复制链接]
1345|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cumtgirl|  楼主 | 2008-3-15 11:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "msp430x14x.h"
#include "define.h"

//使用方式:以涵数方式调用,使用时程序关闭总中断,使用完后打开总中断.
//占用资源为:使用两个IO口,本程序CPU主时钟MCLK=800K.
//SDA 数据线定义
#define SDAOUT P1DIR |= BIT4
#define SDAIN  P1DIR &= ~BIT4
#define SDA1   P1OUT |= BIT4
#define SDA0   P1OUT &= ~BIT4
//SCL 时钟线定义
#define SCLOUT P6DIR |= BIT3
#define SCL1   P6OUT |= BIT3
#define SCL0   P6OUT &= ~BIT3

#define SDA_STATE P1IN & BIT4   //读入SDA状态

//从器件接收方的应答返回标志
#define OK 0x01                 //表示从器件有应答
#define NO 0x00                 //表示从器件无应答  

//IIC总线操作成失标志
#define error 0x01              //错误
#define right 0x00              //正确

//IIC总线操作成失标志
 #define error 0x01              //错误
 #define right 0x00              //正确

 #define AT24_ADD      0xA0      //24c02芯片地址          

 #define write          0x00     //写
 #define read           0x01     //读

 #define Quantity      3      //操作数量
 #define incept_add      0x10   //操作内部地址首址
 
//写入AT24C02数据表
//  unsigned char write_table[3]={'a','e','d'};
//读出AT24C02数据缓冲区
 //unsigned char read_Buff[3]={'x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'}; 
unsigned char read_Buff[3]={'x','x','x'};
//******************************************************
//MSP430F14初始化
void init (void)
{
   
}
//******************************************************
//小延时
nop_()
{_NOP();_NOP();}

SomeNOP()
 {nop_();nop_();nop_();nop_();nop_();}
//******************************************************
//软延时
void delay(unsigned int n)
{unsigned int k;
 for(k=0;k<n;k++);
}
//**************************************
void XCLR_LOW(void)
{
 P1SEL &= ~BIT6;                  //P1.6普通IO
 P1DIR |=  BIT6;                   //P1.6输出0
 P1OUT &= ~BIT6;     
}
void XCLR_HIGH(void)
{
 P1SEL &= ~BIT6;               //P6.1普通IO
 P1DIR |=  BIT6;                //P6.1输出1
 P1OUT |=  BIT6;       
}
//******************************************************
void main(void)
{
  WDTCTL=WDTPW+WDTHOLD;         //停止WDT
   //P6SEL &= ~BIT3;                  //P1.6普通IO
   //P6DIR |=  BIT3;                   //P1.6输出0
   //P6OUT |=  BIT3;  
   //P6OUT &=  ~BIT3;
   //P6OUT |=  BIT3; 
     
  XCLR_LOW();
  init();                       //初始化
 // IIC(write_table,Quantity,incept_add,(AT24_ADD|write));
 delay(500);                 //写入后,做一个适当的延时
 IIC(read_Buff,Quantity,incept_add,(AT24_ADD|read));  
 LPM1;
}
//**************************************
//起始信号
void I2CStart(void)
 {
 _DINT();               //关总中断;
 SCLOUT;                //SCL口设为输出-------后加
 SDAOUT;                //SDA口设为输出 
 SDA1;                   
 //SCLOUT;                //SCL口设为输出 
 SCL1;
 SomeNOP(); SomeNOP();            //INI
 SDA0;                   
 SomeNOP(); SomeNOP();           //START
 SCL0;         
 }
//**************************************
//结束信号
void I2CStop(void)
 {
  SCL0;   
  SDA0;                   
  SomeNOP();              //INI
  SCL1;                                  
  SomeNOP(); 
  SDA1;                  //STOP
  _EINT();               //EA=1;
 }

//**************************************
//等待从器件接收方的应答
unsigned char WaitAck(void)
 {
 unsigned char errtime=255;      //因故障接收方无ACK,超时值为255。
 SDA1;                  
 SomeNOP();
 SCL1;
 SomeNOP();
 SDAIN;                 //SDA口设为输入
 while(SDA_STATE)       //SDA出现为0时,则为有应答
  { errtime--; 
   if (!errtime)        //errtime是否为0
    {I2CStop();        
     return NO;}        //返回为0(失败)
  }
 SDAOUT;                //SDA口设为输出 
 SCL0; 
 return OK;             //返回为1(成功)
 }
//**************************************
//主器件为接收方,从器件为发送方时,单片机发出应答信号
//MCU Send to IC
void SendAck(void)
 {
 SDA0;                 
 SomeNOP();
 SCL1;                 
 SomeNOP();
 SCL0;         
 }
//**************************************
//主器件为接收方,从器件为发送方时,非应答信号
void SendNotAck(void)
 {
 SDA1;  
 SomeNOP();
 SCL1;                   
 SomeNOP();
 SCL0; 
 }
//**************************************
//发送字节
 void I2CSendByte(unsigned char ch)
 {
  unsigned char i=8;
  while (i--)
  {
   SCL0;                //SCL=0;
   nop_();
   if(ch&0x80)
    SDA1;               //使SDA为1位
   else
    SDA0;               //使SDA为0位
    ch<<=1; 
   SomeNOP();
   SCL1;           
   SomeNOP();
   }
  SCL0;         
 }
//**************************************
//接收字节
unsigned char I2CReceiveByte(void)
 {
 unsigned char i=8;        //接收8位
 unsigned char ddata;
 SDA1;                  
 SDAIN;                    //SDA口设为输入
 while (i--)
 {
  ddata<<=1;              //将ddata位向高位移,让位0
  SCL0;
  SomeNOP();
  SCL1;
  SomeNOP();
  
  if(SDA_STATE)                //读入SDA,后加
  ddata|=1;                    
 }
 SCL0;                         //SCL=0;
 SDAOUT;                       //(附加)SDA口设回为输出
 return  ddata;
 }
//**********************************************************************
//正常操作时返回位值为0,有故障时返回位值为1.
//unsigned char *DataBuff数据缓冲区指针,char ByteQuantity字节数量,
//unsigned int Address IC片内地址,
//unsigned char ControlByte芯片控制字节-IC地址/读写位,
unsigned char IIC(unsigned char *DataBuff,char ByteQuantity,unsigned int Address,
         unsigned char ControlByte)
{
 unsigned char errorflag=error;      //错误标志位,1为错误,0为正确
 unsigned char i;                    //i为允许本次操作的最大次数
  i=1;
 SCLOUT;                               //时钟口长设为输出
 while(i--)
 { 
   I2CStart();
   I2CSendByte(ControlByte&0xfe);//指定芯片,此次必定为写
   if(!WaitAck())              //涵数返回一个1为成功
     continue;                      //结束写操作,并i-1后,再来一次
   I2CSendByte((unsigned char)Address);      //发送片内地址
   if(!WaitAck())            //数返回一个1为成功                            
     continue;                    //结束写操作,并i-1后,再来一次      
   
  //------------------------------已经选定好IC
   if(!(ControlByte&0x01))      //本次操作是读还是写
      {                         //写操作
     errorflag=right;      //清错误标志位为0
     while(ByteQuantity--)   //操作j个数字节
          {
            I2CSendByte(*DataBuff++);//发送        
         if(WaitAck())           //涵数返回一个1为成功,涵数返回一个0为失败
              continue;                  //成功,下一个数据循环(跳while)
         errorflag=error;          //不应答,失败了. errorflag=1
         break;                  //退出写操作
       }
     if(errorflag==error) //经过写完后,如果最后errorflag标志为1,则表示有错误
           continue;                  //结束写操作,并i-1后,再来一次
     break;                          //写操作完成
      }  
   else                        //则为读操作
     {  I2CStart();                  //开始       
        I2CSendByte(ControlByte);
        if(!WaitAck())                      //涵数返回一个1为成功
        {continue;}                      //结束此操作,并i-1后,再来一次
     while(--ByteQuantity)           //读入ByteQuantity个数字节
           {*DataBuff++=I2CReceiveByte();//连续读入ByteQuantity个数据
              SendAck();}              //主机向从机发出应答,表示主机已接收            
        *DataBuff=I2CReceiveByte();     //读入最后个数据
     SendNotAck();                   //最后发出不应答信号(位),表示主机不再读了.
     errorflag=right;                //向错误标志位写0(right),表示读数据正确.
     break;}                         //读操作完成*/
     }
 I2CStop();                             //停止,结束IIC总线
 return(errorflag);                     //返回操作成败标志
}

相关帖子

沙发
cumtgirl|  楼主 | 2008-3-15 11:38 | 只看该作者

re

在430F149的微控开发板上运行好好的,可以读出,也可以写入数据。为什么换到我的Msp430F133的板上运行,就读不出数据呢

使用特权

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

本版积分规则

140

主题

293

帖子

0

粉丝