⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 msp430I2C通信读AT24C02
💻 C
字号:


#include<msp430X16X.h>
#include "IIC.h" 
unsigned char I2CBuffer[3];
int PtrTransmit;


/*******************************************

                   延时

*******************************************/


void Delay(int m)
{
   while(m-- > 0);
}

/*******************************************

    对端口的输入输出方向进行设置

*******************************************/
void Init_Port(void)
{ 
  //初始化端口寄存器
  P1DIR =0xFF;
  P2DIR =0xFF;
  P3DIR =0xF5;
  P4DIR =0xFF;
  P5DIR =0xFF;
  P6DIR =0xFF;
  Delay(100);
}

 
/*******************************************

         设置单片机的各个时钟

*******************************************/
void Init_CLK(void)
{
  unsigned int i;
  BCSCTL1 =0x00;            //将寄存器的内容清零,XT2振荡器开启,LFTX1工作在低频模式下
                            //ACLK的分频因子为1
  do
  {
    //清除OSCFault标志
    IFG1 &=~OFIFG;
    for (i=0x20;i>0;i--);
  }
  while ((IFG1 & OFIFG)==OFIFG);       //如果OSCFault=1
  BCSCTL1 &=~(XT2OFF+XTS);             //open XT2,LFTX2选择低频率
  BCSCTL1 |=RSEL0+RSEL1+RSEL2;         //DCO Rsel=7
  BCSCTL1 |=0x07;
  BCSCTL2 +=SELM1;                     //MCLK的时钟源为TX2CLK,分频因子为1
  BCSCTL2 +=SELS;                      //SMCLK的时钟源为TX2CLK,分频因子为1
   Delay(100);
}



/*******************************************

    通过设置相应寄存器实现对I2C模块的设置

*******************************************/
 void InitI2C(void)
{
  P3SEL=0x0A;                          //将P3.1和P3.3设置为I2C管脚
  P3DIR &=~0x0A;                       //设置P3.1和P3.3管脚的方向
  
  U0CTL |=I2C+SYNC;                    //选择为I2C模式
  U0CTL &=~I2CEN;                      //禁止I2C模块
   
  I2CTCTL=I2CTRX+I2CSSEL_2;            //设置I2C为7位地址模式,不使用DMA,字节模式,时钟源为SMCLK,设置成传输模式
  
  I2CSA=0x50;                          //定义从器件地址
  I2COA=0x01a5;                        //设置本身地址
   
  I2CPSC=159;                          //I2C时钟为SMCLK/160
  I2CSCLH=0x03;                        //SCL高电平为:5 *I2C时钟
  I2CSCLL=0x03;                        //SCL低电平为:5 *I2C时钟
   
  U0CTL |=I2CEN;                       //I2C模块有效
  
  Delay(100);
}
  
 
/*******************************************

              写操作初始化

*******************************************/
void I2CWriteInit(void)
{
  U0CTL |=MST;                        //主模式              
  I2CTCTL |=I2CTRX;                   //传输模式:R/W为:0
  I2CIFG &=~TXRDYIFG;                 //清除中断标志
  I2CIE =TXRDYIE;                     //发送中断使能
   Delay(100);
}



/*******************************************

             读操作初始化

*******************************************/
void I2CReadInit(void)
{
  I2CTCTL &=~I2CTRX;                  //接收模式:R/W为:1
  I2CIE =RXRDYIE;                     //接收中断使能
  Delay(100);
}

 

/*******************************************

                  读操作

*******************************************/

unsigned char EEPROM_RandomRead(unsigned char nAddr)
{
  unsigned char adr_hi;
  unsigned char adr_lo;

  while(I2CDCTL&I2CBUSY);          //等待I2C模块完成所有操作
  adr_hi = nAddr>>8;
  adr_lo = nAddr & 0xFF;
  
  I2CBuffer[1] = adr_hi;            //设置地址
  I2CBuffer[0] = adr_lo;
  PtrTransmit = 1;                  //数组指针
  I2CWriteInit();                  //写操作初始化
  I2CNDAT = 2;                     //传输数据长度,一个控制字节和一个地址数据
  I2CIFG &= ~ARDYIFG;              //清除中断标志
  I2CTCTL |= I2CSTT;               //产生起始条件
  while((~I2CIFG)&ARDYIFG);        //等待传输完成
  I2CReadInit();                   //读操作初始化
  I2CNDAT = 1;                     //接收1个字节的数据
  I2CIFG &= ~ARDYIFG;              //清除中断标志
  I2CTCTL |= I2CSTT+I2CSTP;        //开始接收,产生重新起始和停止条件
  while((~I2CIFG)&ARDYIFG);        //等待传输完成
  Delay(100);
  return I2CBuffer[0];             //返回数据
  
  
}

 

