Home > other >  STM32F103 hardware IIC completely solve busy deadlock + return + overtime without interrupting the h
STM32F103 hardware IIC completely solve busy deadlock + return + overtime without interrupting the h

Time:09-16

Directly register operation, completely solve the problem, effective measurement,


# include "IIC_2. H"
# include "DELAY. H"
///* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
//busy a deadlock problem, but be careful, there is no timeout mechanism - equal to cannot guarantee multi-master handling stability

Qualitative
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Void IS_BUSY (void)
{
u8 i;
While ((I2C2 - & gt; SR2 & amp; (1 & lt; <1)).=0)//bus BUSY BUSY!=0 is circular wait here

{
RCC - & gt; APB2ENR |=1 & lt; <3;//PORTB clock can make
//here only for initialization IIC2 pin
GPIOB - & gt; CRH&=0 xffff00ff;
GPIOB - & gt; CRH |=0 x00007700;//PB10 - SCK PB11 - SDA IO open drain output zero x77
For (I=0; I<10; I++)
{
PBout (10)=~ PBout (10);//BUSY solving the deadlock problem
Delay_us (20);
}

PCout (13)=~ PCout (13);//the led flash up
IIC_init ();

}



}


Void IIC_init (void)
{

RCC - & gt; APB1ENR |=1 & lt; <22.//hardware IIC2 clock can make
//note!!!!! AFIO clock, there is no open, only operating

IO remapping AF (reuse), AFIO clock need to open, not belong to the ordinary IO clock management,
RCC - & gt; APB2ENR |=1 & lt; <3;//PORTB clock can make
//here only for initialization IIC2 pin
GPIOB - & gt; CRH&=0 xffff00ff;
GPIOB - & gt; CRH |=0 x0000ff00;//PB10 - SCK PB11 - SDA all need open leak multiplexing output

0 xf

//here is IIC2 register configuration

RCC - & gt; APB1RSTR |=1 & lt; <22.//reset IIC2 register
RCC - & gt; APB1RSTR & amp;=~ (1 & lt; <22);//stop reset IIC2 register


I2C2 - & gt; CR1 |=1 & lt; <15.//reset IIC2
I2C2 - & gt; CR1 & amp;=~ (1 & lt; <15);
Delay_us (5);

I2C2 - & gt; CR1 & amp;=~ (1 & lt; <1);//a 0 bit - 1: I2C pattern 1: SMBus mode - configuration for IIC module

Type,
I2C2 - & gt; CR1 |=1 & lt; <10;//bit - 10 0: no answer back 1: accept to return after a byte

Back a response (matching the address or data)

//I2C2 - & gt; CR2 |=1 & lt; <10;//bit - 10 - buffer interrupts enabled
//I2C2 - & gt; CR2 |=1 & lt; <9.//bit - nine - event interrupts enabled
I2C2 - & gt; CR2 |=1 & lt; <8;//bit - 8 - error interrupts enabled
I2C2 - & gt; CR2 |=0 x24;//bit - 5-0 position - configured as input clock 36 m,

I2C2 - & gt; OAR1 & amp;=~ (1 & lt; <15);//bit - 15 0:7 bits from address 1:10 bits from address -- -- --

Configured to seven from address,
I2C2 - & gt; OAR1 |=1 & lt; <14.//bit - 14 - software requirements must keep
'1'I2C2 - & gt; OAR1 |=0 x00;//bit - 7:1 bit - seven from the mode of address to 0 x00 - receive

The host signal using

I2C2 - & gt; OAR2 & amp;=~ (1);//bit 0 bit 0:7 bit address pattern recognition OAR1 1:7 who only

Mode recognition OAR1-2 double address - seven pattern recognition only OAR1,

I2C2 - & gt; The CCR |=1 & lt; <15.//bit - 15 - configuration for rapid mode of IIC 400 KHZ -

All the configuration register is best in CR1 PE can make a closed set,
I2C2 - & gt; CCR&=~ (1 & lt; <14);//bit - 14 - fast mode of duty ratio is set to 2:1
I2C2 - & gt; The CCR |=0 x1f;//bit - 11:0 - configuration for rapid mode of IIC CCR for

0 x1f=31. 31, 2 * * ns + 1 * 31 * 27 ns=2511 ns one cycle, 398.24771 kHZ to 400 kHZ

I2C2 - & gt; TRISE=0 xc. Configuration//bit - 5-0 position - the biggest rise time of 324 ns


///* * * * * * * * * * * * * * IIC2 NVIC interrupt priority level configuration * * * * * * * * * * * * * * * * * * * * * * * * */

//can make fault interrupt

NVIC_Init (0, 0, I2C2_ER_IRQn, 2);//in group 2, the highest level - first group cannot change

I2C2 - & gt; CR1 |=1;//bit 0 -- all configuration registers configuration is in order after opening a PE - enabling IIC2

Delay_us (5);

}

