Forum: Mikrocontroller und Digitale Elektronik PIC24 Probleme mit Delay_ms


von Holger W. (sirmortimer)


Lesenswert?

Hallo Leute,

ich habe ein Probleme mit der Delay-Routine für einen PIC24-Prozesser.

Ich arbeite mit MPLAB X und dem X16-Compiler.

Der Code, den ich für die Delay-Funktion benutze ist:

void Delay(unsigned int delay_count)
{
  temp_count=delay_count +1;
  asm volatile("outer: dec _temp_count");
  asm volatile("cp0 _temp_count");
  asm volatile("bra z, done");
  asm volatile("do #3200, inner");
  asm volatile("nop");  asm volatile("inner: nop");
  asm volatile("bra outer");
  asm volatile("done:");

Leider meldet der Compiler für die Zeile

asm volatile("do #3200, inner");

das der Befehl für den PIC24FJ1128GA010 nicht unterstützt wird (habe ich 
durch succesives Auskommentieren herausgefunden).

Was mache ich falsch, bzw. gibt es eine bessere Möglichkeit für eine 
Delay-Funtion?

Vielen Dank schonmal , Holger

von Peter C. (peter_c49)


Lesenswert?

Hallo Holger,

was du falsch machst hab ich nicht nachgesehen, nachstehend was ich 
meist benutze um delays zu machen wenn ich es ohne timer machen möchte.
habe damit noch nie probleme gehabt auf diversen 16 bit PICs.

#include<libpic30.h> // for __delay32

#ifndef delay_msec
#define delay_ns(d) { __delay32( (unsigned long) 
((d)*(FCY)/1000000000UL)); }
#define delay_us(d) { __delay32( (unsigned long) ((d)*(FCY)/1000000UL)); 
}
#define delay_msec(d) { __delay32( (unsigned long) ((d)*(FCY)/1000UL)); 
}
#define delay_s(d)  { __delay32( (unsigned long) ((d)*(FCY)/1UL)); }
#endif

wichtig, FCY muss irgendwo mal für deine HW/config passend definiert 
sein.
#define FCY 16000000UL // 8 mhz * pll(4) => 32Mhz == 16Mhz FCY

mfG
Peter ;-)

von Dieter W. (dds5)


Lesenswert?

Holger W. schrieb:
> Leider meldet der Compiler für die Zeile
>
> asm volatile("do #3200, inner");
>
> das der Befehl für den PIC24FJ1128GA010 nicht unterstützt wird

Da hat der Compiler recht, den ASM "do" Befehl kennen nur die PIC24H und 
dsPIC Controller.

von Holger W. (sirmortimer)


Lesenswert?

Hallo Peter,

vielen Dank für Deine überaus schnelle Antwort.

Dein Code funktioniert prima und ist zudem viel eleganter, als das was 
ich gepostet und sonst gefunden habe!
Und mit FCY = Fosc/2 kann man die Funktionen an jede Konfiguration 
bequem anpassen.

Also ich bin begeistert.

Viele Grüße, Holger

von Klaus (Gast)


Lesenswert?

Peter C. schrieb:
> was du falsch machst hab ich nicht nachgesehen, nachstehend was ich
> meist benutze um delays zu machen wenn ich es ohne timer machen möchte.
> habe damit noch nie probleme gehabt auf diversen 16 bit PICs.
>
> #include<libpic30.h> // for __delay32
>
> #ifndef delay_msec
> #define delay_ns(d) { __delay32( (unsigned long)
> ((d)*(FCY)/1000000000UL)); }
> #define delay_us(d) { __delay32( (unsigned long) ((d)*(FCY)/1000000UL));
> }
> #define delay_msec(d) { __delay32( (unsigned long) ((d)*(FCY)/1000UL));
> }
> #define delay_s(d)  { __delay32( (unsigned long) ((d)*(FCY)/1UL)); }
> #endif

Könnte es sein, daß das fast genauso schon in libpic30.h drinsteht? Die 
fertig gelieferten Funktionen heißen

__delay_us()   und
__delay_ms()
1
#define __delay_ms(d) \
2
  { __delay32( (unsigned long) (((unsigned long long) d)*(FCY)/1000ULL)); }
3
#define __delay_us(d) \
4
  { __delay32( (unsigned long) (((unsigned long long) d)*(FCY)/1000000ULL)); }

MfG Klaus

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.