Recently, mainly in writing some STM32 on the development program, because the STM32 firmware library, I2C module is not good to use, so in the use of software simulation method to achieve.
The specific code is as follows (debugged under Keil):
#include "stm32f10x_lib.h"//Conditional Compilation 1: Use software to simulate I2C//#define PIN_SCL gpio_pin_6//#define PIN_SDA gpio_pin_7 static __inli ne void twi_scl_0 (void) {gpiob->brr=pin_scl;} static __inline void Twi_scl_1 (void) {GPIOB->BSRR=PIN_SCL;} stat IC __inline void twi_sda_0 (void) {gpiob->brr=pin_sda;} static __inline void twi_sda_1 (void) {Gpiob->bsrr=pin_
SDA;} Static __inline U8 twi_sda_state (void) {return (GPIOB->IDR & PIN_SDA)!= 0;}//static __inline void Twi_
NOP (void) {Twi_delay ();}
static const U8 Twi_ack = 0;
static const U8 Twi_ready = 0;
static const U8 Twi_nack = 1;
static const U8 Twi_bus_busy = 2;
static const U8 Twi_bus_error = 3; static const U8 Twi_retry_count = 3;
Retry count extern void Delay_ms (u32 n);
static void Twi_initialize (void);
static U8 Twi_start (void);
static U8 Twi_start_sht (void);
static void Twi_stop (void);
Static U8 Twi_sendbyte (U8 Data);
static U8 twi_receivebyte (void);
static void Twi_sendack (void); static void Twi_seNdnack (void);
/******************************************************************************* * Function Name: TWI_Delay
* Description: Delay function
* * Input: None
* Output: None
* Return: no * Author:
* Date Modified: June 8, 2010
/static void Twi_nop (void) {
Vu32 I, J;
Vu32 sum = 0;
i = 20;
while (i--) {for (j = 0; J <; J + +) sum = i;
sum = i; }
/****************** Function Name: twi_initialize
* Description: I2C initialization function
* * Input: None
* Output: None
* Return: no * Author:
* Date Modified: June 8, 2010
/static void twi_initialize (void)
{Gpio_inittypedef gpio_initstructure;
Gpio_initstructure.gpio_speed=gpio_speed_50mhz;
Gpio_initstructure.gpio_mode=gpio_mode_out_od; Gpio_iniTstructure.gpio_pin = PIN_SDA;
Gpio_init (Gpiob, &gpio_initstructure);
GPIO_INITSTRUCTURE.GPIO_MODE=GPIO_MODE_OUT_PP;
Gpio_initstructure.gpio_pin = PIN_SCL;
Gpio_init (Gpiob, &gpio_initstructure);
Twi_sda_1 ();
Twi_scl_0 ();
DebugPrint ("Software TWI initializing...\n");
}/******************************************************************************* * Function name: TWI_START
* Description: Send start
* * Input: None
* Output: None
* Return: no * Author: * Date Modified: June 8, 2010
***********************************************************************
/static U8 Twi_start (void) {twi_sda_1 ();
Twi_nop ();
Twi_scl_1 ();
Twi_nop (); if (!
Twi_sda_state ()) {////debugprint ("twi_start:busy\n");
return twi_bus_busy;
} twi_sda_0 ();
Twi_nop ();
Twi_scl_0 ();
Twi_nop ();
if (Twi_sda_state ()) {////debugprint ("Twi_start:bus error\n");
return twi_bus_error;
return twi_ready; }/*--------------------------------------------------------------------------//** * @Brief: Twi_start_sht * * @Returns: *//////*--------------------------------------------------------------------------/static U8 Twi_start_sht
(void)
{twi_sda_1 ();
Twi_scl_0 ();
Twi_nop ();
Twi_sda_1 ();
Twi_scl_1 ();
Twi_nop (); if (!
Twi_sda_state ()) {return twi_bus_busy;
} twi_sda_0 ();
Twi_nop ();
Twi_scl_0 ();
Twi_nop ();
Twi_scl_1 (); Twi_noP ();
Twi_sda_1 ();
Twi_nop ();
Twi_scl_0 ();
Twi_nop ();
return twi_ready; * * *--------------------------------------------------------------------------//** * @Brief: Twi_stop * * *-----
---------------------------------------------------------------------*/static void Twi_stop (void) {twi_sda_0 ();
Twi_nop ();
Twi_scl_1 ();
Twi_nop ();
Twi_sda_1 ();
Twi_nop ();
DebugPrint ("twi_stop\n"); }/*--------------------------------------------------------------------------//** * @Brief: Twi_sendack * *- ------------------------------------------------------------------------*/static void Twi_sendack (void) {Twi_sda_
0 ();
Twi_nop ();
Twi_scl_1 ();
Twi_nop ();
Twi_scl_0 ();
Twi_nop ();
Twi_sda_1 ();
DebugPrint ("twi_sendack\n"); * * *--------------------------------------------------------------------------//** * @Brief: twi_sendnack/*- -------------------------------------------------------------------------*/static void Twi_sendnack (void) {twi_sda_1 ();
Twi_nop ();
Twi_scl_1 ();
Twi_nop ();
Twi_scl_0 ();
Twi_nop ();
DebugPrint ("twi_sendnack\n"); }/*--------------------------------------------------------------------------//** * @Brief: Twi_sendbyte * * Param:data * * @Returns: *//*--------------------------------------------------------------------------/static
U8 Twi_sendbyte (U8 Data) {U8 i;
Twi_scl_0 ();
for (i=0;i<8;i++) {//---------data is established----------if (data&0x80) {twi_sda_1 ();
else {twi_sda_0 ();
} data<<=1;
Twi_nop ();
---data is established to maintain a certain delay----//----produce a rise along [positive pulse] twi_scl_1 ();
Twi_nop ();
Twi_scl_0 ();
TWI_NOP ()//delay to prevent the SCL from becoming low to change the SDA, resulting in start/stop signal//---------------------------}//Receiving response from the machine twi_sda_1 ();
Twi_nop ();
Twi_scl_1 ();
Twi_nop ();
if (Twi_sda_state ()) {twi_scl_0 ();
Twi_sda_1 ();
DebugPrint ("twi_nack!\n");
return twi_nack;
else {twi_scl_0 (); Twi_Sda_1 ();
DebugPrint ("twi_ack!\n");
return twi_ack;
}/*--------------------------------------------------------------------------//** * @Brief: Twi_receivebyte * * @Returns: *////--------------------------------------------------------------------------/static U8 Twi_rec
Eivebyte (void) {U8 i,dat;
Twi_sda_1 ();
Twi_scl_0 ();
dat=0;
for (i=0;i<8;i++) {twi_scl_1 ()//Generate clock rise along [positive pulse], let the data from the machine be ready to TWI_NOP ();
dat<<=1;
if (Twi_sda_state ())//Read pin state {dat|=0x01;
TWI_SCL_0 ()//ready to receive data again TWI_NOP ()/Wait for Data Ready}//////debugprint ("twi_dat:%x\n", Dat);
return Dat;
}