I2C Scanner mit einem STM32F0

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo,

Hat jemand von euch schon mal einen "I2C Scanner" mit dem oben genannten Prozessor realisiert?
Mit nem AVR würde es ja relativ zügig gehen.
 
Hat jemand von euch schon mal einen "I2C Scanner" mit dem oben genannten Prozessor realisiert?
Mit nem AVR würde es ja relativ zügig gehen.

Also wenn du eine Software in einer Hochspache für AVR Mikrocontroller "relativ zügig" hinbekommst, wäre die Portierung auf einen STM32 wahrscheinlich in den folgenden Bereichen notwendig ...
  • Initialisierung I2C Hardwaremodul oder direkt GPIO
  • Timermodul
  • Ausgabe (UART Modul, Display GPIO ...)
Das ist wahrscheinlich gar nicht so viel Arbeit.
 
Schreiben klappt ja schon wunderbar. Ich möchte einfach mal einen I2C Scanner Implementieren... Von der Funktion her, weiß ich wie ich es machen könnte, es geht jetzt viel mehr um die Hardware und die Register. Bei jeglichem Avr kann man ja direkt das Status Register auslesen und das ACK Bit auswerten bei dem Stm32 habe ich solch ein Bit noch nicht gefunden...
 
Hier ist übrigens mal die schreib Routine!



CodeBox C
uint8_t I2C_WrReg(I2C_TypeDef *I2Cx, uint8_t Addr, uint8_t Reg, uint8_t Val)
{
  uint32_t tme_out = 0;

   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY) == SET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 1;
  }
  }

   I2C_TransferHandling(I2Cx, Addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);

   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXIS) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 2;
  }
  }

   I2C_SendData(I2Cx, Reg);

   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TCR) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 3;
  }
  }

   I2C_TransferHandling(I2Cx, Addr, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);

   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_TXIS) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 4;
  }
  }

   I2C_SendData(I2Cx, Val);

   while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_STOPF) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 5;
  }
  }

   I2C_ClearFlag(I2Cx, I2C_FLAG_STOPF);

   //return SUCCESS;
}
 
Bei jeglichem Avr kann man ja direkt das Status Register auslesen und das ACK Bit auswerten bei dem Stm32 habe ich solch ein Bit noch nicht gefunden...
Obacht:
Du meinst nicht das Statusregister (SREG), sondern das TWSR (TWI Status Register), und dort die fünf TWS-Bits.

Ich habe mal kurz (!!) ins Datenblatt des STM32F0 geschaut (hab damit nie was gemacht...) - vielleicht hift Dir das
25.7.7 Interrupt and status register (I2C_ISR)
weiter??
Bit 4 NACKF: Not Acknowledge received flag This flag is set by hardware when a NACK is received after a byte transmission. It is cleared by software by setting the NACKCF bit. Note: This bit is cleared by hardware when PE=0.
 
Hallo LotadaC,

das Bit ist mir auch schon aufgefallen. Habe es auch schon versucht auszuwerten. Leider klappt das nicht (mache bestimmt was falsch!)
Muss ich, damit ich dieses Bit auswerten kann auch den Interrupt dafür aktivieren? Auf Seite 662 sieht man das Register mit dem entsprechenden Bit?!



CodeBox C
uint8_t I2C_ReReg(I2C_TypeDef *I2Cx, uint8_t Addr, uint8_t Reg)
{

  uint32_t tme_out = 0;
  uint8_t retByte = 0;

  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY) == SET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 1;
  }
  }

  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(I2Cx, Addr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);

  if(I2Cx->ISR & 0b00000000000000000000000000010000)
  {
  GPIO_WriteBit(GPIOC,(1<<9),Bit_SET);
  }

  while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 1;
  }
  }

  /* Send Register address */
  I2C_SendData(I2Cx, (uint8_t)Reg);

  if(I2Cx->ISR & 0b00000000000000000000000000010000)
  {
  GPIO_WriteBit(GPIOC,(1<<9),Bit_SET);
  }

  while(I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 2;
  }
  }

  /* Configure slave address, nbytes, reload, end mode and start or stop generation */
  I2C_TransferHandling(I2Cx, Addr, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);

  while(I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 3;
  }
  }

  /* Read data from RXDR */
  retByte = I2C_ReceiveData(I2Cx);

  /* Wait until STOPF flag is set */
  while(I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET)
  {
  if(tme_out++ > 800000)
  {
  tme_out = 0;
  return 4;
  }
  }

  /* Clear STOPF flag */
  I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);

  // return a Reg value
  return (uint8_t)retByte;
}


Eigentlich sollte nach dem ersten Byte was übertragen wurde ein NACKF vom Slave kommen...
 
Was ist mit "PE=0"?

Meine "Spezialität" sind die ATtinies - in so'n, möglicherweise komplett anderen Mikrocontroller will ich mich jetzt eigentlich nicht reindenken...
 
So, falls es jemand mal irgendwann gebrauchen könnte.
Der Scanner funktioniert jetzt! Ist jetzt zwar mit TimeOuts gelöst aber immerhin funktioniert er sauber.
 

Anhänge

  • main.c
    8,6 KB · Aufrufe: 4
  • Like
Reaktionen: Dirk
  • Like
Reaktionen: Dirk und Janiiix3

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)