我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 624|回复: 5

STM32 I2C 24C512

[复制链接]

该用户从未签到

34

主题

12

回帖

0

积分

二级逆天

积分
0

终身成就奖

发表于 2020-11-24 07:55:18 | 显示全部楼层 |阅读模式
/**********************************************************************************
* 文件名  :I2C.c
* 描述    :IIC外设EEPROM(AT24C512)应用函数库
*
* 硬件连接: ---------------------------
*          |       PB6 - I2C1_SCL      |
*          |       PB7 - I2C1_SDA      |
*           ---------------------------
* 说明    :模拟IIC
**********************************************************************************/
#include "drive.h"
#include "system.h"
#include "app.h"
#include "w5500_conf.h"

#define ATMEL_EEPROM
//#define CYPRESS_FRAM

//#define CONFIG_HAVE_FM24V05
#define CONFIG_HAVE_FM24V10

#define ADDR_24CXX    0xA0
#define SCLH         GPIOB->BSRR = GPIO_Pin_6
#define SCLL         GPIOB->BRR  = GPIO_Pin_6   
#define SDAH         GPIOB->BSRR = GPIO_Pin_7
#define SDAL         GPIOB->BRR  = GPIO_Pin_7
#define SCLread      GPIOB->IDR  & GPIO_Pin_6
#define SDAread      GPIOB->IDR  & GPIO_Pin_7


void InitI2C(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
    GPIO_Init(GPIOB, &GPIO_InitStructure);  
}

bool I2C_Start(void)
{
    SDAH;
    SCLH;
    DelayUs(5);
    if(!SDAread)return false; //SDA线为低电平则总线忙,退出
    SDAL;
    DelayUs(5);
    if(SDAread) return false; //SDA线为高电平则总线出错,退出
    SDAL;
    DelayUs(5);
    return true;
}

void I2C_Stop(void)
{
    SCLL;
    DelayUs(5);
    SDAL;
    DelayUs(5);
    SCLH;
    DelayUs(5);
    SDAH;
    DelayUs(5);
}

void I2C_Ack(void)
{
    SCLL;
    DelayUs(5);
    SDAL;
    DelayUs(5);
    SCLH;
    DelayUs(5);
    SCLL;
    DelayUs(5);
}

void I2C_NoAck(void)
{
    SCLL;
    DelayUs(5);
    SDAH;
    DelayUs(5);
    SCLH;
    DelayUs(5);
    SCLL;
    DelayUs(5);
}

bool I2C_WaitAck(void)   //返回为:=1有ACK,=0无ACK
{
    SCLL;
    DelayUs(5);
    SDAH;   
    DelayUs(5);
    SCLH;
    DelayUs(5);
    if(SDAread)
    {
     SCLL;
     return false;
    }
    SCLL;
    return true;
}

void I2C_SendByte(byte SendByte) //数据从高位到低位//
{
    byte i=8;
    while(i--)
    {
        SCLL;
        DelayUs(5);
        if(SendByte&0x80)
          SDAH;  
        else
          SDAL;   
        SendByte<<=1;
        DelayUs(5);
        SCLH;
        DelayUs(5);
    }
    SCLL;
}

byte I2C_ReceiveByte(void)  //数据从高位到低位
{
    byte i=8;
    byte ReceiveByte=0;
   
    SDAH;   
    while(i--)
    {
      ReceiveByte<<=1;      
      SCLL;
      DelayUs(5);
      SCLH;
      DelayUs(5);
      if(SDAread)
      {
        ReceiveByte|=0x01;
      }
    }
    SCLL;
    return ReceiveByte;
}

#ifdef CYPRESS_FRAM
////////////////////////////////////////////////////////////////////////////////////////////////////
bool I2C_WriteByte(byte SendByte, uint WriteAddress, byte DeviceAddress)
{
    if(!I2C_Start()) return false;
    I2C_SendByte( DeviceAddress & 0xFE);//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((WriteAddress>>8) & 0xFF));   //设置高起始地址      
    I2C_WaitAck();
    I2C_SendByte((byte)((WriteAddress) & 0xFF));   //设置低起始地址      
    I2C_WaitAck();
    I2C_SendByte(SendByte);           //写数据
    I2C_WaitAck();   
    I2C_Stop();
    //要等待EEPROM写完,可以采用查询或延时方式(10ms)
    DelayMs(1);
    return true;
}

