Forum: Mikrocontroller und Digitale Elektronik Timingproblem mit Onewire und STM32


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Ich probiere gerade einen DS18B20 mit einem STM32F103C8 auszulesen.
Dabei scheine ich ein Timingproblem zu haben, ich komme aber nicht 
dahinter.

Für die Delays habe ich mir den Systick etwas genauer angesehen und 
folgend implementiert:
Delay.c:
1
volatile uint32_t us_tick, ms_tick;
2
3
/*__IO uint32_t TimingDelay;
4
uint32_t MillisCounter = 0;*/
5
6
/**
7
  * @brief  Decrements the TimingDelay variable.
8
  * @param  None
9
  * @retval None
10
  */
11
12
void SysTick_Handler(void){
13
  us_tick++; //Increment millisecond variable
14
  if(us_tick%1000 == 999){ //If 1000 milliseconds have passed, increment seconds
15
    ms_tick++;
16
  }
17
}
18
19
void Delay_Ms(__IO uint32_t nTime){
20
  volatile uint32_t msStart = ms_tick;
21
  while((ms_tick - msStart) < nTime){
22
    asm volatile("nop");
23
  }
24
}
25
26
void Delay_us(__IO uint32_t nTime){
27
  volatile uint32_t usStart = us_tick;
28
  while((us_tick - usStart) < nTime){
29
    asm volatile("nop");
30
  }
31
}

sowie ganz am Anfang der int main(void){} folgende Zeilen:
1
SystemInit();                                             //ensure CPU is running t correctly set clock speed
2
  SystemCoreClockUpdate();                                  //update SystemCoreClock variable to current clock speed
3
  SysTick_Config(SystemCoreClock/1000000);                  //systick every microsecond

Das habe ich mit Delay_Ms(1000) sowie Delay_us(1000000) an einer LED 
ausprobiert. Wirkt auch stabil.

Für das Timing der einzelnen Funktionen habe ich mich an 
https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 sowie das 
Datenblatt des DS18B20 gehalten.
Im Anhang sind die OneWire.c und .h
(folgende Zeilenangaben beziehen sich auf OneWire.c)

In Zeile 34 prüfe ich das "Lebenszeichen" des Sensors, "err" bleibt 
dabei auf 0. Sensor sollte also da sein ...
Wenn ich in Zeile 128 einen Breakpoint setzte sehe ich, dass die beiden 
gelesenen Bytes immer 0xff beinhalten.

Laut Datenblatt soll für die Datenleitung ja ein 4,7kOhm verwendet 
werden. An dem Pull-Up des uC's wird es doch nicht liegen? (laut 
Datenblatt min 30kOhm, typ 40kOhm, max 50kOhm)

Liebe Grüße

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Was sagt das Scope oder ein Logicanalysator zu Deinem Hardwaretiming? 
Oder mache Dir das Programmieren einfacher und verwende den USART (Maxim 
AN 126) fuer das Hardwaretiming...

von Matthias (Gast)


Lesenswert?

Uwe B. schrieb:
> Was sagt das Scope oder ein Logicanalysator zu Deinem Hardwaretiming?

Ich verwende emBlocks 2.30. Dort gibt es eine Lasche "Cscope", dort sind 
keine Meldungen enthalten. Beim Compilieren gibt es auch weder Error 
noch Warning. Logicanalysator habe ich nicht.

Uwe B. schrieb:
> Oder mache Dir das Programmieren einfacher und verwende den USART

Das kann ich mir mal anschauen. Würde allerdings den Weg den ich hier 
genommen habe auch bis zum Schluss gehen ;)

von Matthias (Gast)


Lesenswert?

Nachtrag:
1. Der DS18B20 ist mit 3,3V Versorgt. Um genau zu sein 3,19V, gemessen 
direkt an den Anschlusspins.

2. Die Temperaturwandlungsroutine scheint nicht fertig zu werden. HAbe 
die Abfrage in Zeile 118 von der Zählvariable getrennt
1
while (GPIO_ReadInputDataBit(port,used_pin)){
Dort kommt er nicht mehr raus.

von Matthias (Gast)


Lesenswert?

Ich habe mir den Code nochmal genauer angeschaut und den "us_tick" 
während der Abarbeitung etwas beobachtet.
Aufgefallen ist mir der folgende Abschnitt:
1
uint8_t ds1820_re_bit(GPIO_TypeDef * port, uint16_t used_pin){
2
  uint8_t rebit;
3
  GPIO_WriteBit(port,used_pin,DISABLE);             // Pull low
4
  Delay_us(OW_Delay_A);                             // 6us (standard)
5
  pin_to_input(port, used_pin);              // define as input with Pull Up
6
  Delay_us(OW_Delay_E);                  // 9us (standard)
7
  rebit = GPIO_ReadInputDataBit(port,used_pin);     // Read bit
8
  Delay_us(OW_Delay_F);                  // 55us (standard)
9
  pin_to_output(port, used_pin);                    // define as ouput
10
  return rebit;
11
}
Unter der Annahme, dass bei dem PullLow der Ticker auf 0 stehen würde:
(zeitangaben nach Ausführung der Zeile)
- pull low   0  uS
- delay A    12 uS
- to input   75 uS
- delay E    89 uS
- read input

Der Read-Befehl kommt also viel zu spät und alle Messen sind schon 
gesungen.

Kann mir jemand sagen, ob mein Systick überhaupt richtig eingestellt 
ist, sodass ich mich auf die Angabe des us_tick verlassen kann?

von (prx) A. K. (prx)


Lesenswert?

Die Lib-Funktionen dürften einem exakten Timing etwas im Weg sein. Da 
solltest du schon direkt an dier Hardware ran.

Ausserdem lassen sich die STM32 GPIOs als Open Drain konfigurieren, so 
dass die Richtungsumschaltung entfällt.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Ich probiere gerade einen DS18B20 mit einem STM32F103C8 auszulesen.
> Dabei scheine ich ein Timingproblem zu haben, ich komme aber nicht
> dahinter.

Schau Dir mal an, wie ich das im Rahmen des WordClock24h-Projekts 
gelöst habe:

  https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/

Der Code läuft auf STM32F4xx und STM32F10x.

von Matthias (Gast)


Lesenswert?

A. K. schrieb:
> Ausserdem lassen sich die STM32 GPIOs als Open Drain konfigurieren, so
> dass die Richtungsumschaltung entfällt.

Danke, genau danach wollte ich gerade im Referenz-Manual suchen! ;)

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Na endlich läuft es! :D

A. K. schrieb:
> Die Lib-Funktionen dürften einem exakten Timing etwas im Weg sein. Da
> solltest du schon direkt an dier Hardware ran.
>
> Ausserdem lassen sich die STM32 GPIOs als Open Drain konfigurieren, so
> dass die Richtungsumschaltung entfällt.

Das waren die beiden Sachen die ich ändern musste.

Interessant ist noch, dass das Warten bei 0x44-TemperaturConversion nie 
zum Tragen kommt. (Zeilen 124 und 153)
Allerdings endet die "ds1820_wr_byte"-Funktion auch mit einem 5uS-Delay.
Reicht das dem Sensor erfahrungsgemäß für das Füllen der beiden 
Register?

Ansonsten im Anhang nochmal der c-Code

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.