#include <msp430X16X.h>
unsigned char I2CBuffer[2];
/*************************************************************
初始化函数
************************************************************/
//对端口的输入输出方向的设置
void Init_Port(void)
{
//初始化端口寄存器
P1DIR=0xFF;
P2DIR=0xFF;
P3DIR=0xF5;
P4DIR=0xFF;
P5DIR=0xFF;
P6DIR=0xFF;
}
//设置单片机的各个时钟,在此设置的基础上,才能适当设置IIC模块的总线工作频率
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);
//DSO Rsel=7(Freq=3200k/25摄氏度)
BCSCTL1|=RSEL0+RSEL1+RSEL2;
BCSCTL1|=0x07;
//MCKL的时钟源为TX2CLK,分频因子为1
BCSCTL2+=SELM1;
//SMCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 +=SELS;
}
//设置相应寄存器实现对IIC模块的设置
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;
}
/****************************************************
24的写操作
****************************************************/
//写操作的初始化
void I2CWriteInit(void)
{
//主(Master)模式
U0CTL|=MST;
//传输模式,R/W为:0
I2CTCTL|=I2CTRX;
//清除中断标志
I2CIFG&=~TXRDYIFG;
//发送中断使能
I2CIE=TXRDYIE;
}
//写操作:单片机首先发送控制字节,然后发送地址字节,最后输入写的内容
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;
}
/*******************************************************************
24读操作函数:单片机发送一个控制字节,然后发送地址数据,然后读出该地址的数据
******************************************************************/
unsigned char EEPROM_RandomRead(unsigned char nAddr)
{
//等待I2C模块完成所有操作
while (I2CDCTL&I2CBUSY);
//设置地址
I2CBuffer[0]=nAddr;
//设置缓冲区指针
tx_count=0;
//写操作初始化
I2CWriteInit();
//传输数据长度
//1个控制字节和1个地址数据
I2CNDAT=1;
//清除中断标志
I2CIFG&=~ARDYIFG;
//产生起始条件
I2CTCTL|=I2CSTT;
//等待传输完成
while((~I2CIFG)&ARDYIFG);
//读操作初始化
I2CReadInit();
//接收1个字节的数据
I2CNDAT=1;
//清除中断标志
I2CIFG&+~ARDYIFG;
//开始接收,产生重新起始和停止条件
I2CTCTL|=I2CSTT+I2CSTP;
//等待传输完成
while((~I2CIFG)&ARDYIFG);
//返回数据
return I2CBuffer[0];
}
//读初始化函数
void I2CReadInit(void)
{
//接收模式,R/W为:1
I2CTCTL&=~I2CTRX;
//接收中断使能
I2CIE=RXRDYIE;
}
//上面的程序中,需要设定IIC模块工作的模式,并使能相应的中断,从而实现数据
//的接收。在完成1次指定地址读操作后,24LC02B的地址指针可以自动加1,此时可以
//实现当前地址的读操作
unsigned char EEPROM_CurrentAddessRead(void)
{
//等待I2C模块完成所有操作
while(I2CDCTL&I@CBUSY);
//读操作的初始化
I2CReadInit();
//主(Master)模式
U0CTL|=MST;
//接收1个字节的数据
I2CNDAT=1;
//清除中断标志
I2CIFG&=~ARDYIFG;
//开始接收,产生重新起始和停止条件
I2CTCTL|=I2CSTT+I2CSTP;
//等待传输完成
while((~I2CIFG)&ARDYIFG);
//返回数据
return I2CBuffer[0];
}
/****************************************************************
具体函数:通过对不同中断标志的判断就可以实现不同的操作
****************************************************************/
#if __VER__ <200
interrupt [USARTOTX_VECTOR] void ISR_I2C(void)
#else
#pragma vector=USARTOTX_VECTOR
__interrupt void ISR_I2C(void)
#endif
{
switch(I2CIV)
{
case I2CIV_AL:
{
//仲裁中断
break;
}
case I2CIV_NACK:
{
//NACK中断
break;
}
case I2CIV_ARDY:
{
//访问准备好中断
break;
}
case I2CIV_RXRDY:
{
//接收准备好中断
I2CIV_RXRDY[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;
}
}
}
//ACK
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(I2CDCTL&I2CBUST);
//产生停止条件
I2CTCTL|=I2CSTP;
//等待停止条件复位
while(I2CDCTL&I2CBUSY);
count=count+1;
}
//清除I2CEN位
U0CTL&=~I2CEN;
I2CTCTL&=~I2CRM;
//使能I2C
U0CTL|=I2CEN;
return;
}
/***********************************************************************
首先在指定的地址中写入数据,然后利用随机读函数读出指定地址的数据,并利用
当前地址按函数顺序读出下一个地址的数据
***********************************************************************/
void main( void )
{
volatile unsigned char Data[6];
//停止看门狗
WDTCTL=WDTPW+WDTHOLD;
//初始化端口
Init_Port();
//初始化时钟
Init_CLK();
//I2C初始化
InitI2C();
//打开中断
_EINT();
//写入数据
EEPROM_ByteWrite(0x0000,0x12);
//等待写操作完成
EEPROM_AckPolling();
//写入数据
EEPROM_ByteWrite(0x0001,0x34);
//等待写操作完成
EEPROM_AckPolling();
//写入数据
EEPROM_ByteWrite(0x0002,0x56);
//等待写操作完成
EEPROM_AckPolling();
//写入数据
EEPROM_ByteWrite(0x0003,0x78);
//等待写操作完成
EEPROM_AckPolling();
//写入数据
EEPROM_ByteWrite(0x0004,0x9A);
//等待写操作完成
EEPROM_AckPolling();
//写入数据
EEPROM_ByteWrite(0x0005,0xBC);
//等待写操作完成
EEPROM_AckPolling();
//读出数据,随机读
Data[0]=EEPROM_RandomRead(0x0000);
//读出数据,当前地址读
Data[1]=EEPROM_CurrentAddressRead();
//读出数据,当前地址读
Data[2]=EEPROM_CurrentAddressRead();
//读出数据,当前地址读
Data[3]=EEPROM_CurrentAddressRead();
//读出数据,当前地址读
Data[4]=EEPROM_CurrentAddressRead();
//读出数据,当前地址读
Data[5]=EEPROM_CurrentAddressRead();
}
IIC.rar_IIC
版权申诉
152 浏览量
2022-09-19
15:53:18
上传
评论
收藏 16KB RAR 举报
![avatar](https://profile-avatar.csdnimg.cn/271c0f59ce4e427783f4849fb0aeba2e_weixin_42662171.jpg!1)
林当时
- 粉丝: 103
- 资源: 1万+
最新资源
- ParaStor300S技术培训PPT-面向售前-V1.4.pptx
- 在MATLAB中,你可以使用多种函数和工具来创建各种类型的图形 以下是一些基本的MATLAB绘图命令和示例:
- 1_网络2204班 30 王磊 open flow 协议分析实践.docx
- 探索 v-on 之奥秘二:事件及各类修饰符的深度剖析与案例展示
- k8s基础教程与相关面试
- TerraScan中文用户指南
- DCDC电源芯片 MP2315GJ-Z DataSheel
- ABAP代码上传到GiLab
- 汽车电子等产品EMC整改案例.pdf
- LN61C SOT23-3封装 高精度低功耗小封装电压检测芯片 深圳市可芯电子有限公司.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)