uint I2C_EEPROM_BufferWrite(byte* pBuffer, uint WriteAddr, uint NumByteToWrite){

  uint i;
    byte *p;
    p = pBuffer;
    if(!I2C_Start()) return false;
    I2C_SendByte( ADDR_24CXX & 0xFE);//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((WriteAddr>>8) & 0xFF));   //设置高起始地址      
    I2C_WaitAck();
    I2C_SendByte((byte)((WriteAddr) & 0xFF));   //设置低起始地址      
    I2C_WaitAck();

  for(i=0;i<NumByteToWrite;i++){
    I2C_SendByte(*(p+i));           //写数据
    I2C_WaitAck();
    DelayUs(1);
  }
    I2C_Stop();
    //要等待EEPROM写完,可以采用查询或延时方式(10ms)
    DelayMs(1);
    return true;
}


//读出1字节数据          待读出地址       器件类型
byte I2C_ReadByte( uint ReadAddress,  byte DeviceAddress)
{  
    byte temp;
    if(!I2C_Start())return false;
    I2C_SendByte((DeviceAddress & 0xFE));//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((ReadAddress>>8) & 0xFF));   //设置高起始地址  
    I2C_WaitAck();
    I2C_SendByte((byte)((ReadAddress) & 0xFF));     //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte((DeviceAddress & 0xFE)|0x01);    //读器件地址
    I2C_WaitAck();
    temp = I2C_ReceiveByte();
    I2C_NoAck();
    I2C_Stop();
    return temp;
}

void I2C_24CXX_Read(uint nAddr, byte* pDat, uint nLen)
{
    ushort i;
    for(i=0;i<nLen;i++)
    {
        *(pDat+i)=I2C_ReadByte(nAddr+i, ADDR_24CXX);
  }
}

uint I2C_24CXX_ReadID(void){
    byte temp;
  uint rv = 0;
    if(!I2C_Start())return false;
  
  I2C_SendByte(0xf8);
  if(!I2C_WaitAck()){I2C_Stop(); return false;}
  
    I2C_SendByte((ADDR_24CXX & 0xFE));//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
  
  if(!I2C_Start())return false;
  I2C_SendByte(0xf9);
  I2C_WaitAck();
  
    temp = I2C_ReceiveByte();
  rv = rv | (temp<<24);
  I2C_Ack();
  
  temp = I2C_ReceiveByte();
  rv = rv | (temp<<16);
  I2C_Ack();

  temp = I2C_ReceiveByte();
  rv = rv | (temp<<16);
    I2C_NoAck();
    I2C_Stop();
  
    return rv;

}

#endif

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef ATMEL_EEPROM
//写入1字节数据     待写入数据       待写入地址            器件类型
bool I2C_WriteByte(byte SendByte, uint WriteAddress, byte DeviceAddress)
{  
    if(!I2C_Start()) return false;
    I2C_SendByte( DeviceAddress & 0xFE);//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((WriteAddress>>8) & 0xFF));   //设置高起始地址      
    I2C_WaitAck();
    I2C_SendByte((byte)((WriteAddress) & 0xFF));   //设置低起始地址      
    I2C_WaitAck();
    I2C_SendByte(SendByte);           //写数据
    I2C_WaitAck();   
    I2C_Stop();
    //要等待EEPROM写完,可以采用查询或延时方式(10ms)
    DelayMs(10);
    return true;
}


//读出1字节数据          待读出地址       器件类型
byte I2C_ReadByte( uint ReadAddress,  byte DeviceAddress)
{  
    byte temp;
    if(!I2C_Start())return false;
    I2C_SendByte((DeviceAddress & 0xFE));//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((ReadAddress>>8) & 0xFF));   //设置高起始地址  
    I2C_WaitAck();
    I2C_SendByte((byte)((ReadAddress) & 0xFF));     //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte((DeviceAddress & 0xFE)|0x01);    //读器件地址
    I2C_WaitAck();
    temp = I2C_ReceiveByte();
    I2C_NoAck();
    I2C_Stop();
    return temp;
}


void I2C_24CXX_Write(uint nAddr, byte* pDat, uint nLen)
{
    ushort i;
    for(i=0;i<nLen;i++)
    {
        I2C_WriteByte(*(pDat+i), nAddr+i, ADDR_24CXX);
    }
}