# define a TimeOut 1000

Void I2C_SingleWrite (uint8_t address, uint8_t subAddress, uint8_t data)
{
Under-16 SR2_STATE=0, I=0;

IS_BUSY ();

I2C2 - & gt; CR1 |=1 & lt; <8;//START producing starting conditions=1;
I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; X0001 (0))!=0 x0001) {if (I==0) {I2C2 - & gt; CR1 |

=1 & lt; <9. return; } the else I -; }//SB=1 starting conditions has hair - read SR1 + write DR can clear

In addition,//IIC_Start ();

I2C2 - & gt; DR=((address<1) | 0);

//IIC_Send_Byte ((address<1) | 0);//sending device address + write command

I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; X0002 (0))!={0 x0002) if (I==0) {I2C2 -

CR1 |=1 & lt; <9. return; } the else I -; }//waiting for the address to send success, ADDR=1 represents the address to send success,

Received from the machine after completing an ACK receiving address setting 1//IIC_Wait_Ack ();//wait reply


SR2_STATE=I2C2 - & gt; SR2.//read SR1 - read - SR2 ADDR,
SR2_STATE=SR2_STATE;
/* note that the manual says TxE won't be set on the sending address phase, so here TxE=0, not through the

Judge TxE=1 to confirm the receipt of ACK */

I2C2 - & gt; DR=subAddress;//the first DATA, this time a write DR immediately move into

A register, TxE or 1//IIC_Send_Byte (subAddress);//write register address -

DATA1

I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; X0080 (0))!=0 x0080) {if (I==0) {I2C2 - & gt; CR1 |

=1 & lt; <9. return; } the else I -; }//here waiting TxE=1 is to judge whether the DR is empty,

//IIC_Wait_Ack ();//wait reply

I2C2 - & gt; DR=data;//send data -- if not consider a continuous write two DR under test,

I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; X0084 (0))!=0 x0084) {if (I==0) {I2C2 - & gt; CR1 |

=1 & lt; <9. return; } the else I -; }//TxE=1 and BTF=1 data register empty - shift register is empty

//IIC_Wait_Ack ();//wait reply

I2C2 - & gt; CR1 |=1 & lt; <9.//STOP condition STOP=1;

}


Void I2C_MultipleRead (uint8_t address, uint8_t subAddress, uint8_t *

Pbufs, uint8_t len)
{
Under-16 SR2_STATE=0, I=0;

IS_BUSY ();

I2C2 - & gt; CR1 |=1 & lt; <8;//START producing starting conditions=1;
I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; X0001 (0))!={0 x0001) if (I==0) {I2C2 -

CR1 |=1 & lt; <9. return; } the else I -; }//SB=1 starting conditions has hair - read SR1 + write DR can clear

In addition,//IIC_Start ();

I2C2 - & gt; DR=((address<1) | 0);

//IIC_Send_Byte ((address<1) | 0);//sending device address + write command

I=the TimeOut; While ((I2C2 - & gt; SR1 & amp; nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related