打印
[STM32F1]

STM32F103 + AT24C256的EEPROM

[复制链接]
4168|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32F103  
我用的3.5的函数库 和 AT24C256K的 EEPROM

这段代码我是在微雪电子的程序上修改了下,单看读写函数都没问题

但是我主程序开机要打印一定字节的数据想看看效果的话,发现超过1000个byte程序就无效果了。

读写函数如下:
【读】:
uint8_t I2C_Read(I2C_TypeDef *I2Cx, uint8_t I2C_Addr, uint16_t addr, uint8_t *buf, uint16_t num)         //256K 的EEPROM 传送WORD ADDRESS 是2个字节,修改addr和num类型
{
    if(num==0)
        return 1;
       
        while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
               
        I2C_AcknowledgeConfig(I2Cx, ENABLE);
               
        I2C_GenerateSTART(I2Cx, ENABLE);                                                         //开始
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
       
        I2C_Send7bitAddress(I2Cx, ADDR_24C02N, I2C_Direction_Transmitter);                   //Device Address         写
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
                       
    I2C_SendData(I2Cx, addr >> 8);                                                                                                //1st WORD Address                 如果用的是2K的,则只需要传送1个字节
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        /******************************************************************/                //2nd WORD Address
        I2C_SendData(I2Cx, addr & 0xff);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        /*****************************************************************/
       
        I2C_GenerateSTART(I2Cx, ENABLE);                                                                                        //开始
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);                                //Device Address   读
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

        while (num)
    {
                if(num==1)
                {
                     I2C_AcknowledgeConfig(I2Cx, DISABLE);
                    I2C_GenerateSTOP(I2Cx, ENABLE);                                                                //如果一定时间无ACK,则会发送停止信号
                }
            
                while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));  /* EV7 */
            *buf = I2C_ReceiveData(I2Cx);                                                                  //数据
            buf++;
            /* Decrement the read bytes counter */
            num--;
    }

        I2C_AcknowledgeConfig(I2Cx, ENABLE);

        return 0;
}

【写】:

/*******************************************************************************
* Function Name  : I2C_delay
* Description    :
* Input          : None
* Output         : None
* Return         : None
* Attention                 : None
*******************************************************************************/
static void I2C_delay(uint16_t cnt)
{
        while(cnt--);
}

/*******************************************************************************
* Function Name  : I2C_AcknowledgePolling
* Description    :
* Input          : I2C_TypeDef * , uint8_t
* Output         : None
* Return         : None
* Attention                 : None                                 
*******************************************************************************/
static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx, uint8_t I2C_Addr)
{
  vu16 SR1_Tmp;
  do
  {   
    I2C_GenerateSTART(I2Cx, ENABLE);
    SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);
        I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
  }while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));

  I2C_ClearFlag(I2Cx, I2C_FLAG_AF);   
  I2C_GenerateSTOP(I2Cx, ENABLE);
}

/*******************************************************************************
         I2C1单字节写函数                                  
*******************************************************************************/
uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx, uint8_t I2C_Addr, uint16_t addr, uint8_t value)
{
        I2C_GenerateSTART(I2Cx, ENABLE);                                                            //开始
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));  

        I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);                           //Device Address 写
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        I2C_SendData(I2Cx, addr >> 8);                                                                                   //First Word Address
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        /*************************************************************************/                   //Second Word Address
        I2C_SendData(I2Cx, addr & 0xff);
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        /*************************************************************************/

        I2C_SendData(I2Cx, value);                                                                                                                  //Data
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        I2C_GenerateSTOP(I2Cx, ENABLE);                                                                                                   //结束

          I2C_AcknowledgePolling(I2Cx, I2C_Addr);         

        I2C_delay(2000);

        return 0;
}

/*******************************************************************************
                        I2C1写函数               
*******************************************************************************/
uint8_t I2C_Write(I2C_TypeDef *I2Cx, uint8_t I2C_Addr, uint16_t addr, uint8_t *buf, uint16_t num)
{
        uint16_t err = 0;
               
        while(num--)
        {
                if(I2C_WriteOneByte(I2Cx, I2C_Addr, addr++, *buf++))
                {
                        err++;
                }
        }
        if(err)
                return 1;
        else
                return 0;       
}



我主程序里如果把这个函数去掉,即使超过1000个字节也能正常


