📄 iic.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 + -