/*******************************************

                   写操作

*******************************************/
void EEPRPM_ByteWrite(unsigned char nAddr,unsigned char nVal)
{
  unsigned char adr_hi;
  unsigned char adr_lo;
  
  while(I2CDCTL&I2CBUSY);     //等待I2C模块完成所有操作
  adr_hi = nAddr >> 8;        //高字节地址
  adr_lo = nAddr & 0xFF;       //低字节地址
  I2CBuffer[2] = adr_hi;      //存储要发送的地址  
  I2CBuffer[1] = adr_lo;        
  I2CBuffer[0] = nVal;        //存储要发送的数据
  PtrTransmit = 2;            //数组指针
  I2CWriteInit();             //写数据初始化
  I2CNDAT=3;                  //传输数据长度,一个控制字节和两个数据字节
  I2CTCTL |= I2CSTT+I2CSTP;   //产生开始和停止条件,开始I2C通信
  Delay(100);
}

 
/*******************************************

             读取当前地址内容

*******************************************/
unsigned char EEPROM_CurrentAddressRead(void)
{
  while(I2CDCTL&I2CBUSY);         //等待I2C模块完成所有操作
  I2CReadInit();                  //读操作初始化
  U0CTL |=MST;                    //主模式
  I2CNDAT = 1;                    //接收一个字节的数据
  I2CIFG &= ~ARDYIFG;             //清除中断标志
  I2CTCTL |= I2CSTT+I2CSTP;       //开始接收,产生重新起始和停止条件
  while((~I2CIFG)&ARDYIFG);       //等待传输完成
  Delay(100);
  return I2CBuffer[0];            //返回数据
  
}

 
/*******************************************

                   中断

*******************************************/
#if __VER__<200
    interrupt [USART0TX_VECTOR] void ISR_I2C(void)
#else      
    #pragma vector=USART0TX_VECTOR
    __interrupt  void ISR_I2C(void)
#endif      
{
  switch(I2CIV)
  {
    case I2CIV_AL:                    //仲裁中断
      {
        break; 
      } 
    case I2CIV_NACK:                  //NACK中断
      {
        break; 
      }
    case I2CIV_OA:                    //自己地址中断
      {
        break;
      }
    case I2CIV_ARDY:                  //访问准备好中断
      {
        break;    
      }
    case I2CIV_RXRDY:                 //接收准备好中断                    
      {
        I2CBuffer[0]=I2CDRB;                                                            
        break;
      }
    case I2CIV_TXRDY:                  //发送准备好中断
      {
        I2CDRB=I2CBuffer[PtrTransmit];
        PtrTransmit=PtrTransmit-1;
        if(PtrTransmit <0)                //禁止发送中断
         {
           I2CIE &=~TXRDYIE;
         }
          break; 
      }
    case I2CIV_GC:                     //一般调用中断
      {
        break;
      }
    case I2CIV_STT:                    //起始条件中断
      {
        break;
      }
  }
}

 
/*******************************************

                    应答

*******************************************/
void EEPROM_AckPolling(void)
{
  unsigned int count;
  while(I2CDCTL&I2CBUSY);               //等待I2C模块完成所有操作
  count=0;
  U0CTL &=~I2CEN;                       //清除I2CEN
  I2CTCTL |=I2CRM;           
  U0CTL |=I2CEN;                        //使能I2C模块
  I2CIFG=NACKIFG;                       //设置NACKIFG标志
  while(NACKIFG & I2CIFG)
  {
    I2CIFG=0x00;                        //清除中断标志
    U0CTL |=MST;                        //主模式
    I2CTCTL |=I2CTRX;                   //设置传输模式
    I2CTCTL |=I2CSTT;                   //产生起始条件
    while((I2CTCTL & I2CSTT)==0);            //等待I2CSTT被清除
    I2CTCTL |=I2CSTP;                   //产生停止条件
    while(I2CDCTL&I2CBUSY);             //等待停止条件复位
    count=count+1;
  }
  U0CTL &=~I2CEN;                       //清除I2CEN位
  I2CTCTL &=~I2CRM;
  U0CTL |=I2CEN;                        //使能I2C
  Delay(100);
  return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -