⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1024.c

📁 此源代码为电力系统中的RTU终端反馈!具有GPRS通讯功能!
💻 C
字号:
#include "1024.h"

void I2CStart(void)                            
{                                          
  SET_SDA_FOR_OUTPUT;                         //msp430复位的I/O默认状态是输入,所以
  SET_SCL_FOR_OUTPUT;                         //先设为输出
  SDA_1;                                      //I2CStart的条件是在SCL是高电平的情况下
  SCL_1;                                      //SDA有一个从高电平向低电平的跳变   
  SDA_0;  
  SCL_0;

}

void I2CStop(void)
{
  SET_SDA_FOR_OUTPUT;                          //  这两句也可以不要 ,加上更好
  SET_SCL_FOR_OUTPUT;                          
  SDA_0;                                       //I2CStop的条件是在SCL是低电平的情况下
  SCL_1;                 
  SDA_1;                      
   clr_watchdog();     
}
 
BOOL I2CSendByte(BYTE ByteData)               //I2C的基本传送方式是字节发送
{ 
  BOOL ack;
  BYTE i;
  for (i = 0;  i < 8;  i++)                  //主器件通过SCL发出8个时钟脉冲将要发送的      
  {                                          //数据通过SDA发出
    SCL_0;
    if (ByteData&0x80) 
      SDA_1;
    else   
      SDA_0;       
    ByteData <<= 1;
    SCL_1;
  }
   
  SCL_0;                                      //在第9个时钟时读取从件(ATC1024)发送的                              
  SET_SDA_FOR_INPUT;                          //ack应答信号,此时SDA应为输入状态,SDA
                                              //为输入状态时,SDA是高电平
                                              //***注意在设置SDA为输入时,一定要先使SCL
  SCL_1;                                      //是低电平,千万不能使SCL为高电平,因为在
                                              //SCL是高电平的情况下,有可能出现SDA从低
  ack = READ_SDA;                             //到高的跳变(I2CStop状况)发送失败,
  SCL_0;
  SET_SDA_FOR_OUTPUT;                      
  return (ack);                               //返回ack信号,低电平表示有应答,高则没有 
}

BYTE I2CReceiveByte(BOOL last_char)
{   
  BYTE data=0, i;
  SET_SDA_FOR_INPUT;                         //主器件通过8个时钟信号,接收从件发出的数据 
  for (i = 0;  i < 8;  i++)
  { 
    SCL_0; 

    SCL_1;
    data <<=1;
    if (READ_SDA) data++;
  }  
  SCL_0;  
  if (last_char)                             //如果接收是最后的一个字节时,主器件在第9个        
    SET_SDA_FOR_INPUT;                      //给从件一个高电平信号,否则给一个低电平信号,
  else                                      //表示继续接收  
    SET_SDA_FOR_OUTPUT; 
  SDA_0;
  SCL_1;

  SCL_0;  
  return data;
}     
//对1024采用的是页写的方式,需要的参数是九位的页地址,八位的页内地址
//要传送数据的地址,传送数据的长度
//ATC1024分两块,每块256页,每页256个字节
BOOL TryWrite1024(UINT page, BYTE addr, BYTE *data, int len)
{ 
   int i;
   BYTE device, NUM;
   while (len)
   {
     device = 0xa4;
     if (page > 255) device += 2;       //如果页数大于256,则块数加1,即device加2
     
     I2CStart();
     if (I2CSendByte(device)) return FALSE;        //发送器件地址,没有应答信号表示失败
     if (I2CSendByte(page & 0xFF)) return FALSE;   //发送页地址,没有应答信号表示失败
     if (I2CSendByte(addr)) return FALSE;          //发送字节地址,没有应答信号表示失败   
     if (addr + len > 255)                         //如果所写数据跨页,进行相应的处理 
        NUM = 256 - addr;                          //先写当前页,再在下页写完余下的数据 
     else                                           
        NUM = len;
     len -= NUM;
     for(i = 0; i < NUM; i++) 
      if( I2CSendByte(*data++))return FALSE ;
     I2CStop();
     
     if (len)                                       
     {
        page++;
        addr=0;
        Delay(10000);                              //延时1MS子程序,每次写完后需要 
     }
   }
   return TRUE;                                    // 页写成功
}