void I2C_24CXX_Read(uint nAddr, byte* pDat, uint nLen)
{
    ushort i;
    for(i=0;i<nLen;i++)
    {
        *(pDat+i)=I2C_ReadByte(nAddr+i, ADDR_24CXX);
    }
}

/*
* 函数名:I2C_EEPROM_PageWrite
* 描述  :向EEPROM的一个写循环中可以写多个字节,但一次写入的
*         字节数不能超过EEPROM页的大小,AT24C02每页有8个字节
* 输入    :-pBuffer 缓冲区指针
*               -WriteAddr 接收数据的EEPROM的内部地址
*               -NumByteToWrite 要写入EEPROM的字节数
* 输出    :无
* 调用    :外部调用
*/
bool I2C_EEPROM_PageWrite(byte* pBuffer, uint WriteAddress, uint NumByteToWrite)
{
    if(!I2C_Start())return false;
    I2C_SendByte( ADDR_24CXX & 0xFE);//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((WriteAddress>>8) & 0xFF));   //设置高起始地址      
    I2C_WaitAck();
    I2C_SendByte((byte)((WriteAddress) & 0xFF));   //设置低起始地址      
    I2C_WaitAck();
   
    while(NumByteToWrite--)
    {
        //发送当前数据
        I2C_SendByte(*pBuffer);
        //指针指向下一字节
        pBuffer++;
        //等待发送数据寄存器为空,即收到ACK
        I2C_WaitAck();   
    }
    //发送停止传输指令
    I2C_Stop();
    //DelayUs(500);
    DelayMs(10);
    return true;
}

bool I2C_EEPROM_PageWrite1(byte* pBuffer, uint WriteAddress, uint NumByteToWrite)
{
    if(!I2C_Start())return false;
    I2C_SendByte( ADDR_24CXX & 0xFE);//写器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return false;}
    I2C_SendByte((byte)((WriteAddress>>8) & 0xFF));   //设置高起始地址      
    I2C_WaitAck();
    I2C_SendByte((byte)((WriteAddress) & 0xFF));   //设置低起始地址      
    I2C_WaitAck();
   
    while(NumByteToWrite--)
    {
        //发送当前数据
        I2C_SendByte(*pBuffer);
        //指针指向下一字节
        pBuffer++;
        //等待发送数据寄存器为空,即收到ACK
        I2C_WaitAck();   
    }
    //发送停止传输指令
    I2C_Stop();
    //DelayUs(700);
    DelayMs(2);
    return true;
}

