新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32開發板- I2C--24Cxx

        STM32開發板- I2C--24Cxx

        作者: 時間:2016-11-27 來源:網絡 收藏
        我們所用來示范的24Cxx系列是最常用的EEPROM芯片。
        前面提到了一個地址碼,
        24Cxx的地址碼是固定的,
        8位如下:
        1010A2 A1 A00
        A2 A1 A0分別是它三個管腳的電平

        24Cxx 理解起來有一個特別之處。
        24Cxx 包括 01/02/04/08/16 四種,容量關系剛好和數字一樣。1K 2K 4K 8K 16K
        24C02 最為常見, 它的三個地址管腳A2 A1 A0都是可用的,
        A2 A1 A0 有8中電平組合,也就是說,可以有8個 24C02 掛載同一個I2C總線上。
        24C04呢, A0管腳就失效了,只有A2 和 A1 有用,四種組合,最多有4個24C04在總線上,
        以此類推。24C16只能有一個在總線上。
        這里就不好理解了,為什么要這樣呢。
        事實是一片 24C16 == 8片24C02 總線掛到一起。A2 A1 A0雖然起不到設置作用了,但你使用地址碼還是會訪問到特定的區域。
        明白了吧。所以其實24C系列的代碼是通用的。
        地址碼也是固定的。就是 0xA0 0xA2 0xA4 0xA6 0xA8 0xAA 0xAC 0xAE
        好,我們以24C16為范例吧。

        本文引用地址:http://www.104case.com/article/201611/322417.htm

        IO設置在I2C1上,無Remap,復用開漏輸出。I2C 總線是掛4.7k電阻上拉到高電平的。
        //-----------------------I2C--------------------------------------------

        GPIO_InitStruct.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;//復用開漏輸出
        GPIO_Init(GPIOB, &GPIO_InitStruct);

        I2C init函數:

        void i2c_24c_init(I2C_TypeDef *I2Cx)
        {
        I2C_InitTypeDef I2C_InitStruct;

        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;// I2C模式
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;// ACK 在通訊中常見,握手包,即發送到了一個數據,接收方回一句,我收到鳥。
        I2C_InitStruct.I2C_ClockSpeed = I2C_Speed;// I2C 速度設置,一般是40KHZ,400KHZ是極限,一般到不了那么高
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;//快速模式下的選項,這里先不講,100KHZ以上才有用
        I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//應答地址碼長度,7位或者10位,24C是7位

        // EEprom Block Select;
        I2C_InitStruct.I2C_OwnAddress1 = I2C_Slave_Adress7;//第一個設備自身地址

        I2C_Cmd(I2Cx,ENABLE);//開啟I2C

        I2C_Init(I2Cx,&I2C_InitStruct);//將剛剛的設置送進去
        }

        注意:現在的片子一般都不止一個I2C。所以用了上述模式,請詳細看注釋。

        寫一個字節進EEPROM:
        參數解釋:Byte待寫的字節,WriteAddr預計寫入的地址,ByteToWrite寫多少給字節,EE24cBlockSelect選擇EEPROM相應的區域(I2C地址),*I2Cx,I2C設備指針
        void i2c_24c_byte_write(unsigned char Byte, unsigned char WriteAddr, unsigned int ByteToWrite, unsigned char EE24cBlockSelect,I2C_TypeDef *I2Cx)
        {
        // Start the I2C
        I2C_GenerateSTART(I2Cx,ENABLE); //打開I2C,開始發送過程

        //not recommanded, stupid way
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));//設置主機模式

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter); //發送片選,選擇哪一片區域寫。i2C地址區分

        // when get ACK, means Set Success
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //等待這次選擇過程完成

        I2C_SendData(I2Cx, WriteAddr);//發送要寫入的地址碼

        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待字節發送完成

        I2C_SendData(I2Cx, Byte); //發送要寫的字節

        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待直到字節發送完成

        I2C_GenerateSTOP(I2Cx, ENABLE); //發送過程結束。
        }

        讀EEPROM函數類似,卻稍微復雜。
        參數說明:pBuffer接收I2C數據的緩沖區,Addr讀的地址,NumToRead讀多少個字節,ee24cblockselect讀哪個區域,I2Cx i2c設備指針
        void i2c_24c_buffer_read(unsigned char *pBuffer, unsigned char Addr,unsigned char NumToRead,unsigned char EE24cBlockSelect, I2C_TypeDef *I2Cx)
        {
        //open I2C
        I2C_GenerateSTART(I2Cx, ENABLE);//開始發送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))); //設置自己為主機

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter);//設置自己為發送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))); //等待主機發送模式設置成功

        I2C_Cmd(I2Cx,ENABLE);//使能I2C

        I2C_SendData(I2Cx, Addr); //發送地址碼,即要讀的地址

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)));//等待主機發送過程完成

        I2C_GenerateSTART(I2Cx, ENABLE); //I2C開始發送

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));//設置主機模式

        I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Receiver);//設置從機地址,并設置主機為接收模式

        while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))); //確認該過程完成

        while(NumToRead)
        {
        if(NumToRead==1)
        {
        I2C_AcknowledgeConfig(I2Cx, DISABLE);//關閉I2C的應答功能

        I2C_GenerateSTOP(I2Cx, ENABLE); //發送結束信息
        }

        if((I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)))//如果接收到信息了
        {
        *pBuffer = I2C_ReceiveData(I2Cx);//把接收到的數據 填進緩沖區當中

        pBuffer++;

        NumToRead--;
        }
        }

        I2C_AcknowledgeConfig(I2Cx, ENABLE);//開啟主機I2C的應答功能

        }

        在寫i2C和讀i2C之間要插入下面函數等待,否則會有問題

        I2C_EE_WaitEepromStandbyState();



        關鍵詞: STM32I2C24Cx

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 偃师市| 江油市| 墨玉县| 仁化县| 富源县| 武汉市| 伊吾县| 新安县| 九寨沟县| 闸北区| 广丰县| 盐津县| 思茅市| 阿拉尔市| 长沙市| 清丰县| 吴江市| 中方县| 邹城市| 怀集县| 古丈县| 阜阳市| 江西省| 南投市| 海丰县| 凌源市| 榆林市| 梧州市| 佳木斯市| 陵水| 建湖县| 南宫市| 增城市| 天峻县| 福建省| 白玉县| 和静县| 巨鹿县| 启东市| 漳浦县| 东至县|