BOOL TryRead1024(UINT page, BYTE addr, BYTE *data, int len)
{ 
  int i;  
  unsigned int device, NUM; 
  while (len)
  {
    device = 0xa4;
    if (page > 255) device += 2;
    
    I2CStart();
    if (I2CSendByte(device)) return FALSE;           //发送器件地址,没有应答信号表示失败
    if (I2CSendByte(page & 0xFF)) return FALSE;      //发送页地址,没有应答信号表示失败
    if (I2CSendByte(addr)) return FALSE;             //发送字节地址,没有应答信号表示失败
    I2CStart();                                      //如果所读数据跨页,进行相应的处理
    if (I2CSendByte(device + 1)) return FALSE;
    if (addr + len > 255) 
      NUM = 256 - addr;
    else
      NUM = len;
    len -= NUM;
    for (i = 0;  i < NUM - 1 ;  i++)
      *data++ = I2CReceiveByte(FALSE);              //没有读完时,主器件就发出继续读的信号
    *data++ = I2CReceiveByte(TRUE);                 //读完了,主器件就发出停止信号
    I2CStop();
    
    if (len > 0)
    {
      page++;
      addr=0;
      Delay(10000);                             
    }
  }
  return TRUE;
} 

BOOL Write1024(UINT page, BYTE addr, BYTE *data, int len ,BOOL is_delay)
{
  int i,t;    
   if(page>511) return FALSE;  
  // if( (CommState.DoWrParm==0) &&((page ==0) ||(page ==505))   )
  if( (page ==0) ||(page ==505))
  { if(CommState.DoWrParm ==0)
      return FALSE;  
   }
  for(i=0;i<1000;i++)
  {
     if(WriteDelay==0) break;     
       Delay(500);   
  }
   WP_Disable ; 
   for(t=0;t<3;t++)
   {
    i=TryWrite1024(page, addr, data, len);   
    if(i) break;   
   } 
    WriteDelay=10;  
   WP_Enable ;
   return i;
}

BOOL Read1024(UINT page, BYTE addr, BYTE *data, int len)
{
  int i,r;
   if(page>511) return FALSE;  
 for(i=0;i<1000;i++)
 {
   if(WriteDelay==0) break;
       Delay(500);   
 }
  for (i = 3; i; i--)
  {
    r=TryRead1024(page, addr, data, len);
    if (r)break;
    I2CStop();
  }
  return r;
}

void Delay(UINT us)
{
  int i;
  for (i = us >> 3;  i;  i--) 
     clr_watchdog();
  _NOP();
}

//历史数据:若15分钟存一次:保存7天 ,一天96条,每条记录76个字节,一页存两条记录,每天占48页,共占336页
//          若30分钟存一次:保存15天,一天48条,每条记录76个字节,一页存两条记录,每天占24页,共占360页
//          若1小时存一次:保存31天,一天24条,每条记录76个字节,一页存两条记录,每天占12页,共占372页
//统计数据:保存2个月,一天一条记录,每条记录占两页,共128页
UINT Get1024Page( STDATETIME data,char modeIsSt)                      //得到页首地址
{
    UINT PageAddr=512;
  //  if(data.week_date > 31)   return 512;
  //  if(data.month > 12)     return 512; 
    if(modeIsSt == HISDATA)
    {
       PageAddr =(( (data.week_date&0x1f)%((HisCate<<3) - 1))*(48/HisCate))+1;     //得到这一天的数据存贮的首地址
    }
    if(modeIsSt==STATICSDATA)
    {
       PageAddr=(data.month&0x1);                               
       PageAddr<<=6;
       PageAddr+=(373 +((data.week_date&0x1f)<<1));        //存两个月的统计数据       
    }
    return PageAddr;
}

BYTE GetAddrInPage(STDATETIME st)//得到页内地址   
{
     BYTE AddrInPage = 0;
     if(st.hour > 23 ) 
     {
        ptr_1024=512;
        return  0;        
     }     
     switch(HisCate)
     {
       case 1:  ptr_1024 += (st.hour<<1);
                ptr_1024 += (st.minute/30);
                if(st.minute == 15 || st.minute == 45)
                AddrInPage += (1<<7);
                break;
       case 2:  ptr_1024 += st.hour;
                AddrInPage += ((st.minute/30)<<7);
                break;
       case 4:  ptr_1024 += (st.hour>>1);
                AddrInPage += ((st.hour&0x01)<<7);
                break;
       default: break;         
     }
     return AddrInPage; 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -