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

📄 i2c.c

📁 msp430 非常经典的教材 希望对 msp430 的学者有帮助
💻 C
字号:

#include <msp430x16x.h>
#include "i2c.h"

#define SLAVEADDR   0x50;

int tx_count;
int rx_count;
unsigned char I2CBuffer[3];

void InitI2C(void)
{
    //将P3.1和P3.3设置为I2C管脚
    P3SEL = 0x0A; 
    //设置P3.1和P3.3管脚的方向
    P3DIR &= ~0x0A;
      
    //选择为I2C模式
    U0CTL |= I2C + SYNC; 
    //禁止I2C模块
    U0CTL &= ~I2CEN;      

    //设置I2C为7位地址模式,不使用DMA,
    //字节模式,时钟源为SMCLK,
    //设置成传输模式
    I2CTCTL = I2CTRX + I2CSSEL_2; 
    
    //定义从器件地址
    I2CSA = SLAVEADDR;  
    //设置本身的地址
    I2COA = 0x01A5;               
    
    //I2C时钟为SMCLK / 160
    I2CPSC = 159;  
    //SCL 高电平为:5  *I2C 时钟
    I2CSCLH = 0x03;   
    //SCL 低电平为:5  *I2C 时钟
    I2CSCLL = 0x03; 
    
    //I2C 模块有效
    U0CTL |= I2CEN;
    
    tx_count = 0;
    rx_count = 0;
}

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


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

void EEPROM_ByteWrite(unsigned char nAddr, unsigned char nVal)
{
    //等待I2C模块完成所有操作
    while (I2CDCTL&I2CBUSY) ; 
  
    //设置地址数据
    I2CBuffer[1] = nAddr; 
    //设置数据
    I2CBuffer[0] = nVal;
    //设置缓冲区指针
    tx_count = 1; 
  
    //写数据初始化
    I2CWriteInit();
    
    //发送数据的长度
    //1个控制字节,2个数据字节
    I2CNDAT = 2; 
    
    //开始和停止条件产生
    //开始I2C通信
    I2CTCTL |= I2CSTT+I2CSTP;  
    
    return;
}

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

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

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

#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[tx_count];
            tx_count = tx_count - 1;
            if (tx_count < 0)
            {
                //禁止发送中断
                I2CIE &= ~TXRDYIE; 
            }
            break;
        }
                        
        case I2CIV_GC: 
        {
            //一般调用中断
            break;
        }
        case I2CIV_STT:
        {
            //起始条件中断
            break;
        }
    }
}
void Init_Port(void)
{
    //初始化端口寄存器
    P1DIR = 0xFF;
    P2DIR = 0xFF;
    P3DIR = 0xF5;
    P4DIR = 0xFF;
    P5DIR = 0xFF;
    P6DIR = 0xFF;
}
void Init_CLK(void)
{
    unsigned int i;
    //将寄存器的内容清零
    //XT2震荡器开启
    //LFTX1工作在低频模式
    //ACLK的分频因子为1
    BCSCTL1 = 0X00;			
					
					
    do 
    {
        // 清除OSCFault标志
	IFG1 &= ~OFIFG;                       
	for (i = 0x20; i > 0; i--);                
    }
    while ((IFG1 & OFIFG) == OFIFG);      // 如果OSCFault =1   
				
    //open XT2, LFTX2 选择低频率
    BCSCTL1 &= ~(XT2OFF + XTS);
    //DCO Rsel=7(Freq=3200k/25摄氏度)  
    BCSCTL1 |= RSEL0 + RSEL1 + RSEL2; 
    BCSCTL1 |= 0x07;
    //MCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELM1;		
    //SMCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELS;		    
}

⌨️ 快捷键说明

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