新闻  |   论坛  |   博客  |   在线研讨会
24c512用msp430读写程序
tvb2058 | 2007-09-19 14:37:19    阅读:4494   发布文章

/************************************************************
*文件名: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       *       *     
*作者:   jy
*状态:  通过
************************************************************/
#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);
}

//------------------写at24c512----
void I2cWrAt24c512(void)
{
    unsigned int j=0;
    unsigned char m,n;
    unsigned int tempAddr;
  
    for (j = 0;j <462;j++)            // page write
        {
        tempAddr = 128*j;      
        while (I2CBUSY & I2CDCTL);            // I2C ready?
        I2cSendSubAddr(tempAddr,0x80);
        I2cSendStr(FPGACfg+tempAddr,0x80);   
        P4OUT ^= 0x80;   
        for (m=0;m<125;m++) {for (n=0;n<110;n++);}
        P4OUT ^= 0x80;        
        }
   
    tempAddr = 128*j;
    while (I2CBUSY & I2CDCTL);            // I2C ready?
    I2cSendSubAddr(tempAddr,0x4f);
    I2cSendStr(FPGACfg+tempAddr,0x4f);   
    P4OUT ^= 0x80;   
    for (m=0;m<125;m++) {for (n=0;n<110;n++);}
    P4OUT ^= 0x80;
}
   
                        
/*-------------------------- MSP430 I2C 读取数据-----------------------------*/
/*---------------------------------------------------------------------
--子程标号      :I2cSlaSubAddr                                          
--子程功能      :主器件发送从机器件地址和子地址                        
--入口参数      :unsigned int suba                    
--参数说明      :子地址                                         
--子程调用      :I2cBusSendByte                                       
--子程序状况    :Y                                                      
--说明          :完成地址信息的定位,先确定顺序读写的起始地址                                   
---------------------------------------------------------------------
--*/
void I2cReceSubAddr(unsigned int suba)    // test 09-25 读之前先写地址
{
    unsigned char Hi_suba,Lo_suba;
    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;  //  I2CRM = 1,自己设定字节个数

    I2CTCTL =  I2CSSEL_2;        // I2CRM = 0,
    I2CNDAT = 2;                 // I2CRM = 0,2byte地址 + 128byte数据,固定字节
    I2CIFG = 0;
    I2CPSC = 1;                  // set scl
//    I2CSCLH = 0x02;              // High period of SCL
  //  I2CSCLL = 0x02;              // Low period of SCL
    I2CSA = 0x50;                // Slave address of At24c512   
    U0CTL |= I2CEN;              // enable I2C module, 7 bit addr,  master mode   08-26
    U0CTL |= MST;

   
    Hi_suba = ( unsigned char )( suba >> 8 );
    Lo_suba = ( unsigned char )( suba & 0x00ff );
   
    while (I2CBUSY & I2CDCTL);    // I2C ready? 在空闲状态:0,空闲;1:忙
    I2CTCTL |= I2CTRX + I2CSTT + I2CSTP ;  // I2CRM =0,启动总线,发送从器件地址
    while((I2CIFG & NACKIFG) == 0x02)   // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1   
        {
         I2CTCTL |= I2CSTP;    // 结束总线
        }            
   
    I2cBusSendByte( Hi_suba );          //发送器件子地址  
    while((I2CIFG & NACKIFG) == 0x02)   // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1
        {
         I2CTCTL |= I2CSTP;    // 结束总线
        }  
    I2cBusSendByte( Lo_suba );        //发送器件子地址
    while((I2CIFG & NACKIFG) == 0x02)   // ack 为低电平,等待地址应答位 ,判断 无应答NACKIFG = 1
        {
         I2CTCTL |= I2CSTP;    // 结束总线
        }  
    DelayTime10us(250);
    DelayTime10us(250);
    DelayTime10us(250);
    DelayTime10us(250);
}

/*---------------------------------------------------------------------
--子程标号      :I2cSlaSubAddr                                          
--子程功能      :主器件接收初始化                       
--入口参数      :无                                                                                               
--子程序状况    :                                                     
--说明          :                                 
---------------------------------------------------------------------
--*/
void InitI2cRece(unsigned char num)
{
    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;  // I2CRM=1 x(x>256)字节模式

    I2CTCTL =  I2CSSEL_2;           // I2CRM=0
    I2CNDAT = num;                   // 1个字节
    I2CPSC = 1;                    // set scl
  //  I2CSCLH = 0x01;               // High period of SCL
  //  I2CSCLL = 0x01;               // Low period of SCL
    I2CIFG = 0;
    I2CSA = 0x50;                 // Slave address of At24c512  
    I2CTCTL &= ~I2CTRX;
    U0CTL |= I2CEN;               // enable I2C module, 7 bit addr,  master mode   08-26  
}

/*---------------------------------------------------------------
--功能描述    : 读一个字节
--子程序状况  :
------------------------------------------------------------------
--*/
unsigned char I2cReceSlaByte(void)
{
    unsigned char ch;
    DelayTime10us(15);
    U0CTL |=  MST;                //主模式   
    while (I2CBUSY & I2CDCTL);    // I2C ready? 在空闲状态:0,空闲;1:忙
    I2CTCTL |= I2CSTT + I2CSTP;              // I2CRM =0; Receive, ST, SP (clears MST)
    while((I2CIFG & RXRDYIFG) != RXRDYIFG);  // 等待地址应答位 ,判断   
    ch = I2CDRB;  
    return(ch);   
}

/*---------------------------------------------------------------
--功能描述    : 连续读数据
--子程序状况  :
------------------------------------------------------------------
--*/
void I2cReceSlaStr(unsigned char num)
{
    unsigned char i;
    DelayTime10us(15);
    U0CTL |=  MST;                //主模式   
    while (I2CBUSY & I2CDCTL);    // I2C ready? 在空闲状态:0,空闲;1:忙
    I2CTCTL |= I2CSTT + I2CSTP;   // I2CRM =0; Receive, ST, SP (clears MST)
    for (i=0;i<num;i++)
        {
        while((I2CIFG & RXRDYIFG) != RXRDYIFG);  // 等待地址应答位 ,判断   
        rxDataArray = I2CDRB;  
        }  
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
李宁 [ 匿名]  2008-10-07 11:23:50 

你好,能不能留个联系费方式,我想请教个问题,谢谢

推荐文章
最近访客