程序和流程图:IIC.hvoid Init_IIC(void);void EEPROM_ByteWrite(unsigned char nAddr,unsigned char nVal); unsigned char EEPROM_RandomRead(unsigned char nAddr); unsigned char EEPROM_CurrentAddressRead(void);void EEPROM_AckPolling(void);void Init_CLK(void);void Init_IIC_Port(void);Main.C/*******************************************IIC for AT24c16 OR AT24CXXX 系列只要控制好IICRM IICSTP IICSTT 其硬件会自动完成SCL SDA的一系列时序只要注意各个发送与接收的控制标志位.******************************************/#include <MSP430x16x.h>#include "IIC.h"volatile unsigned char Data[6];void main(void){//volatile unsigned char Data[6];//停止看门狗WDTCTL = WDTPW+WDTHOLD;//初始化端口Init_IIC_Port();//初始化时钟Init_CLK();//I2C初始化Init_IIC(); //置传输方式及控制方式//打开中断_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); //地址自动加1 //读出数据,当前地址读Data[1] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[2] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[3] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[4] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[5] = EEPROM_CurrentAddressRead(); }IIC.C#include <MSP430x16x.h>#include "IIC.h"#define SLAVEADDR 0x50;int tx_count;int rx_count;unsigned char I2CBuffer[3];void Init_IIC(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 / 160I2CPSC = 159;//SCL 高电平为:5 *I2C 时钟I2CSCLH = 0x03;//SCL 低电平为:5 *I2C 时钟I2CSCLL = 0x03;//I2C 模块有效U0CTL |= I2CEN;tx_count = 0;rx_count = 0;}void I2CWriteInit(void) //对于AT24CXXX的写操作是置成主模式并置位中断使能.{//主(Master)模式U0CTL |= MST;//传输模式,R/W 为:0I2CTCTL |= I2CTRX;//清除中断标志I2CIFG &= ~TXRDYIFG;//发送中断使能I2CIE = TXRDYIE;}void I2CReadInit(void){//接收模式,R/W 为:1I2CTCTL &= ~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;//使能I2CU0CTL |= I2CEN;return;}#if __VER__ < 200interrupt [USART0TX_VECTOR] void ISR_I2C(void)#else#pragma vector=USART0TX_VECTOR__interrupt void ISR_I2C(void)#endif //上面的程序其实只要编写://#pragma vector=USART0TX_VECTOR __interrupt void ISR_I2C(void)就行.{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_IIC_Port(void){//初始化端口寄存器与IIC口无关的PX口关闭以便于对编写系统板的综合程序.//P1DIR = 0xFF;//P2DIR = 0xFF;P3DIR = 0xF5;P5DIR = 0x7F;//P6DIR = 0xFF;//P4OUT = 0X11;//P5OUT &= 0XF0;P3SEL|=BIT1+BIT3; //在这里如果设置成}void Init_CLK(void){unsigned int i;//将寄存器的容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1BCSCTL1 = 0X00;do{// 清除OSCFault标志IFG1 &= ~OFIFG;for (i = 0x20; i > 0; i--);}while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1//open XT2, LFTX2 选择低频率BCSCTL1 &= ~(XT2OFF + XTS); //BCSCTL1=0X00 功能一样BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;BCSCTL1 |= 0x07;//MCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELM1;//SMCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELS;}//对于系统时钟的选择关系到整个程序运行稳定性./*************************************************************文件名:msp430f169i2c.c*整体描述:MSP430F169单片机硬件IIC软件,字节方式,主方式* IIC接口:P3.3=SCL,P3.1=SDA;(开漏输出)* 相应寄存器:地址寄存器I2COA 用于存放自身从地址(从方式时才有用)* 地址寄存器I2CSA 用于存放外围的从机地址(主方式时才有用)* 控制寄存器U0CTL 硬件I2C的设置、使能、模式等。