stm32F103 simulates I2C read and write 24c02

Publisher:风轻迟Latest update time:2019-04-02 Source: eefocusKeywords:stm32F103 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

/*********File name: i2c_ee.h**********/


/* Define to prevent recursive inclusion ------------------------------------ */

#ifndef __I2C_EE_H

#define __I2C_EE_H


/* Includes ------------------------------------------------------------------*/

#include "stm32f10x.h"


/* Exported macro ------------------------------------------------------------*/

#define ADDR_24CXX        0xA0


#define SCLH         GPIOB->BSRR = GPIO_Pin_6

#define SCLL         GPIOB->BRR  = GPIO_Pin_6 

   

#define SDAH         GPIOB->BSRR = GPIO_Pin_7

#define SDAL         GPIOB->BRR  = GPIO_Pin_7


#define SCLread      GPIOB->IDR  & GPIO_Pin_6

#define SDAread      GPIOB->IDR  & GPIO_Pin_7


 


/* Exported functions ------------------------------------------------------- */

void I2C_EE_Init(void);

uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte);

uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte);



#endif /* __I2C_EE_H */


//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////


/*********File name: i2c_ee.c**********/


#include "i2c_ee.h"


enum ENUM_TWI_REPLY

{

TWI_NACK=0

,TWI_ACK=1

};


enum ENUM_TWI_BUS_STATE

{

TWI_READY=0

,TWI_BUS_BUSY=1

,TWI_BUS_ERROR=2

};



void I2C_EE_Init(void)

{

  GPIO_InitTypeDef  GPIO_InitStructure; 

  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  

  // 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_Out_OD;  

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  

}



void TWI_delay(void)

   uint8_t i=10; //i=10 delay 1.5us//The speed can be optimized here. After testing, it can still be written to the lowest 5

   while(i--); 

   

}

/**************************************************************************

Delay

ms: delay in milliseconds

CYCLECOUNTER / 72000000 

***************************************************************************/

void DelayMs(uint16_t ms)

{

 uint16_t iq0;

        uint16_t iq1;

 for(iq0 = ms; iq0 > 0; iq0--)

 {

  for(iq1 = 11998; iq1 > 0; iq1--); // ( (6*iq1+9)*iq0+15 ) / 72000000 

  

 }

}


uint8_t TWI_Start(void)

{

 SDAH;

 SCLH;

 TWI_delay();

 if(!SDAread)return TWI_BUS_BUSY; //If the SDA line is low, the bus is busy, exit

 SDAL;

 TWI_delay();

 if(SDAread) return TWI_BUS_ERROR; //If the SDA line is high, the bus is wrong and exit

 SCLL;

 TWI_delay();

 return TWI_READY;

}


/*void TWI_Stop(void)

{

 SCLL;

 TWI_delay();

 SDAL;

 TWI_delay();

 SCLH;

 TWI_delay();

 SDAH;

 TWI_delay();

}*/

void TWI_Stop(void)

{

 SDAL;

 SCLL;

 TWI_delay();

 SCLH;

 TWI_delay();

 SDAH;

 TWI_delay();

}


void TWI_Ack(void)

 SCLL;

 TWI_delay();

 SDAL;

 TWI_delay();

 SCLH;

 TWI_delay();

 SCLL;

 TWI_delay();

}


void TWI_NoAck(void)

 SCLL;

 TWI_delay();

 SDAH;

 TWI_delay();

 SCLH;

 TWI_delay();

 SCLL;

 TWI_delay();

}


uint8_t TWI_WaitAck(void) //Return: =1 for ACK, =0 for no ACK

{

 SCLL;

 TWI_delay();

 SDAH;   

 TWI_delay();

 SCLH;

 TWI_delay();

 if(SDAread)

 {

          SCLL;

          return 0;

 }

 SCLL;

 return 1;

}


void TWI_SendByte(uint8_t SendByte) //Data from high to low //

{

    uint8_t i=8;

    while(i--)

    {

        SCLL;

        TWI_delay();

        if(SendByte&0x80)

          SDAH;  

        else 

        SDAL;   

        SendByte<<=1;

        TWI_delay();

        SCLH;

        TWI_delay();

    }

    SCLL;

}



uint8_t TWI_ReceiveByte(void) //Data from high to low //

    uint8_t i=8;

    uint8_t ReceiveByte=0;


    SDAH;    

    while(i--)

    {

      ReceiveByte <<= 1;      

      SCLL;

      TWI_delay();

      SCLH;

      TWI_delay(); 

      if(SDAread)

      {

        ReceiveByte |= 0x01;

      }

    }

    SCLL;

    return ReceiveByte;

}


//Return: 3 write successful; 0 write device address error, 1 bus busy, 2 error

//Write 1 byte of data SendByte: data to be written WriteAddress: address to be written 

uint8_t TWI_WriteByte(uint8_t SendByte, uint8_t WriteAddress)