/*
* 函数名:I2C_EEPROM_BufferWrite
* 描述  :将缓冲区中的数据写到I2C的外设(EEPROM)中
* 输入    :-pBuffer 缓冲区指针
*         -WriteAddr 接收数据的EEPROM的内部地址
*         -NumByteToWrite 要写入EEPROM的字节数
* 输出    :无
* 调用    :外部调用
*/
uint I2C_EEPROM_BufferWrite(byte* pBuffer, uint WriteAddr, uint NumByteToWrite)
{
    //定义4个8位的变量,分别为页数,不足一页字节数,字节地址,字节计数器
    byte NumOfPage = 0, NumOfSingle = 0,  count = 0;    //页数,不足一页字节数,计数器
    ushort Addr = 0;                                    //字节地址
    //字节地址(不足一页)
    Addr = WriteAddr % PageSize;
    //一页中的剩余字节数
    count = PageSize - Addr;
    //欲写入数据所占的页数
    NumOfPage = NumByteToWrite / PageSize;
    //欲写入数据所占的字节数(不足一页)
    NumOfSingle = NumByteToWrite % PageSize;
   
    //判断写入起始地址是否为某页的第一个字节地址处,是则进入
    if(Addr == 0)
    {
        //判断写入的数据字节数是否足一页,不足则进入
        if(NumOfPage == 0)
        {
            //向EEPROM写入NumOfSingle个字节的数据
            I2C_EEPROM_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            //I2C_24CXX_Write(WriteAddr, pBuffer, NumOfSingle);
        }
        //写入的数据字节数超过一页
        else
        {
            //向EEPROM写入NumOfPage页数据
            while(NumOfPage--)
            {
                //向EEPROM写入一页数据
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, PageSize);
               
                //写入数据地址指向下一页起始地址
                WriteAddr += PageSize;
               
                //写入数据指向下一页的数据
                pBuffer += PageSize;
            }
            
            //写入余下不足一页的数据
            if(NumOfSingle != 0)
            {
                //向EEPROM写入NumOfSingle个字节的数据
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, NumOfSingle);
               
            }
        }
    }
    //写入数据的起始地址不是某页的第一个字节地址处
    else
    {
        //判断写入的数据字节数是否足一页,不足则进入
        if(NumOfPage == 0)
        {
            //向EEPROM写入NumOfSingle个字节的数据,当写到页边界时,将从该页的起始地址继续写入数据
            //****所以,遇到这种情况要特别处理****

            if(count>=NumByteToWrite)       //如果当前页剩余字节数大于或等于要写入的字节数
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            else
            {
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, count);  //先写入当前页剩余的字节数

                //将数据写满当前页后剩余的字节数
                NumByteToWrite -= count;

                //写入数据地址指向下一页起始地址
                WriteAddr += count;
               
                //写入数据指向下一页的数据
                pBuffer += count;

                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, NumByteToWrite); //写入下页剩余的字节数

            }
        }
        //写入的数据字节数超过一页
        else
        {
            //将数据写满当前页后剩余的字节数
            NumByteToWrite -= count;
            
            //除去当前页后欲写入的页数
            NumOfPage = NumByteToWrite / PageSize;
            
            //除去当前页后欲写入数据所占的字节数(不足一页)
            NumOfSingle = NumByteToWrite % PageSize;
            
            //判断当前页是否还有剩余空间,是则进入
            if(count != 0)
            {
                //将当前页所剩空间写满
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, count);
               
                //写入数据地址指向下一页起始地址
                WriteAddr += count;
               
                //写入数据指向下一页的数据
                pBuffer += count;
            }
            
            //向EEPROM写入NumOfPage页数据
            while(NumOfPage--)
            {
                //向EEPROM写入一页数据
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, PageSize);
               
               
                //写入数据地址指向下一页起始地址
                WriteAddr += PageSize;
               
                //写入数据指向下一页的数据
                pBuffer += PageSize;
            }
            
            //写入余下不足一页的数据
            if(NumOfSingle != 0)
            {
                //向EEPROM写入NumOfSingle个字节的数据
                I2C_EEPROM_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            }
        }
    }
    return 0;
}


uint I2C_EEPROM_BufferWrite1(byte* pBuffer, uint WriteAddr, uint NumByteToWrite)
{
    //定义4个8位的变量,分别为页数,不足一页字节数,字节地址,字节计数器
    byte NumOfPage = 0, NumOfSingle = 0,  count = 0;    //页数,不足一页字节数,计数器
    ushort Addr = 0;                                    //字节地址
    //字节地址(不足一页)
    Addr = WriteAddr % PageSize;
    //一页中的剩余字节数
    count = PageSize - Addr;
    //欲写入数据所占的页数
    NumOfPage = NumByteToWrite / PageSize;
    //欲写入数据所占的字节数(不足一页)
    NumOfSingle = NumByteToWrite % PageSize;
   
    //判断写入起始地址是否为某页的第一个字节地址处,是则进入
    if(Addr == 0)
    {
        //判断写入的数据字节数是否足一页,不足则进入
        if(NumOfPage == 0)
        {
            //向EEPROM写入NumOfSingle个字节的数据
            I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, NumOfSingle);
            //I2C_24CXX_Write(WriteAddr, pBuffer, NumOfSingle);
        }
        //写入的数据字节数超过一页
        else
        {
            //向EEPROM写入NumOfPage页数据
            while(NumOfPage--)
            {
                //向EEPROM写入一页数据
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, PageSize);
               
                //写入数据地址指向下一页起始地址
                WriteAddr += PageSize;
               
                //写入数据指向下一页的数据
                pBuffer += PageSize;
            }
            
            //写入余下不足一页的数据
            if(NumOfSingle != 0)
            {
                //向EEPROM写入NumOfSingle个字节的数据
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, NumOfSingle);
               
            }
        }
    }
    //写入数据的起始地址不是某页的第一个字节地址处
    else
    {
        //判断写入的数据字节数是否足一页,不足则进入
        if(NumOfPage == 0)
        {
            //向EEPROM写入NumOfSingle个字节的数据,当写到页边界时,将从该页的起始地址继续写入数据
            //****所以,遇到这种情况要特别处理****

            if(count>=NumByteToWrite)       //如果当前页剩余字节数大于或等于要写入的字节数
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, NumOfSingle);
            else
            {
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, count);  //先写入当前页剩余的字节数

                //将数据写满当前页后剩余的字节数
                NumByteToWrite -= count;

                //写入数据地址指向下一页起始地址
                WriteAddr += count;
               
                //写入数据指向下一页的数据
                pBuffer += count;

                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, NumByteToWrite); //写入下页剩余的字节数

            }
        }
        //写入的数据字节数超过一页
        else
        {
            //将数据写满当前页后剩余的字节数
            NumByteToWrite -= count;
            
            //除去当前页后欲写入的页数
            NumOfPage = NumByteToWrite / PageSize;
            
            //除去当前页后欲写入数据所占的字节数(不足一页)
            NumOfSingle = NumByteToWrite % PageSize;
            
            //判断当前页是否还有剩余空间,是则进入
            if(count != 0)
            {
                //将当前页所剩空间写满
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, count);
               
                //写入数据地址指向下一页起始地址
                WriteAddr += count;
               
                //写入数据指向下一页的数据
                pBuffer += count;
            }
            
            //向EEPROM写入NumOfPage页数据
            while(NumOfPage--)
            {
                //向EEPROM写入一页数据
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, PageSize);
               
               
                //写入数据地址指向下一页起始地址
                WriteAddr += PageSize;
               
                //写入数据指向下一页的数据
                pBuffer += PageSize;
            }
            
            //写入余下不足一页的数据
            if(NumOfSingle != 0)
            {
                //向EEPROM写入NumOfSingle个字节的数据
                I2C_EEPROM_PageWrite1(pBuffer, WriteAddr, NumOfSingle);
            }
        }
    }
    return 0;
}