void XTCS_Init()                 //系统参数默认值
{
        uint8_t xtcs[16] = {0};
        I2C_Read(I2C1, ADDR_24C02N, 49, xtcs, 16);       
        //抽测 位置数据报告频度、GPS定位频度、航行速度门限值  判断是否从未保存过系统参数
        if(((xtcs[2] == 0x00) || (xtcs[2] == 0xff)) && ((xtcs[3] == 0x00) || (xtcs[3] == 0xff)) && ((xtcs[6] == 0x00) || (xtcs[6] == 0xff))        && ((xtcs[7] == 0x00) || (xtcs[7] == 0xff)) && ((xtcs[10] == 0x00) || (xtcs[10] == 0xff)))
        {
                XTCS.serviceflag = 0x01;
                XTCS.sleepflag = 0x01;
                XTCS.positionfreq[0] = 0x00;          // 144 单位:10分钟
                XTCS.positionfreq[1] = 0x90;
                XTCS.routefreq1 = 0x0F;                         //        15  单位:分钟
                XTCS.routefreq2 = 0xF0;                         //        240  单位:分钟                 
                XTCS.gpsfreq[0] = 0x00;                         //10 单位: 秒
                XTCS.gpsfreq[1] = 0x0A;                         
                XTCS.routevalue = 0x0F;          //15 单位:度
                XTCS.zerospeed_thresold = 0x02;         //2  单位: 0.1米/秒
                XTCS.speed_thresold        = 0x1A;                 //26 单位: 0.1米/秒
                XTCS.distinguish_thresold = 0x14; //20 单位:10米
                XTCS.multidelay_thresold = 0x01;  //1  单位:分钟
                XTCS.controlcenterID[0] = 0x00;          // 0 区域报警、多位置报告等自发自收
                XTCS.controlcenterID[1] = 0x00;
                XTCS.controlcenterID[2] = 0x00;
                memset(XTCS.operator_name, 0, 16);//默认操作员名字编码为0
                I2C_Write(I2C1, ADDR_24C02N, 49, &(XTCS.serviceflag), 1);
                I2C_Write(I2C1, ADDR_24C02N, 50, &(XTCS.sleepflag), 1);
                I2C_Write(I2C1, ADDR_24C02N, 51, &(XTCS.positionfreq[0]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 52, &(XTCS.positionfreq[1]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 53, &(XTCS.routefreq1), 1);
                   I2C_Write(I2C1, ADDR_24C02N, 54, &(XTCS.routefreq2), 1);
                I2C_Write(I2C1, ADDR_24C02N, 55, &(XTCS.gpsfreq[0]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 56, &(XTCS.gpsfreq[1]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 57, &(XTCS.routevalue), 1);
                I2C_Write(I2C1, ADDR_24C02N, 58, &(XTCS.zerospeed_thresold), 1);
                I2C_Write(I2C1, ADDR_24C02N, 59, &(XTCS.speed_thresold), 1);
                I2C_Write(I2C1, ADDR_24C02N, 60, &(XTCS.distinguish_thresold), 1);
                I2C_Write(I2C1, ADDR_24C02N, 61, &(XTCS.multidelay_thresold), 1);
                I2C_Write(I2C1, ADDR_24C02N, 62, &(XTCS.controlcenterID[0]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 63, &(XTCS.controlcenterID[1]), 1);
                I2C_Write(I2C1, ADDR_24C02N, 64, &(XTCS.controlcenterID[2]), 1);
        }
        else
        {
                XTCS.serviceflag = 0x01;
                XTCS.sleepflag = 0x01;
                XTCS.positionfreq[0] = xtcs[2];          
                XTCS.positionfreq[1] = xtcs[3];
                XTCS.routefreq1 = xtcs[4];                         
                XTCS.routefreq2 = xtcs[5];                         
                XTCS.gpsfreq[0] = xtcs[6];       
                XTCS.gpsfreq[1] = xtcs[7];                         
                XTCS.routevalue = xtcs[8];         
                XTCS.zerospeed_thresold = xtcs[9];         
                XTCS.speed_thresold        = xtcs[10];                 
                XTCS.distinguish_thresold = xtcs[11];
                XTCS.multidelay_thresold = xtcs[12];  
                XTCS.controlcenterID[0] = xtcs[13];          
                XTCS.controlcenterID[1] = xtcs[14];
                XTCS.controlcenterID[2] = xtcs[15];
                memset(XTCS.operator_name, 0, 16);//默认操作员名字编码为0       
        }
}


大家能帮我看看,是因为我的读写函数不对了,还是我开机的这个 XTCS_Init() 不对了?
       

沙发
小浣熊| | 2014-9-17 23:07 | 只看该作者
好吧,这个程序真是挺长呀,能不能标注一下呢!!

使用特权

评论回复
板凳
lqab1983|  楼主 | 2014-9-18 09:39 | 只看该作者
首先传个时序图

使用特权

评论回复
地板
lqab1983|  楼主 | 2014-9-18 09:41 | 只看该作者
其次 没啥可标注的吧,读就开头一个函数;
末尾是写函,他调用了单字节写函数

代码中间那些是延时和获取等待信号的函数

我这个不超过1000个字节就可以,一上1000就不行!

为什么,我都修改字节数了,而且有时程序就又能行?不知道为什么

使用特权

评论回复
5
icecut| | 2014-9-18 09:48 | 只看该作者
看一下勘误手册。听说103可以试试模拟iic

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

53

帖子

0

粉丝