在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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) > 設計應用 > STM32 的I2C 硬使用

            STM32 的I2C 硬使用

            作者: 時間:2016-12-03 來源:網絡 收藏
            /*

            操作對象為一24C02
            */

            本文引用地址:http://www.biyoush.com/article/201612/325216.htm

            #include "STM32Lib\stm32f10x.h"
            #include "hal.h"

            //#define AT24C01A//24C01A,I2C時序和往后的24C02一樣
            #define AT24C01//24C01,I2C的時序和普通的有點不同

            #define EEPROM_ADDR0xA0
            #define I2C_PAGESIZE4//24C01/01A頁緩沖是4個


            void I2C_Configuration(void)
            {
            I2C_InitTypeDef I2C_InitStructure;
            GPIO_InitTypeDef GPIO_InitStructure;

            RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);

            /* PB6,7 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);

            I2C_DeInit(I2C1);
            I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
            I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
            I2C_InitStructure.I2C_OwnAddress1 = 0x30;
            I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
            I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
            I2C_InitStructure.I2C_ClockSpeed = 100000;//100K速度

            I2C_Cmd(I2C1, ENABLE);
            I2C_Init(I2C1, &I2C_InitStructure);
            /*允許1字節(jié)1應答模式*/
            I2C_AcknowledgeConfig(I2C1, ENABLE);

            }

            /***************************************************
            **函數名:I2C_ReadS
            **功能:讀取24C02多個字節(jié)
            **注意事項:24C02是256字節(jié),8位地址,A0-A2固定為0,從器件地址為EEPROM_ADDR
            ***************************************************/
            void I2C_ReadS_24C(u8 addr ,u8* pBuffer,u16 no)
            {
            if(no==0)
            return;

            while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

            /*允許1字節(jié)1應答模式*/
            I2C_AcknowledgeConfig(I2C1, ENABLE);


            /* 發(fā)送起始位 */
            I2C_GenerateSTART(I2C1, ENABLE);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

            #ifdef AT24C01A
            /*發(fā)送器件地址(寫)*/
            I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
            while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

            /*發(fā)送地址*/
            I2C_SendData(I2C1, addr);
            while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*數據已發(fā)送*/

            /*起始位*/
            I2C_GenerateSTART(I2C1, ENABLE);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

            /*器件讀*/
            I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


            #else
            /*發(fā)送器件地址(讀)24C01*/
            I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
            #endif

            while (no)
            {
            if(no==1)
            {
            I2C_AcknowledgeConfig(I2C1, DISABLE);//最后一位后要關閉應答的
            I2C_GenerateSTOP(I2C1, ENABLE);//發(fā)送停止位
            }

            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
            *pBuffer = I2C_ReceiveData(I2C1);
            pBuffer++;
            /* Decrement the read bytes counter */
            no--;
            }
            //再次允許應答模式
            I2C_AcknowledgeConfig(I2C1, ENABLE);
            }

            /****************************************************
            **函數名:I2C_Standby_24C
            **功能:24C是否準備好再寫入的判斷
            **注意事項:本函數可以理解為:判忙
            就是不停發(fā)地址 直到器件有應答
            ****************************************************/
            void I2C_Standby_24C(void)
            {
            vu16 SR1_Tmp;
            do
            {
            /*起始位*/
            I2C_GenerateSTART(I2C1, ENABLE);
            /*讀SR1*/
            SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
            /*器件地址(寫)*/
            #ifdef AT24C01A
            I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
            #else
            I2C_Send7bitAddress(I2C1, 0, I2C_Direction_Transmitter);
            #endif
            }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

            /*清除應答錯誤標志*/
            I2C_ClearFlag(I2C1, I2C_FLAG_AF);
            /*停止位*/
            I2C_GenerateSTOP(I2C1, ENABLE);
            }

            /*************************************************
            **函數名:I2C_ByteWrite_24C
            **功能:寫一個字節(jié)
            **注意事項:字寫入同樣需要調用忙判斷
            *************************************************/
            void I2C_ByteWrite_24C(u8 addr,u8 dat)
            {
            /* 起始位 */
            I2C_GenerateSTART(I2C1, ENABLE);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

            #ifdef AT24C01A
            /* 發(fā)送器件地址(寫)*/
            I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

            /*發(fā)送地址*/
            I2C_SendData(I2C1, addr);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

            #else
            I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
            #endif

            /* 寫一個字節(jié)*/
            I2C_SendData(I2C1, dat);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

            /* 停止位*/
            I2C_GenerateSTOP(I2C1, ENABLE);

            I2C_Standby_24C();
            }

            /*************************************************
            **函數名:I2C_PageWrite_24C
            **功能:寫入一頁(以內)
            **注意事項:此函數供群寫入調用
            *************************************************/
            void I2C_PageWrite_24C(u8 addr,u8* pBuffer, u8 no)
            {
            while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

            /*起始位*/
            I2C_GenerateSTART(I2C1, ENABLE);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

            #ifdef AT24C01A
            /*器件地址(寫)*/
            I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

            /*寫地址值*/
            I2C_SendData(I2C1, addr);
            while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

            #else
            I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
            #endif
            while(no--)
            {
            I2C_SendData(I2C1, *pBuffer);
            pBuffer++;
            while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
            }

            /*停止位*/
            I2C_GenerateSTOP(I2C1, ENABLE);
            }

            /*************************************************
            **函數名:I2C_WriteS_24C
            **功能:頁寫入24C
            **注意事項:24C02最多允許一次寫入8個字節(jié)
            *************************************************/
            void I2C_WriteS_24C(u8 addr,u8* pBuffer, u16 no)
            {
            u8 temp;

            //1.先把頁不對齊的部分寫入
            temp=addr % I2C_PAGESIZE;
            if(temp)
            {
            temp=I2C_PAGESIZE-temp;
            I2C_PageWrite_24C(addr,pBuffer, temp);
            no-=temp;
            addr+=temp;
            pBuffer+=temp;
            I2C_Standby_24C();
            }
            //2.從頁對齊開始寫
            while(no)
            {
            if(no>=I2C_PAGESIZE)
            {
            I2C_PageWrite_24C(addr,pBuffer, I2C_PAGESIZE);
            no-=I2C_PAGESIZE;
            addr+=I2C_PAGESIZE;
            pBuffer+=I2C_PAGESIZE;
            I2C_Standby_24C();
            }
            else
            {
            I2C_PageWrite_24C(addr,pBuffer, no);
            no=0;
            I2C_Standby_24C();
            }
            }
            }


            //測試用
            void I2C_Test(void)
            {
            u8 i;
            u8 I2c_Buf[128];

            I2C_Standby_24C();

            //填充緩沖
            for(i=0;i<128;i++)
            I2c_Buf[i]=i;

            //寫
            I2C_WriteS_24C(1,I2c_Buf,120);

            //清緩沖
            for(i=0;i<128;i++)
            I2c_Buf[i]=0;

            //讀
            I2C_ReadS_24C(1,I2c_Buf,80);

            for(i=1;i<120;i++)
            {
            if(I2c_Buf[i]!=i)
            {
            while(1);
            }
            }

            }

            就看這里 確定是否正常~!

            其實 都是 while 這種 硬等待 導致屢次調不通 務必加入 超時判斷。

            簡單的像

            i=0;

            while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))&&i<12000);i++



            關鍵詞: STM32I2C硬使

            評論


            技術專區(qū)

            關閉