/*
* 函数名:I2C_EEPROM_BufferRead
* 描述  :从EEPROM里读取一块数据
* 输入    :-pBuffer 存放从EEPROM读取到的数据的缓冲区指针
*         -ReadAddr 读取数据的EEPROM的内部地址
*         -NumByteToRead 要从EEPROM读取的字节数
* 输出    :无
* 调用    :外部调用
*/
//bool I2C_EEPROM_BufferRead(ushort ReadAddress, byte* pBuffer, ushort NumByteToRead)
//{
//  if(!I2C_Start()) return false;
//  I2C_SendByte( ADDR_24CXX & 0xFE);//写器件地址
//  if(!I2C_WaitAck()){I2C_Stop(); return false;}
//  I2C_SendByte((byte)((ReadAddress>>8) & 0xFF));   //设置高起始地址  
//  I2C_WaitAck();
//  I2C_SendByte((byte)((ReadAddress) & 0xFF));     //设置低起始地址      
//  I2C_WaitAck();
//  I2C_Start();
//  I2C_SendByte((ADDR_24CXX & 0xFE)|0x01);    //读器件地址
//  I2C_WaitAck();
//
//  //读取NumByteToRead个字节数据
//  while(NumByteToRead)
//  {
//      
//      if(!I2C_WaitAck())
//      {
//          //从EEPROM中读取一个字节的数据并储存到缓冲区中
//          *pBuffer = I2C_ReceiveByte();
//  
//          //缓冲区指针指向下一个字节存放地址
//          pBuffer++;
//         
//          //字节数减1
//          NumByteToRead--;
//  
//          //I2C_NoAck();
//          //I2C_WaitAck();
//      }   
//  }
//  I2C_Stop();
//}

#endif

byte  WriteFlagInit = WriteDataFlag;


unsigned int InputChannelAddress ;
unsigned int OutputChannelAddress ;
unsigned int LockDataAddress ;
unsigned int Step ;
unsigned int SystemDataAddress ;
unsigned int FactoryDataAddress ;


