اطلاعیه

Collapse
No announcement yet.

مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

    با سلام خدمت دوستان و اساتید؛

    کدهای زیادی رو امتحان کردم و نمونه های زیادی رو چک کردم، ولی هرکار می کنم همون اوایل ارتباط گیر میکنه تو این حلقه چک:
    [code=c]while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));[/code]

    از I2C1 استفاده میکنم و این هم کدهای راه اندازیش:
    [code=c]//-----------------------------------------------------------------------------
    // Copyright:
    // Author:
    // Remarks:
    // known Problems:
    // Version: 0.0.1
    // Description: I2C Configuration library (.c)
    //
    //-----------------------------------------------------------------------------

    #include <stm32f10x.h>
    #include <stm32f10x_conf.h>
    #include "I2C_Configuration.h"

    #define I2C_Speed 100000
    #define I2C1_SLAVE_ADDRESS7 0xA0
    #define I2C_PageSize 4

    #define EEPROM_Block0_ADDRESS 0xA0 /* E2 = 0 */
    //#define EEPROM_Block1_ADDRESS 0xA2 /* E2 = 0 */
    //#define EEPROM_Block2_ADDRESS 0xA4 /* E2 = 0 */
    //#define EEPROM_Block3_ADDRESS 0xA6 /* E2 = 0 */

    u16 EEPROM_ADDRESS;

    void i2cInit(void){

    /* Enable PortB Clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE );
    /* Enable I2C1 Clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE) ;

    /* Configure I2C1 pins */
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Configure I2C1 pins: SCL and SDA */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);


    /* I2C1 Configuration */
    I2C_InitTypeDef I2C_InitStructure;

    /* I2C configuration */
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;

    /* I2C Peripheral Enable */
    I2C_Cmd(I2C1, ENABLE);
    /* Apply I2C configuration after enabling it */
    I2C_Init(I2C1, &I2C_InitStructure);

    }

    /************************************************** *****************************
    * Function Name : I2C_EE_Init
    * Description : Initializes peripherals used by the I2C EEPROM driver.
    * Input : None
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_Init()
    {
    /* depending on the EEPROM Address selected in the i2c_ee.h file */
    #ifdef EEPROM_Block0_ADDRESS
    /* Select the EEPROM Block0 to write on */
    EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
    #endif
    #ifdef EEPROM_Block1_ADDRESS
    /* Select the EEPROM Block1 to write on */
    EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
    #endif
    #ifdef EEPROM_Block2_ADDRESS
    /* Select the EEPROM Block2 to write on */
    EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
    #endif
    #ifdef EEPROM_Block3_ADDRESS
    /* Select the EEPROM Block3 to write on */
    EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
    #endif
    }

    /************************************************** *****************************
    * Function Name : I2C_EE_BufferWrite
    * Description : Writes buffer of data to the I2C EEPROM.
    * Input : - pBuffer : pointer to the buffer containing the data to be
    * written to the EEPROM.
    * - WriteAddr : EEPROM's internal address to write to.
    * - NumByteToWrite : number of bytes to write to the EEPROM.
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
    {
    u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

    Addr = WriteAddr % I2C_PageSize;
    count = I2C_PageSize - Addr;
    NumOfPage = NumByteToWrite / I2C_PageSize;
    NumOfSingle = NumByteToWrite % I2C_PageSize;

    /* If WriteAddr is I2C_PageSize aligned */
    if(Addr == 0)
    {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage == 0)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
    I2C_EE_WaitEepromStandbyState();
    }
    /* If NumByteToWrite > I2C_PageSize */
    else
    {
    while(NumOfPage--)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
    I2C_EE_WaitEepromStandbyState();
    WriteAddr += I2C_PageSize;
    pBuffer += I2C_PageSize;
    }

    if(NumOfSingle!=0)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
    I2C_EE_WaitEepromStandbyState();
    }
    }
    }
    /* If WriteAddr is not I2C_PageSize aligned */
    else
    {
    /* If NumByteToWrite < I2C_PageSize */
    if(NumOfPage== 0)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
    I2C_EE_WaitEepromStandbyState();
    }
    /* If NumByteToWrite > I2C_PageSize */
    else
    {
    NumByteToWrite -= count;
    NumOfPage = NumByteToWrite / I2C_PageSize;
    NumOfSingle = NumByteToWrite % I2C_PageSize;

    if(count != 0)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, count);
    I2C_EE_WaitEepromStandbyState();
    WriteAddr += count;
    pBuffer += count;
    }

    while(NumOfPage--)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
    I2C_EE_WaitEepromStandbyState();
    WriteAddr += I2C_PageSize;
    pBuffer += I2C_PageSize;
    }
    if(NumOfSingle != 0)
    {
    I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
    I2C_EE_WaitEepromStandbyState();
    }
    }
    }
    }

    /************************************************** *****************************
    * Function Name : I2C_EE_ByteWrite
    * Description : Writes one byte to the I2C EEPROM.
    * Input : - pBuffer : pointer to the buffer containing the data to be
    * written to the EEPROM.
    * - WriteAddr : EEPROM's internal address to write to.
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
    {
    /* Send STRAT condition */
    I2C_GenerateSTART(I2C1, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for write */
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Send the EEPROM's internal address to write to */
    I2C_SendData(I2C1, WriteAddr);

    /* Test on EV8 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send the byte to be written */
    I2C_SendData(I2C1, *pBuffer);

    /* Test on EV8 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STOP condition */
    I2C_GenerateSTOP(I2C1, ENABLE);
    }

    /************************************************** *****************************
    * Function Name : I2C_EE_PageWrite
    * Description : Writes more than one byte to the EEPROM with a single WRITE
    * cycle. The number of byte can't exceed the EEPROM page size.
    * Input : - pBuffer : pointer to the buffer containing the data to be
    * written to the EEPROM.
    * - WriteAddr : EEPROM's internal address to write to.
    * - NumByteToWrite : number of bytes to write to the EEPROM.
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
    {
    /* While the bus is busy */
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    /* Send START condition */
    I2C_GenerateSTART(I2C1, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for write */
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Send the EEPROM's internal address to write to */
    I2C_SendData(I2C1, WriteAddr);

    /* Test on EV8 and clear it */
    while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* While there is data to be written */
    while(NumByteToWrite--)
    {
    /* Send the current byte */
    I2C_SendData(I2C1, *pBuffer);

    /* Point to the next byte to be written */
    pBuffer++;

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    }

    /* Send STOP condition */
    I2C_GenerateSTOP(I2C1, ENABLE);
    }

    /************************************************** *****************************
    * Function Name : I2C_EE_BufferRead
    * Description : Reads a block of data from the EEPROM.
    * Input : - pBuffer : pointer to the buffer that receives the data read
    * from the EEPROM.
    * - ReadAddr : EEPROM's internal address to read from.
    * - NumByteToRead : number of bytes to read from the EEPROM.
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
    {
    /* While the bus is busy */
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

    /* Send START condition */
    I2C_GenerateSTART(I2C1, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for write */
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    /* Clear EV6 by setting again the PE bit */
    I2C_Cmd(I2C1, ENABLE);

    /* Send the EEPROM's internal address to write to */
    I2C_SendData(I2C1, ReadAddr);

    /* Test on EV8 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    /* Send STRAT condition a second time */
    I2C_GenerateSTART(I2C1, ENABLE);

    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    /* Send EEPROM address for read */
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);

    /* Test on EV6 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

    /* While there is data to be read */
    while(NumByteToRead)
    {
    if(NumByteToRead == 1)
    {
    /* Disable Acknowledgement */
    I2C_AcknowledgeConfig(I2C1, DISABLE);

    /* Send STOP Condition */
    I2C_GenerateSTOP(I2C1, ENABLE);
    }

    /* Test on EV7 and clear it */
    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
    /* Read a byte from the EEPROM */
    *pBuffer = I2C_ReceiveData(I2C1);

    /* Point to the next location where the byte read will be saved */
    pBuffer++;

    /* Decrement the read bytes counter */
    NumByteToRead--;
    }
    }

    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2C1, ENABLE);
    }

    /************************************************** *****************************
    * Function Name : I2C_EE_WaitEepromStandbyState
    * Description : Wait for EEPROM Standby state
    * Input : None
    * Output : None
    * Return : None
    ************************************************** *****************************/
    void I2C_EE_WaitEepromStandbyState(void)
    {
    vu16 SR1_Tmp = 0;

    do
    {
    /* Send START condition */
    I2C_GenerateSTART(I2C1, ENABLE);
    /* Read I2C1 SR1 register */
    SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
    /* Send EEPROM address for write */
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);
    }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

    /* Clear AF flag */
    I2C_ClearFlag(I2C1, I2C_FLAG_AF);

    /* STOP condition */
    I2C_GenerateSTOP(I2C1, ENABLE);
    }
    [/code]

    ممنون میشم اگه دوستان تجربه ای دارن کمک کنن.
    با تشکر

    پ.ن: پایه های I2C پول پ شدن و پایه های آدرس دهی at24c01 هم طبق گفته دیتاشیت واسه آدرس عمومیش Gnd شدن.

    «پشتکار» «پشتکار» «پشتکار»

    #2
    پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

    وقت بخیر

    کد راه اندازی که توی همه کتابخانه ها هست !!!!!! شما برنامه main خودتو بذار ببینیم چه کردی !!؟؟

    دیدگاه


      #3
      پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

      نوشته اصلی توسط taktrashe
      وقت بخیر

      کد راه اندازی که توی همه کتابخانه ها هست !!!!!! شما برنامه main خودتو بذار ببینیم چه کردی !!؟؟
      برنامه Main که چیز خاصی نداره!
      اول فراخوانی تابع i2cInit() و بعد از اون یه فراخوانی برای نوشتن، مثلاً:
      [code=c]i2cInit();
      I2C_EE_Init();
      I2C_EE_ByteWrite(10,10);[/code]

      و در نهایت گیر کردن توی حلقه ای که در پست اول گفتم.

      «پشتکار» «پشتکار» «پشتکار»

      دیدگاه


        #4
        پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

        تا اونجا که یادمه سمپلش کار می کرد
        فيلم آموزشي ميکروکنترلر LPC1768
        فيلم آموزشي تکميلي و پيشرفته ميکروکنترلر LPC1768
        فيلم آموزش کاربردی زبان سی در میکروکنترلر ARM
        فیلم آموزش مقدماتی میکروکنترلر LPC1788 به زودی ...

        دیدگاه


          #5
          پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6



          برنامه Main که چیز خاصی نداره!
          همه چیز تو main هست مابقی که کتابخانه است دوست خوب !! اگه Main چیزی نداره !! پاکش کن و کمپایل کن برنامه رو !!

          بگذریم !! تو پروژه تون ببینید دستوری که گیر کرده کدوم یک از این 3 تابع توی Main هست !!؟؟

          دیدگاه


            #6
            پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

            نوشته اصلی توسط mzarkoob
            تا اونجا که یادمه سمپلش کار می کرد
            قبلا رو یه بورد آماده با سمپل i2c نرم افزاری جواب گرفته بودم.ولی این عجیبه واسم.

            نوشته اصلی توسط taktrashe

            همه چیز تو main هست مابقی که کتابخانه است دوست خوب !! اگه Main چیزی نداره !! پاکش کن و کمپایل کن برنامه رو !!

            بگذریم !! تو پروژه تون ببینید دستوری که گیر کرده کدوم یک از این 3 تابع توی Main هست !!؟؟
            متوجه منظورم نشدین. اینکه میگم main ک چیزی نداره. یعنی همه ی موارد مربوط به config و توابع ارتباط با ic توی کتابخونه هس و main فقط فراخونیه.
            در مورد اینکه کدوم خط گیر میکنه هم که گفتم. توی پست اول.
            یعنی همون اول ارتباط i2c و قبل از حتی آدرس دهی بایت های آیسی.
            البته برای اینکه وقتتون گرفته نشه توابع رو چک کنید، تابع writeByte منظورمه.

            «پشتکار» «پشتکار» «پشتکار»

            دیدگاه


              #7
              پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

              وقت بخیر

              با توجه به دستورات I2c بعد از ارسال start سخت ماجول وازد مد ماستر میشود !!

              کد:
              /** 
               * @brief Communication start
               * 
               * After sending the START condition (I2C_GenerateSTART() function) the master 
               * has to wait for this event. It means that the Start condition has been correctly 
               * released on the I2C bus (the bus is free, no other devices is communicating).
               * 
               */
              /* --EV5 */
              #define I2C_EVENT_MASTER_MODE_SELECT           ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
              برای چک کردن صحت خط و درستی ارسال استارت دستور

              کد:
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
              استفاده میشود ! در صورتی که خط I2c آزاد نباشد و ماجول وازد این مرحله نشود ! در حالت انتظار می ماند .

              دیدگاه


                #8
                پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

                نوشته اصلی توسط taktrashe
                وقت بخیر

                با توجه به دستورات I2c بعد از ارسال start سخت ماجول وازد مد ماستر میشود !!

                کد:
                /** 
                 * @brief Communication start
                 * 
                 * After sending the START condition (I2C_GenerateSTART() function) the master 
                 * has to wait for this event. It means that the Start condition has been correctly 
                 * released on the I2C bus (the bus is free, no other devices is communicating).
                 * 
                 */
                /* --EV5 */
                #define I2C_EVENT_MASTER_MODE_SELECT           ((uint32_t)0x00030001) /* BUSY, MSL and SB flag */
                برای چک کردن صحت خط و درستی ارسال استارت دستور

                کد:
                  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
                استفاده میشود ! در صورتی که خط I2c آزاد نباشد و ماجول وازد این مرحله نشود ! در حالت انتظار می ماند .
                خب؟
                اینکه دقیقاً صورت مشکل بود :| دلیلش یا راه حلشو میخواستم بدونم...

                «پشتکار» «پشتکار» «پشتکار»

                دیدگاه


                  #9
                  پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

                  وقت بخیر

                  ستفاده میشود ! در صورتی که خط I2c آزاد نباشد و ماجول وازد این مرحله نشود ! در حالت انتظار می ماند .
                  جواب در همین خط بالاست استاد ! خطوط I2C شما احتمالا آزاد نمیشوند که در انتظار می ماند !

                  متاسفانه دوست عزیز ( ناراحت نشوید ) جوری برخورد می فرمایید که دوستان دیگر نمایندگی Stm هستند و موظف به پاسخ گویی دقیق ، بطوری که یک راست بروند سر اصل مطلب و اشکال رو عنوان کنند !! شما که خود برنامه رو نوشتید و سخت افزار دستتون هست در حال بررسی و عیب یابی هستید ! چه برسد به دوستی که از راه دور قصد کمک دارد !

                  اینحانب یا دیگر دوستان ! بر اساس تجربه نکاتی که بنظرمون میرسه رو مطرح میکنیم !! اشکال و نکنه اصلی رو خود شما میتونید بررسی و کشف کنید

                  دیدگاه


                    #10
                    پاسخ : مشکل در راه اندازی AT24C01 EEPROM با STM32F103RBT6

                    نوشته اصلی توسط taktrashe
                    وقت بخیر

                    جواب در همین خط بالاست استاد ! خطوط I2C شما احتمالا آزاد نمیشوند که در انتظار می ماند !

                    متاسفانه دوست عزیز ( ناراحت نشوید ) جوری برخورد می فرمایید که دوستان دیگر نمایندگی Stm هستند و موظف به پاسخ گویی دقیق ، بطوری که یک راست بروند سر اصل مطلب و اشکال رو عنوان کنند !! شما که خود برنامه رو نوشتید و سخت افزار دستتون هست در حال بررسی و عیب یابی هستید ! چه برسد به دوستی که از راه دور قصد کمک دارد !

                    اینحانب یا دیگر دوستان ! بر اساس تجربه نکاتی که بنظرمون میرسه رو مطرح میکنیم !! اشکال و نکنه اصلی رو خود شما میتونید بررسی و کشف کنید
                    نمیدونم شما چرا بد برداشت میکنید پست های منو؟
                    برعکس من اصن از این اخلاقا ندارم ک بخوام بشینم کسی کمک کنه یا طلب داشته باشم.
                    اگر هم پست اولم رو مطالعه بفرمایید، خودم هم گفتم کدوم خط و کجا گیر میکنه با اینکه مدارات پیشنهادی لحاظ شده و باز هم جواب نمیده! و در نهایت نوشتم دوستانی که تجربه ی اینو داشتن، اگه لطف کنن کمک کنن!
                    کجای این حس طلبکاری بود؟ :|
                    تاپیکهای قبلی ام ک داشتم یا دوستان کمک کردن به نتیجه رسیده و یا سرچ کردم یا تجربه ای به نتیجه رسیدم، پست های اولش رو ادیت کردم و راه حل رو گذاشتم تا اگه کس دیگه ای به مشکل مشابه من خورد روال کار رو بدونه. و هیچ علاقه ای هم ندارم دیگران رو اذیت کنم تا مشکل خودم حل بشه.

                    موفق باشید

                    «پشتکار» «پشتکار» «پشتکار»

                    دیدگاه

                    لطفا صبر کنید...
                    X