Forum: Mikrocontroller und Digitale Elektronik Problem mit ISR I2C Slave STM32


von DSP (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

möchte gerne einen STM32F407 als SMBus-Slave nutzen.

Nutze dazu die StdPeriph Driver.

Aus irgendeinem Grund funktioniert meine ISR nicht so wie sie sollte.
Auf der Leitung sieht alles richtig aus.
Sende mit einem Arduino Mirco(Master) die Addresse, 0xFF, 0x33,0XAA

Ich Emfange nur die ersten beiden Bytes (0xFF, 0x33) und RxNE wird nicht 
reseted. Außerdem findet das Stop Event nicht statt, da im Status 
Register 0x00000050 steht.
1
void I2C3_EV_IRQHandler(void)
2
{
3
    uint32_t dwLastEvent;
4
    dwLastEvent = I2C_GetLastEvent(I2C3);
5
6
#ifdef DEBUG_STMSTUDIO
7
  CR1_DEBUG  = I2C_ReadRegister(I2C3, I2C_Register_CR1);    
8
  CR2_DEBUG  = I2C_ReadRegister(I2C3, I2C_Register_CR2);
9
  Event_DEBUG = dwLastEvent;
10
#endif
11
  switch(dwLastEvent)
12
  {
13
    /* Slave Receive ******************************************************/
14
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //EV1
15
          GPIO_WriteBit(GPIOD,LEDBlue_Pin,Bit_SET);
16
          
17
    
18
          break;
19
20
    case (I2C_EVENT_SLAVE_BYTE_RECEIVED | 0x0004) :             //EV2 + BTF
21
          //GPIO_WriteBit(GPIOD,LEDRed_Pin,Bit_SET);
22
          RxBuffer[ixRxBuffer] = I2C_ReceiveData(I2C3);
23
          ixRxBuffer++;
24
25
          
26
          break;
27
    
28
    case I2C_EVENT_SLAVE_STOP_DETECTED :                       //EV4
29
          
30
          I2C3->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_STOP);
31
          ixRxBuffer=0;
32
          ixTxBuffer=0;
33
          
34
          break;
35
    
36
    default:
37
          DefaultEvent_DEBUG = I2C_GetLastEvent(I2C3);        
38
          break;
39
40
  }

von aSma>> (Gast)


Lesenswert?

Die Häfte des Codes fehlt!

Schau einfach ins Reference Manual nach und debugge Scheritt für 
Schritt. Manchmal steht was auch in Errata drin. ST hat auch Appnotes 
zum i2c bus (googlen).

Mein Tipp: Nehme DMA.

von KeilBenutzer (Gast)


Lesenswert?

Hey,

du solltest dafür die HAL-Treiber von STM benutzen. Darin wird alles 
i.d.R. korrekt geregelt und du musst dann nur noch in der Call-Back 
deine eigenen Routinen einfügen.

Mit den HAL-Treibern, fängst du so korrekt den IT ab:
1
 void I2C3_EV_IRQHandler(void){
2
  
3
  HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);  
4
}
5
6
void I2C3_ER_IRQHandler(void){
7
  
8
  HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
9
}

Danach musst du nur noch die Call-Back nach deinem nutzen umbauen:
z.B. für korrekt gesendet:
1
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c){
2
3
/* User Code */
4
}
5
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c){
6
7
/* User Code */
8
}

von DSP (Gast)


Lesenswert?

Habe das Problem gelöst.

Warum auch immer, wurde das I2C_EVENT_SLAVE_BYTE_RECEIVED beim letzten 
zusendenen Byte nicht ausgelöst, da bevor erfassung des Events die Stop 
Condition da war.

Habe ein Eigenens EVENT gemacht was den Fall abdeckt:
1
    case (I2C_EVENT_LAST_BYTE_RECEIVED)  :      //0x00000050               //EVSelfmade last 
2
                                                            //Byte is combined with Stop-condition
3
          RxBuffer[ixRxBuffer] = I2C_ReceiveData(I2C3);
4
          ixRxBuffer++;
5
break;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.