void I2C_DataInit(void)        //数据初始化
{
    unsigned int i=0;
    unsigned char WriteFlag=0xff;
    unsigned char FactoryDataFlag=0xff;
   
    I2C_24CXX_Read( FactoryDataFlagAddress,&FactoryDataFlag,1 );
   
    if( FactoryDataFlag!=WriteDataFlag )        //单片机第一次上电  初始化外部存储的数据
    {
        I2C_EEPROM_BufferWrite( &AppInit.FactoryData.ModeSet,FactoryDataAddress, sizeof(FactorySetStruct) );
        FactoryDataFlag = WriteDataFlag;
        I2C_EEPROM_BufferWrite( &FactoryDataFlag,FactoryDataFlagAddress, sizeof(FactoryDataFlag) );
    }
    I2C_24CXX_Read( FactoryDataAddress,&App.FactoryData.ModeSet,sizeof(FactorySetStruct) );

    I2C_24CXX_Read(WriteDataFlagAddress,&WriteFlag,1);
    //写入初始化数据
    if(WriteFlag!=WriteDataFlag)
    {
        LcdDisplayString(0,"   Data Writing......   ");
        LcdDisplayString(1,"      Please Wait!      ");
        
        for(i=0;i<31;i++)
        {
            if( (i!=0)&&(i<=App.FactoryData.FixedNumber) )
            {
                continue;
            }
            //写当前组和30组的用户数据,包括输入通道,输出通道,锁定数据(注意系统锁定数据只使用当前组)
            I2C_EEPROM_BufferWrite( &AppInit.InputData[0].ChannelName[0], InputChannelAddress+Step*i,Step);
        }
        
        for( i=1;i<(App.FactoryData.FixedNumber+1);i++) //工厂程序的名字不可初始化
        {
            I2C_24CXX_Read( SystemDataAddress+(unsigned char*)(&App.SystemData.ProgramName[0])-(unsigned char*)(&App.SystemData.DeviceID),
                            (unsigned char*)(&AppInit.SystemData.ProgramName[0]),13 );
        }
        //写系统数据
        I2C_EEPROM_BufferWrite( &AppInit.SystemData.DeviceID,SystemDataAddress, sizeof(SystemSetStruct) );
        
        WriteFlag = WriteDataFlag;
        I2C_EEPROM_BufferWrite((unsigned char*)(&WriteFlag),WriteDataFlagAddress,1);
    }
    //读系统的数据   
    I2C_24CXX_Read( SystemDataAddress,&App.SystemData.DeviceID,sizeof(SystemSetStruct) );
        
    memcpy( LcdBuffer0,App.SystemData.LogoString1,24);
    memcpy( LcdBuffer1,App.SystemData.LogoString2,24);

    local_ip[0]=App.SystemData.IP[0];
    local_ip[1]=App.SystemData.IP[1];
    local_ip[2]=App.SystemData.IP[2];
    local_ip[3]=App.SystemData.IP[3];
   
    mac[5]=App.SystemData.IP[3];
    mac[4]=App.SystemData.IP[2];
    mac[3]=App.SystemData.IP[1];
    mac[2]=App.SystemData.IP[0];

    gateway[0] = App.SystemData.Gateway[0];
    gateway[1] = App.SystemData.Gateway[1];
    gateway[2] = App.SystemData.Gateway[2];
    gateway[3] = App.SystemData.Gateway[3];
        
    switch(App.SystemData.PowerOnState)
    {
        //power on keep state
        case 1:  
            //读当前组数据
            I2C_24CXX_Read(InputChannelAddress, &App.InputData[0].ChannelName[0], Step);
            break;
        
        //all mute
        case 2:
            //读当前组数据
            I2C_24CXX_Read(InputChannelAddress, &App.InputData[0].ChannelName[0], Step);        
            //静音
            for( i=0;i<4;i++ )  App.InputData.Mute = 0;
            for( i=0;i<8;i++ )  App.OutputData.Mute = 0;
        
            I2C_EEPROM_BufferWrite( (unsigned char*)(&App.InputData[0].ChannelName[0]),InputChannelAddress, Step-sizeof(LockDataStruct) );
            break;
   
        //load program
        case 3:
            LcdDisplayString(0,"        Waiting         ");
            LcdDisplayString(1," Power On Loading...... ");
            //读对应组数据
            I2C_24CXX_Read( InputChannelAddress+App.SystemData.PowerLoadNumber*Step, &App.InputData[0].ChannelName[0], Step);
            I2C_24CXX_Read( LockDataAddress+64, &App.CurrentLockData.SystemLoadProgram, 32);
        
            App.SystemData.CurrentProgramNumber = App.SystemData.PowerLoadNumber;
            memcpy( (unsigned char*)(&App.SystemData.ProgramName[0][0]),
                    (unsigned char*)(&App.SystemData.ProgramName[App.SystemData.PowerLoadNumber][0]),12);
        
            break;

        //异常处理防止连不上设备
        default:
            break;
    }   
   
    App.OutputData[0].AllVolume = 0;    //总音量设置为0
   
    if( FactoryFlag==1 )    //工厂模式
    {
        //静音
        for( i=0;i<4;i++ )  App.InputData.Mute = 0;
        for( i=0;i<8;i++ )  App.OutputData.Mute = 0;     
    }
    if( (App.FactoryData.TimeHourSet>0)||(App.FactoryData.MinuteSet>0) )
    {
        switch( App.FactoryData.ModeSet )
        {
            case 0:
                if( App.FactoryData.TimeHourCount<9952 )
                {
                    App.FactoryData.TimeHourCount++;
                    I2C_EEPROM_BufferWrite( (unsigned char*)(&App.FactoryData.TimeHourCount),
                                        FactoryDataAddress+(unsigned int)(&App.FactoryData.TimeHourCount)-(unsigned int)(&App.FactoryData.ModeSet),2);
                }
                if( App.FactoryData.TimeHourCount>App.FactoryData.TimeHourSet )
                {
                    FactoryLockFlag = 1;
                    for( i=0;i<4;i++ )  App.InputData.Mute = 0;      //静音
                    for( i=0;i<8;i++ )  App.OutputData.Mute = 0;
                    
                    GPIO_WriteBit( GPIOA, GPIO_Pin_1, Bit_RESET);       //直接关静音继电器
                }
                break;
            case 1:
                if( (App.FactoryData.TimeHourCount*60+App.FactoryData.MinuteCount)
                    >=(App.FactoryData.TimeHourSet*60+App.FactoryData.MinuteSet) )
                {
                    FactoryLockFlag  = 1;
                    for( i=0;i<4;i++ )  App.InputData.Mute = 0;      //静音
                    for( i=0;i<8;i++ )  App.OutputData.Mute = 0;     
                    
                    GPIO_WriteBit( GPIOA, GPIO_Pin_1, Bit_RESET);       //直接关静音继电器
                }
                break;
        }
    }
   
    if( App.FactoryData.FixedNumber>30 )
    {
        App.FactoryData.FixedNumber = 0;
        I2C_EEPROM_BufferWrite( (unsigned char*)(&App.FactoryData.FixedNumber),
                                SystemDataAddress+(unsigned int)&App.FactoryData.FixedNumber-(unsigned int)&App.FactoryData.ModeSet,1);
    }
   
    //App.FactoryData.DeviceMode = 24;
    //App.FactoryData.DeviceMode = 26;
    //App.FactoryData.DeviceMode = 28;
    //App.FactoryData.DeviceMode = 36;
    //App.FactoryData.DeviceMode = 46;
    App.FactoryData.DeviceMode = 48;
}
回复

