新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 模擬I2C

        STM32 模擬I2C

        作者: 時間:2016-11-22 來源:網絡 收藏
        使用STM32來訪問I2C接口的鐵電存儲器,FM24CL16,2K字節
        =================================
        I2C的引腳配置:

        /*ConfigureI2C1pins:SCLandSDA*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        =================================
        /*******************************************************************************
        *FileName:i2c_fram.h
        *Author:MCDApplicationTeam
        *Version:V2.0.1
        *Date:06/13/2008
        *Description:Headerfori2c_ee.cmodule
        *******************************************************************************/
        /*Definetopreventrecursiveinclusion------------------------------------*/
        #ifndef__I2C_FRAM_H
        #define__I2C_FRAM_H

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

        /*Exportedtypes------------------------------------------------------------*/
        /*Exportedconstants--------------------------------------------------------*/


        /*Exportedmacro------------------------------------------------------------*/
        /*Exportedfunctions-------------------------------------------------------*/


        boolI2C_FRAM_BufferWrite(u8*pBuffer,u16WriteAddr,u16NumByteToWrite);
        boolI2C_FRAM_BufferRead(u8*pBuffer,u16ReadAddr,u16NumByteToRead);

        #endif/*__I2C_FRAM_H*/

        =================================
        /*******************************************************************************
        *FileName:i2c_fram.c
        *Author:Appcat
        *Version:V0.0.1
        *Date:07/11/2009
        *Description:Thisfileprovidesasetoffunctionsneededtomanagethe
        *communicationbetweenI2CperipheralandI2CFM24CL16FRAM.
        *******************************************************************************/

        /*Includes------------------------------------------------------------------*/
        #include"i2c_fram.h"

        /*Privatetypedef-----------------------------------------------------------*/
        /*Privatedefine------------------------------------------------------------*/
        #defineI2C_Speed100000
        #defineI2C1_SLAVE_ADDRESS70xA0
        #defineI2C_PageSize256

        #defineSCL_HGPIOB->BSRR=GPIO_Pin_6
        #defineSCL_LGPIOB->BRR=GPIO_Pin_6

        #defineSDA_HGPIOB->BSRR=GPIO_Pin_7
        #defineSDA_LGPIOB->BRR=GPIO_Pin_7

        #defineSCL_readGPIOB->IDR&GPIO_Pin_6
        #defineSDA_readGPIOB->IDR&GPIO_Pin_7


        /*Privatemacro-------------------------------------------------------------*/
        /*Privatevariables---------------------------------------------------------*/
        vu8FRAM_ADDRESS;

        /*Privatefunctionprototypes-----------------------------------------------*/

        /**/
        voidI2C_delay(void)
        {
        u8i=150;//這里可以優化速度 ,經測試最低到5還能寫入
        while(i)
        {
        i--;
        }
        }

        boolI2C_Start(void)
        {
        SDA_H;
        SCL_H;
        I2C_delay();
        if(!SDA_read)returnFALSE; //SDA線為低電平則總線忙,退出
        SDA_L;
        I2C_delay();
        if(SDA_read)returnFALSE; //SDA線為高電平則總線出錯,退出
        SDA_L;
        I2C_delay();
        returnTRUE;
        }

        voidI2C_Stop(void)
        {
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SDA_H;
        I2C_delay();
        }

        voidI2C_Ack(void)
        {
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
        }

        voidI2C_NoAck(void)
        {
        SCL_L;
        I2C_delay();
        SDA_H;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
        }

        boolI2C_WaitAck(void) //返回為:=1有ACK,=0無ACK
        {
        SCL_L;
        I2C_delay();
        SDA_H;
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
        SCL_L;
        returnFALSE;
        }
        SCL_L;
        returnTRUE;
        }

        voidI2C_SendByte(u8SendByte)//數據從高位到低位//
        {
        u8i=8;
        while(i--)
        {
        SCL_L;
        I2C_delay();
        if(SendByte&0x80)
        SDA_H;
        else
        SDA_L;
        SendByte<<=1;
        I2C_delay();
        SCL_H;
        I2C_delay();
        }
        SCL_L;
        }

        u8I2C_ReceiveByte(void)//數據從高位到低位//
        {
        u8i=8;
        u8ReceiveByte=0;

        SDA_H;
        while(i--)
        {
        ReceiveByte<<=1;
        SCL_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
        ReceiveByte|=0x01;
        }
        }
        SCL_L;
        returnReceiveByte;
        }

        boolI2C_FRAM_BufferWrite(u8*pBuffer,u16WriteAddr,u16NumByteToWrite)
        {
        u8Addr=0,count=0;

        Addr=WriteAddr/I2C_PageSize;

        count=WriteAddr%I2C_PageSize;

        Addr=Addr<<1;

        Addr=Addr&0x0F;

        FRAM_ADDRESS=I2C1_SLAVE_ADDRESS7|Addr;

        if(!I2C_Start())returnFALSE;
        I2C_SendByte(FRAM_ADDRESS);//設置器件地址+段地址
        if(!I2C_WaitAck())
        {
        I2C_Stop();
        returnFALSE;
        }
        I2C_SendByte(count);//設置段內地址
        I2C_WaitAck();

        while(NumByteToWrite--)
        {
        I2C_SendByte(*pBuffer);
        I2C_WaitAck();
        pBuffer++;
        }
        I2C_Stop();
        //注意:因為這里要等待EEPROM寫完,可以采用查詢或延時方式(10ms)
        //Systick_Delay_1ms(10);
        returnTRUE;
        }


        //讀出1串數據
        boolI2C_FRAM_BufferRead(u8*pBuffer,u16WriteAddr,u16NumByteToRead)
        {
        u8Addr=0,count=0;

        Addr=WriteAddr/I2C_PageSize;

        count=WriteAddr%I2C_PageSize;

        Addr=Addr<<1;

        Addr=Addr&0x0F;

        FRAM_ADDRESS=I2C1_SLAVE_ADDRESS7|Addr;

        if(!I2C_Start())returnFALSE;

        I2C_SendByte(FRAM_ADDRESS);//設置器件地址+段地址

        if(!I2C_WaitAck())
        {
        I2C_Stop();
        returnFALSE;
        }

        I2C_SendByte(count);//設置低起始地址
        I2C_WaitAck();
        I2C_Start();
        I2C_SendByte(FRAM_ADDRESS|0x01);
        I2C_WaitAck();
        while(NumByteToRead)
        {
        *pBuffer=I2C_ReceiveByte();
        if(NumByteToRead==1)I2C_NoAck();
        elseI2C_Ack();
        pBuffer++;
        NumByteToRead--;
        }
        I2C_Stop();
        returnTRUE;
        }

        =================================


        關鍵詞: STM32模擬I2

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 习水县| 陇川县| 耿马| 五寨县| 平湖市| 全椒县| 离岛区| 凤山市| 丰台区| 广宁县| 墨江| 中方县| 加查县| 金坛市| 德庆县| 林芝县| 库伦旗| 平遥县| 绥化市| 会同县| 钟祥市| 清新县| 德昌县| 会理县| 新宁县| 东明县| 长治市| 宜川县| 武定县| 道孚县| 明光市| 井陉县| 苍梧县| 广宗县| 金阳县| 衢州市| 平武县| 阿克陶县| 江油市| 丰县| 清丰县|