分享

MSP430单片机硬件IIC

 莽汉一枚 2013-07-24

MSP430单片机硬件IIC


//MSP430IIC接口是很方便的物件,但是还是有很多人弃之不用,当然有各种原因,但是如果你确实要用IIC接口,而且容许的话,用它还是很舒服的,可能开始不太顺,但是一旦搞通了你会体会到他的好处。

    我看了一些网上的程序,有的仍然用模拟方式的思维处理某些环节,比如应答信号。非要追踪”ACK”不可,其实接口已经提供了“NACK”中断,何必非要反向处理呢?事实上,如果在正常传送中出现“NACK”中断,你要考虑更换器件或者考虑系统的稳定性了。

 

#include <msp430x16x.h>

unsigned char RX_BUF[10];

unsigned char TX_BUF[16];

unsigned char Rece_data[16];

 

int RX_COUNTER;

int TX_COUNTER;

 

void Init_IIC(void);

void EEPROM_WriteN(unsigned char mAddr,unsigned char sAddr,unsigned char n);

unsigned char EEPROM_ByteRead(unsigned char mAddr,unsigned char sAddr);

void EEPROM_ReadN(unsigned char mAddr,unsigned char sAddr,unsigned char n);

//=======================================

//USART0中断

//=======================================

#pragma vector = USART0TX_VECTOR

__interrupt void I2C_ISR(void)

{

    switch(I2CIV)

    {

    case 2: I2CTCTL |= I2CSTP; I2CIFG=0; break;//无应答

    case 10: RX_BUF[RX_COUNTER] = I2CDRB;

             RX_COUNTER++;

             break;

             

    case 12: I2CDRB = TX_BUF[TX_COUNTER];

             TX_COUNTER++;

             break;

    default: break;

    }

}

 

//====================================

//系统时钟初始化

//====================================

void INIT_SYSTIMER(void)

{

  unsigned char i;

  BCSCTL1 &= ~XT2OFF;                       //选 XT2

  do

  {

    IFG1 &= ~OFIFG;                         //清除震荡器失效标志

    for (i = 0xFF; i > 0; i--);             //稳定时间

  }

  while ((IFG1 & OFIFG)!=0);                //如果震荡器失效标志存在,等待

  BCSCTL2 = SELM_2 + SELS + DIVS_3;        //MCLK时钟源=XT2SMCLK时钟源=XT2/8

}

//=================================

void delay(unsigned int i)

{

  unsigned int j;

  for(j=0;j<i;j++);

}

 

//=================================================

void Init_IIC(void)

{

    P3SEL |= 0x0a;  

    U0CTL = I2C + SYNC;   

    U0CTL &= ~I2CEN;

    I2CTCTL |= I2CSSEL_2;       //SMCLK

    I2CPSC = 9;                 //I2C时钟 = SMCLK / 10: 100KH;

    I2CSCLH = 0x03;             //SCL 高电平为:5 *I2C 时钟

    I2CSCLL = 0x03;             //SCL 低电平为:5 *I2C 时钟

    I2CSA = 0X50;

    I2CNDAT = 0x02;

    U0CTL |= I2CEN;             //I2C 模块有效

    I2CIE |= TXRDYIE + RXRDYIE; //Enable TX RX interrupt

}

//=================================================

//对于FM24L16的写操作  发送N个数据

//16>n>0

//0x50<=mAddr<=0x57  sAddr<16;

//=================================================

void EEPROM_WriteN(unsigned char mAddr,unsigned char sAddr,unsigned char n) 

{

    I2CSA = mAddr;              //页地址

    TX_BUF[0] = sAddr;          //子地址

    I2CNDAT = n;                //计数器初值

    TX_COUNTER = 0;

    while (I2CDCTL & I2CBUSY);  //检查模块忙

    I2CIFG =0;                  //中断标志清零

    I2CIE |= TXRDYIE;

    U0CTL |= MST;

    I2CTCTL |= I2CTRX + I2CSTT + I2CSTP;

    while ((~I2CIFG) & ARDYIFG); //检查发送结束

}

//===================================================

//1个字节

//===================================================

unsigned char EEPROM_ByteRead(unsigned char mAddr,unsigned char sAddr)

{

    I2CSA = mAddr;                  //页地址

    TX_BUF[0] = sAddr;              //子地址

    TX_COUNTER = 0;                 //计数器初值

    RX_COUNTER = 0;

   

    while (I2CDCTL & I2CBUSY);      //检查模块忙

    I2CNDAT = 1;                    //1位数据=子地址

    I2CIFG = 0;                     //中断标志清零

    I2CIE |= TXRDYIE;

    U0CTL |= MST;

    I2CTCTL |= I2CTRX + I2CSTT;     //置位起始位   发送子地址

    while ((~I2CIFG) & ARDYIFG);    //检查发送结束

 

    I2CIFG &= ~ARDYIFG;

    I2CIE |= RXRDYIE;

    I2CTCTL &= ~I2CTRX;

    I2CTCTL |= I2CSTT + I2CSTP;     //接收1位数据后置位停止位

    while ((~I2CIFG) & ARDYIFG);    //检查接收结束

   

    return RX_BUF[0];               //返回接收的1字节数据

}

//======================================

//n=N个字节,mAddr页地址;sAddr子地址

//======================================

void EEPROM_ReadN(unsigned char mAddr,unsigned char sAddr,unsigned char n)

{

unsigned char i;

unsigned char k;

unsigned char m=0;

    k = sAddr + n;

    for(i=sAddr;i<k;i++)

    {

        Rece_data[m]=EEPROM_ByteRead(mAddr,i);

        m++;

    }

}

 

 

 

//==================================

void SAVE_DATA(unsigned char mAddr,unsigned char sAddr,unsigned char n)

{

    TX_BUF[1] = 0X41;      

    TX_BUF[2] = 0X42;

    TX_BUF[3] = 0X43;      

    TX_BUF[4] = 0X44;

    TX_BUF[5] = 0X45;  

    TX_BUF[6] = 0X46;  

    TX_BUF[7] = 0X47;

    TX_BUF[8] = 0X48;      

    TX_BUF[9] = 0X49;      

    TX_BUF[10] = 0X4A;     

    TX_BUF[11] = 0X4B;     

   

    EEPROM_WriteN(0x50,0x00,n+1);

}

 

//==================================

int main(void)

{

    WDTCTL = WDTPW + WDTHOLD;   // Stop WDT

    INIT_SYSTIMER();

    Init_IIC();

    _EINT();                    //打开中断

 

    while(1)

    {

//=================================

 

      SAVE_DATA(0x50,0x00,11);

      EEPROM_ReadN(0x50,0x00,11);  

   

        delay(10);

//=================================

    }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约