使用道具 举报

  • TA的每日心情
    开心
    9 小时前
  • 签到天数: 128 天

    [LV.7]常住居民III

    32

    主题

    1万

    回帖

    3万

    积分

    三级逆天

    积分
    34414

    终身成就奖特殊贡献奖原创先锋奖社区居民忠实会员社区劳模最爱沙发原创达人优秀斑竹奖宣传大使奖

    QQ
    发表于 2020-11-24 08:15:01 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    4 天前
  • 签到天数: 78 天

    [LV.6]常住居民II

    4

    主题

    1544

    回帖

    1873

    积分

    二级逆天

    积分
    1873

    终身成就奖

    发表于 2020-11-24 08:26:12 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    难过
    3 天前
  • 签到天数: 81 天

    [LV.6]常住居民II

    0

    主题

    3710

    回帖

    7451

    积分

    二级逆天

    积分
    7451

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    发表于 2020-11-24 08:49:00 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 107 天

    [LV.6]常住居民II

    5

    主题

    6751

    回帖

    1万

    积分

    三级逆天

    积分
    14185

    终身成就奖特殊贡献奖原创先锋奖

    发表于 2020-11-24 08:52:26 | 显示全部楼层
    回复

    使用道具 举报

  • TA的每日心情
    开心
    半小时前
  • 签到天数: 41 天

    [LV.5]常住居民I

    6

    主题

    1万

    回帖

    2万

    积分

    三级逆天

    积分
    20508

    终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

    QQ
    发表于 2020-11-25 08:11:42 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    论坛开启做任务可以
    额外奖励金币快速赚
    积分升级了


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    平平安安
    TOP
    快速回复 返回顶部 返回列表