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