在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32的I2C-EEPROM已調(diào)試成功

            STM32的I2C-EEPROM已調(diào)試成功

            作者: 時(shí)間:2016-11-17 來源:網(wǎng)絡(luò) 收藏

            萬利的I2C-EEPROM例程有些問題,經(jīng)本人兩個(gè)晝夜的反復(fù)試驗(yàn),已修改完善。

            本文引用地址:http://www.biyoush.com/article/201611/315433.htm

            修改了兩個(gè)地方,在void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)寫操作函數(shù)和void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)讀操作函數(shù)體內(nèi)的開頭先要執(zhí)行一句I2C_EE_WaitEepromStandbyState();

            這樣在以后調(diào)用寫操作函數(shù)和讀操作函數(shù)時(shí)就不用執(zhí)行I2C_EE_WaitEepromStandbyState()了。但上電復(fù)位后先要執(zhí)行一次讀操作,以后就可以無限制的隨便調(diào)用這兩個(gè)函數(shù)了。

            詳細(xì)如下。

            /* Includes ------------------------------------------------------------------*/
            #include "stm32f10x_lib.h"
            #include "i2c_ee.h"
            #include"delay.h"

            /* Private typedef -----------------------------------------------------------*/
            /* Private define ------------------------------------------------------------*/
            #define I2C_Speed 10000
            #define I2C1_SLAVE_ADDRESS7 0xA0

            #define I2C_PageSize 4


            /* Private macro -------------------------------------------------------------*/
            /* Private variables ---------------------------------------------------------*/
            u16 EEPROM_ADDRESS;

            /* Private function prototypes -----------------------------------------------*/

            void I2C_Configuration(void);


            /*******************************************************************************
            * Function Name : I2C_Configuration
            * Description : I2C Configuration
            * Input : None
            * Output : None
            * Return : None
            *******************************************************************************/
            void I2C_Configuration(void)
            {
            GPIO_InitTypeDef GPIO_InitStructure;
            I2C_InitTypeDef I2C_InitStructure;

            /* Configure I2C1 pins: SCL and SDA */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//開漏輸出
            GPIO_Init(GPIOB, &GPIO_InitStructure);
            /* I2C configuration */
            I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//設(shè)置 I2C為 I2C模式
            I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//I2C快速模式 Tlow / Thigh = 2

            I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;//設(shè)置第一個(gè)設(shè)備地址
            I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能應(yīng)答
            I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//應(yīng)答 7位地址
            I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;//設(shè)置時(shí)鐘頻率
            /* I2C Peripheral Enable */
            I2C_Cmd(I2C1, ENABLE);//使能I2C外設(shè)
            /* 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()
            {
            /* I2C configuration */
            I2C_Configuration();

            /* 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 : EEPROMs internal address to write to.
            * - NumByteToWrite : number of bytes to write to the EEPROM.
            * Output : None
            * Return : None
            pBuffer:指向要寫入數(shù)據(jù)數(shù)組的指針
            WriteAddr:24c02中要寫入數(shù)據(jù)的首地址
            NumByteToWrite:寫入的字節(jié)數(shù)
            *******************************************************************************/
            void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)//將緩沖器的數(shù)據(jù)寫入EEPROM
            {
            u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

            Addr = WriteAddr % I2C_PageSize;//寫入地址是每頁的第幾位
            count = I2C_PageSize - Addr;//在開始的一頁要寫入的個(gè)數(shù)
            NumOfPage = NumByteToWrite / I2C_PageSize;//要寫入的頁數(shù)
            NumOfSingle = NumByteToWrite % I2C_PageSize;//不足一頁的個(gè)數(shù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            /* If WriteAddr is I2C_PageSize aligned */
            if(Addr == 0) //寫入地址是頁的開始
            {
            /* If NumByteToWrite < I2C_PageSize */
            if(NumOfPage == 0) //數(shù)據(jù)小于一頁
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//寫少于一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            }
            /* If NumByteToWrite > I2C_PageSize */
            else //數(shù)據(jù)大于等于一頁
            {
            while(NumOfPage--)//要寫入的頁數(shù)
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); //寫一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            WriteAddr += I2C_PageSize;
            pBuffer += I2C_PageSize;
            }

            if(NumOfSingle!=0)//剩余數(shù)據(jù)小于一頁
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//寫少于一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            }
            }
            }
            /* If WriteAddr is not I2C_PageSize aligned */
            else //寫入地址不是頁的開始
            {
            /* If NumByteToWrite < I2C_PageSize */
            if(NumOfPage== 0) //數(shù)據(jù)小于一頁
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);//寫少于一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            }
            /* If NumByteToWrite > I2C_PageSize */
            else//數(shù)據(jù)大于等于一頁
            {
            NumByteToWrite -= count;
            NumOfPage = NumByteToWrite / I2C_PageSize; //重新計(jì)算要寫入的頁數(shù)
            NumOfSingle = NumByteToWrite % I2C_PageSize;//重新計(jì)算不足一頁的個(gè)數(shù)

            if(count != 0)//在此處count一定不為0,此判斷條件好象有點(diǎn)多余
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, count);//將開始的空間寫滿一頁
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            WriteAddr += count;
            pBuffer += count;
            }

            while(NumOfPage--)//要寫入的頁數(shù)
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);//寫一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            WriteAddr += I2C_PageSize;
            pBuffer += I2C_PageSize;
            }
            if(NumOfSingle != 0)//剩余數(shù)據(jù)小于一頁
            {
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); //寫少于一頁的數(shù)據(jù)
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            }
            }
            }
            }

            /*******************************************************************************
            * 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 : EEPROMs internal address to write to.
            * Output : None
            * Return : None
            pBuffer:指向要寫入數(shù)據(jù)數(shù)組的指針
            WriteAddr:24c02中要寫入數(shù)據(jù)的首地址
            *******************************************************************************/
            void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)//寫一個(gè)字節(jié)到EEPROM
            {
            /* Send STRAT condition */
            I2C_GenerateSTART(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 START條件

            /* Test on EV5 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //檢查最近一次 I2C事件是否是輸入的事件

            /* Send EEPROM address for write */
            I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的從 I2C設(shè)備傳送地址字,選擇發(fā)送方向
            /* Test on EV6 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//檢查最近一次 I2C事件是否是輸入的事件

            /* Send the EEPROMs internal address to write to */
            I2C_SendData(I2C1, WriteAddr);//通過外設(shè) I2Cx發(fā)送地址
            /* Test on EV8 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//檢查最近一次 I2C事件是否是輸入的事件

            /* Send the byte to be written */
            I2C_SendData(I2C1, *pBuffer); //通過外設(shè) I2Cx發(fā)送數(shù)據(jù)

            /* Test on EV8 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//檢查最近一次 I2C事件是否是輸入的事件
            /* Send STOP condition */
            I2C_GenerateSTOP(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 STOP條件
            }

            /*******************************************************************************
            * Function Name : I2C_EE_PageWrite
            * Description : Writes more than one byte to the EEPROM with a single WRITE
            * cycle. The number of byte cant exceed the EEPROM page size.
            * Input : - pBuffer : pointer to the buffer containing the data to be
            * written to the EEPROM.
            * - WriteAddr : EEPROMs internal address to write to.
            * - NumByteToWrite : number of bytes to write to the EEPROM.
            * Output : None
            * Return : None
            pBuffer:指向要寫入數(shù)據(jù)數(shù)組的指針
            WriteAddr:24c02中要寫入數(shù)據(jù)的首地址
            NumByteToWrite:寫入的字節(jié)數(shù)
            *******************************************************************************/
            void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)//寫少于一頁的數(shù)據(jù)
            {
            /* Send START condition */
            I2C_GenerateSTART(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 START條件
            /* Test on EV5 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //檢查最近一次 I2C事件是否是輸入的事件
            /* Send EEPROM address for write */
            I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的從 I2C設(shè)備傳送地址字,選擇發(fā)送方向

            /* Test on EV6 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //檢查最近一次 I2C事件是否是輸入的事件

            /* Send the EEPROMs internal address to write to */
            I2C_SendData(I2C1, WriteAddr); //通過外設(shè) I2Cx發(fā)送地址

            /* Test on EV8 and clear it */
            while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //檢查最近一次 I2C事件是否是輸入的事件

            /* While there is data to be written */
            while(NumByteToWrite--)
            {
            /* Send the current byte */
            I2C_SendData(I2C1, *pBuffer); //通過外設(shè) I2Cx發(fā)送數(shù)據(jù)

            /* Point to the next byte to be written */
            pBuffer++;
            /* Test on EV8 and clear it */
            while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//檢查最近一次 I2C事件是否是輸入的事件
            }

            /* Send STOP condition */
            I2C_GenerateSTOP(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 STOP條件
            }

            /*******************************************************************************
            * 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 : EEPROMs internal address to read from.
            * - NumByteToRead : number of bytes to read from the EEPROM.
            * Output : None
            * Return : None
            pBuffer:指向要保存讀出數(shù)據(jù)的數(shù)組的指針
            ReadAddr:24c02中要讀出數(shù)據(jù)的首地址
            NumByteToRead:讀出的字節(jié)數(shù)
            *******************************************************************************/
            void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)//將EEPROM的數(shù)據(jù)讀入緩沖器
            {
            I2C_EE_WaitEepromStandbyState();//EEPROM設(shè)為待命狀態(tài)
            /* Send START condition */
            I2C_GenerateSTART(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 START條件
            /* Test on EV5 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//檢查最近一次 I2C事件是否是輸入的事件
            /* In the case of a single data transfer disable ACK before reading the data */
            if(NumByteToRead==1)
            {
            I2C_AcknowledgeConfig(I2C1, DISABLE);//使能或者失能指定 I2C的應(yīng)答功能
            }
            /* Send EEPROM address for write */
            I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的從 I2C設(shè)備傳送地址字,選擇發(fā)送方向

            /* Test on EV6 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//檢查最近一次 I2C事件是否是輸入的事件
            /* Clear EV6 by setting again the PE bit */
            I2C_Cmd(I2C1, ENABLE);//使能或者失能 I2C外設(shè)

            /* Send the EEPROMs internal address to write to */
            I2C_SendData(I2C1, ReadAddr); //通過外設(shè) I2Cx發(fā)送地址

            /* Test on EV8 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//檢查最近一次 I2C事件是否是輸入的事件
            /* Send STRAT condition a second time */
            I2C_GenerateSTART(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 START條件
            /* Test on EV5 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//檢查最近一次 I2C事件是否是輸入的事件
            /* Send EEPROM address for read */
            I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);//向指定的從 I2C設(shè)備傳送地址字,選擇接收方向
            /* Test on EV6 and clear it */
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//檢查最近一次 I2C事件是否是輸入的事件
            /* While there is data to be read */
            while(NumByteToRead)
            {
            /* Test on EV7 and clear it */
            if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) //檢查最近一次 I2C事件是否是輸入的事件
            {
            if(NumByteToRead == 2)
            {
            /* Disable Acknowledgement */
            I2C_AcknowledgeConfig(I2C1, DISABLE);//使能或者失能指定 I2C的應(yīng)答功能
            }

            if(NumByteToRead == 1)
            {
            /* Send STOP Condition */
            I2C_GenerateSTOP(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 STOP條件
            }

            /* Read a byte from the EEPROM */
            *pBuffer = I2C_ReceiveData(I2C1);//返回通過 I2Cx最近接收的數(shù)據(jù)

            /* 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);//使能或者失能指定 I2C的應(yīng)答功能
            }

            /*******************************************************************************
            * Function Name : I2C_EE_WaitEepromStandbyState
            * Description : Wait for EEPROM Standby state
            * Input : None
            * Output : None
            * Return : None
            *******************************************************************************/
            void I2C_EE_WaitEepromStandbyState(void) //EEPROM設(shè)為待命狀態(tài)
            {
            vu16 SR1_Tmp = 0;

            do
            {
            /* Send START condition */
            I2C_GenerateSTART(I2C1, ENABLE);//產(chǎn)生 I2Cx傳輸 START條件
            /* Read I2C1 SR1 register */
            SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);//讀取指定的 I2C寄存器 I2C_SR1 并返回其值
            /* Send EEPROM address for write */
            I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);//向指定的從 I2C設(shè)備傳送地址字 ,選擇發(fā)送方向
            }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));//地址發(fā)送結(jié)束
            /* Clear AF flag */
            I2C_ClearFlag(I2C1, I2C_FLAG_AF);//清除 I2Cx的應(yīng)答錯(cuò)誤標(biāo)志位




            關(guān)鍵詞: STM32I2CEEPRO

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