用msp430读写24c512程序 /************************************************************ *文件名:msp430f169i2c.c *整体描述:MSP430F169单片机硬件IIC软件,字节方式,主方式 * IIC接口:P3.3=SCL,P3.1=SDA;(开漏输出) * 相应寄存器:地址寄存器 I2COA 用于存放自身从地址(从方式时才有用) * 地址寄存器 I2CSA 用于存放外围的从机地址(主方式时才有用) * 控制寄存器 U0CTL 硬件I2C的设置、使能、模式等。 发送控制寄存器 I2CTCTL * 数据控制寄存器 I2CDCTL 指示I2C总线的状态 * * U0CTL -- RXDMAEN,TXDMAEN,I2C, XA, LISREN,SYNC,MST,I2CEN * 0 0 1 0 0 1 1 1 (0x17) * I2CTCTL --I2CWORD,I2CRM,I2CSSEL1,I2XSSEL0, I2CTRX,I2CSTB, I2CSTP, I2CSTT * 0 1 1 0 * 0 * * ************************************************************/ #include <msp430x16x.h> #include "fpgacode.h"
#define WR24C512 #define LED1_1 (0x20) /* Port 3.5 Output -> LED1 */ #define LED1_0 (0xdf)
#define SDA_1 P3OUT |= BIT1 //串行数据线,SDA = 1 #define SDA_0 P3OUT &=~ BIT1 //SDA = 0 #define SCL_1 P3OUT |= BIT3 //串行时钟线,SCL = 1 #define SCL_0 P3OUT &=~ BIT3 //SCL = 0
#define SDADIR_IN P3DIR &=~ BIT1 //SDA,I/O口为输入 #define SDADIR_OUT P3DIR |= BIT1 //I/0口为输出 #define SDA_IN ((P3IN >> 1) & 0x01) //Read SDA
#define SCLDIR_IN P3DIR &=~ BIT3 //SCL,I/O口为输入 #define SCLDIR_OUT P3DIR |= BIT3 //I/0口为输出 #define SCL_IN ((P3IN >> 3) & 0x01) //Read SCL
#ifdef WR24C512 static int numi = 0; //Data Pointer #else static int numj = 0; //Data Pointer #endif
#define I2CSLA 0x50
/*-------------------------------------------------------- --功能描述: 检查总线是否空闲 --子程序状况: 09-23调试通过 ---------------------------------------------------------- --*/ void I2c_Idle_Check(void) { while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 }
void DelayTime10us(unsigned char n) { unsigned char i; while(n--) // 5 cycles for(i=0;i<10;i++); // 8mhz 110:771 + 4 to while }
/*--------------------------------------------------------- --功能描述:发送数据:用于向总线发送数据 --子程序状况: 09-23调试通过 ----------------------------------------------------------- --*/ void I2cBusSendByte(unsigned char c) { while((I2CIFG & TXRDYIFG) != TXRDYIFG); // 检测发送准备 I2CDRB = c; // 写发送寄存器 }
/*------------------ MSP430 I2C 写数据 09-23调试通过---------------------*/ /*-------------------------------------------------------- --功能描述:申请总线:进行I2C总线的初始化-发送起始信号 --子程序状况: 09-23调试通过 ---------------------------------------------------------- --*/ void I2C_Send(unsigned char ndatNum) { // 注意:通讯结束,I2CMST 自动清零,再次通讯必须重新置位 P3OUT = 0x00; // clear P3 output register P3SEL = 0x0A; // P3.1=SDA, P3.3=SCL,Select I2C pins, Setup I2C module U0CTL |= (I2C + SYNC); // select I2C mode;XA=0,7bit_addresing; U0CTL &= ~I2CEN; // i2c功能使能无效 // I2CTCTL = I2CRM + I2CSSEL_2; // x(x>256)字节模式 ,new start测试使用
// 选择方式 I2CRM=0,最终用户使用 I2CTCTL = I2CSSEL_2; I2CNDAT = 2 + ndatNum; // 最终用户使用,2byte地址 + 128byte数据
I2CPSC = 2; // set scl I2CIFG = 0; I2CSA = 0x50; // Slave address of At24c512 U0CTL |= I2CEN; // enable I2C module, 7 bit addr, master mode 08-26 U0CTL |= MST;
while (I2CBUSY & I2CDCTL); // I2C ready? 在空闲状态:0,空闲;1:忙 I2CTCTL |= I2CTRX + I2CSTT + I2CSTP ; // I2CRM =0,启动总线,发送从器件地址 while((I2CIFG & NACKIFG) == 0x02); // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1 } /*---------------------------------------------------------------- --子程标号 :I2cWrSlaSubAddr --子程功能 :主机发送从机的子地址 --入口参数 :unsigned char sla,unsigned int suba --参数说明 :子地址 --子程序状况 :09-23调试通过 --说明 :完成地址信息的定位,先确定顺序读写的起始地址 ----------------------------------------------------------------- --*/ unsigned char I2cSendSubAddr(unsigned int suba,unsigned char ndatNum) { unsigned char Hi_suba,Lo_suba;
I2C_Send(ndatNum); // 启动总线,等待地址应答位
Hi_suba = ( unsigned char )( suba >> 8 ); Lo_suba = ( unsigned char )( suba & 0x00ff ); I2cBusSendByte( Hi_suba ); //发送器件子地址 while((I2CIFG & 0x02) == NACKIFG ) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } I2cBusSendByte( Lo_suba ); //发送器件子地址 while((I2CIFG & 0x02 )==0x02 ) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } return(1); }
/*------------------------------------------------------------------ --子程标号 :I2cWriteStr (用户函数) --子程功能 :向I2C从器件写入数据 --入口参数 :unsigned char *ps,unsigned char num --参数说明 :写入数据的地址指针,数据个数 --子程序状况 : 09-23调试通过 --说明 :I2C读取数据 ------------------------------------------------------------------- --*/ unsigned char I2cSendStr(const unsigned char * ps,unsigned char num) { // unsigned char i; unsigned char tempnum; tempnum = num-1; for(numi=0;numi<tempnum;numi++) { I2cBusSendByte(*ps); while((I2CIFG & 0x02) == NACKIFG) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } ps++; }
// I2CTCTL |= I2CSTP; //I2CRM =1模式中,在发送最后一个数据之前将停止位置位,*特别注意,必须 I2cBusSendByte(*ps); while((I2CIFG & 0x02) == NACKIFG) // 等待数据的应答 { I2CTCTL |= I2CSTP; // 无应答,结束总线 return(0); } return(1); }
|