{  

    uint8_t i;

 uint16_t j;

 i = TWI_Start();

    if(i)

   return i;

     

    TWI_SendByte( ADDR_24CXX & 0xFE); //Write device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1

    

 if(!TWI_WaitAck())

 {

   TWI_Stop(); 

   return 0;

 }

 

    TWI_SendByte(WriteAddress); //Set the starting address      

    TWI_WaitAck(); 

    TWI_SendByte(SendByte); //Write data

    TWI_WaitAck();   

    TWI_Stop(); 

 //Note: Because we need to wait for the EEPROM to finish writing, we can use the query or delay method (10ms)

    DelayMs(12); //Write delay 12ms Write cycle greater than 10ms

    return 3;

}


 


 


//Return: 0 error in writing device address, 1 bus busy, 2 error,

//Read 1 byte of data

//ReadAddress: address to be read 

uint8_t TWI_ReadByte( uint8_t ReadAddress)

{  

    uint8_t i,temp;

    i = TWI_Start();

    if(i)

   return i;

     

    TWI_SendByte((ADDR_24CXX & 0xFE)); //Write the device address and perform a dummy write operation first 

    if(!TWI_WaitAck())

 {

   TWI_Stop(); 

   return 0;

 }


    TWI_SendByte(ReadAddress); //Set the starting address      

    TWI_WaitAck();

    TWI_Start();

    TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //Read device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1

    TWI_WaitAck();

   

    //*pDat = TWI_ReceiveByte();

    temp = TWI_ReceiveByte();

    

    TWI_NoAck();

     

    TWI_Stop();

    return temp; // If the returned value is 0, 1, or 2, it is the same as the error code. Consider this again.

}


/***************************************************************************

Write multiple bytes to 24c256

psrc_data: pointer to the data array to be written

adr: the first address of the data to be written in 24c256

nbyte: The number of bytes written

Return value: 0: Execution completed; 1: Execution error occurred

In the formal parameters: C02 has only one address adr; C256 has a high address hadr and a low address ladr

***************************************************************************/

uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte)

{

   uint8_t i;

  

 for(;nbyte!=0;nbyte--)

 {

  i = TWI_Start();

        if(i)

     return i;

         

        TWI_SendByte( ADDR_24CXX & 0xFE); //Write device address 

    

     if(!TWI_WaitAck())

     {

       TWI_Stop(); 

       return 0;

     }

 

        TWI_SendByte(adr); //Set the starting address      

        TWI_WaitAck(); 

        TWI_SendByte(*psrc_data); //Write data

        TWI_WaitAck();   

        psrc_data++; //Pointer to the data to be written plus 1

  adr++; //Add 1 to the operation address of 24C08 

        TWI_Stop(); 

  //Note: Because we need to wait for the EEPROM to finish writing, we can use the query or delay method (10ms)

        DelayMs(12); //Write delay 12ms Write cycle greater than 10ms

        

 }

 return 0;

}



/***************************************************************************

Read multiple bytes from 24c02

pdin_data: pointer to the array where the read data is to be stored

adr: the first address of the data to be read in 24c02

nbyte: the number of bytes read

Return value: 0: Execution completed; 1: Execution error occurred

***************************************************************************/

uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte)

{

 uint8_t i;

    i = TWI_Start();

    if(i)

   return i;

     

    TWI_SendByte((ADDR_24CXX & 0xFE)); //Write the device address and perform a dummy write operation first 

    if(!TWI_WaitAck())

 {

   TWI_Stop(); 

   return 0;

 }


 TWI_SendByte(adr); //Set the starting address      

    TWI_WaitAck();

    TWI_Start();

    TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //Read device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1

    TWI_WaitAck();


 while(nbyte!=1) //Read the first (nbyte-1) bytes

 {

  *pdin_data = TWI_ReceiveByte(); //Loop to read data from 24C02 and store it in the memory pointed to by pdin_data

  TWI_Ack(); //IIC response

  pdin_data++; //Pointer to the memory where the read data is stored plus 1

  nbyte--; //The remaining bytes to be read minus 1

 };


 *pdin_data = TWI_ReceiveByte(); //Read the last byte

 TWI_NoAck(); //IIC no response operation

     

    TWI_Stop();   

 

 return 0;

}


/*

void TWI_24CXX_Write(uint8_t* pDat, uint8_t nAddr, uint8_t nLen)

{

  uint16_t i;

  for(i=0;i

  {

    TWI_WriteByte(*(pDat+i), nAddr+i);

    

   

  }

}


void TWI_24CXX_Read(uint8_t* pDat, uint8_t nAddr, uint8_t nLen)

{

    uint16_t i;

    for(i=0; i

      *(pDat+i) = TWI_ReadByte(nAddr+i);

}

*/


Keywords:stm32F103 Reference address:stm32F103 simulates I2C read and write 24c02

Previous article:Summary of the process of reading and writing EEPROM using I2C in STM32
Next article:STM32 GPIO and the first STM32 program (marquee)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号