mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik dspic30f c30 (fehlermeldung - ports) / (timer frage)


Autor: speicherschorsch (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

ich verwende einen dspic30f4013, C30 Compiler, einen ca. 7Mhz quarz und 
hab keine ahnung.

ich hab mich mal dran gemacht ein einfaches testprogramm zu schreiben:

das ding soll mithilfe des timers1 ca. jede sekunde alle ports auf 5V, 
dann auf 0V schalten. (am testboard hängen irgendwo ein paar LEDs, die 
müssten dann ja wohl blinken)

kann mal jemand über den code schauen, und beurteilen ob das so 
funktionieren könnte? (ich hab grad keine hardware da ... daher alles 
brain-in-the-loop)

dann noch eine spezielle frage:

kontext:

16bit timer, zählt bis max 2^16 = 65536

es wird ein externer 7MHz Quarz verwendet also eig. 1,43 x10^-7 s pro 
takt

_FOSC(CSW_FSCM_OFF & XT_PLL8); --> 7MHz * 8 = 56MHz

im datasheet steht folgendes:
> The input clock (FOSC/4 or external clock) to the 16-bit
> Timer has a prescale option of 1:1, 1:8, 1:64 and 1:256

ich komm mit den ganzen teilern nicht mehr zurecht!

heißt das jetzt:
der takt der beim timer 1 ankommt ist 7MHz * 8 / 4 = 14MHz. weiter mit 
dem prescaler vom timer 1/256 = 54687,5Hz.?

d.h. ich muss bis 54687 zählen (PR1=0xd59f;), damit ca. jede sekunde 1 
interrupt ausgelöst wird?

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
speicherschorsch schrieb:
> der takt der beim timer 1 ankommt ist 7MHz * 8 / 4 = 14MHz. weiter mit
> dem prescaler vom timer 1/256 = 54687,5Hz.?

Ja sollte so passen. (Ich habe hier mit 4 MHz Quarz und PLL = 16 einen 
16 MHz Takt für die Timer).

speicherschorsch schrieb:
> (ich hab grad keine hardware da ... daher alles
> brain-in-the-loop)

Warum verwendest Du nicht den Simulator? Da würdest du dann auch 
herausfinden ob der Prescaler beim erreichen von PR1 sofort gelöscht 
wird oder auch nicht. (hast Du auf- oder in Wirklichkeit ab-gerundet bei 
0,5).

Gruß Anja

Autor: speicherschorsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anja schrieb:
> Da würdest du dann auch
> herausfinden ob der Prescaler beim erreichen von PR1 sofort gelöscht
> wird oder auch nicht. (hast Du auf- oder in Wirklichkeit ab-gerundet bei
> 0,5).

wow, sorry, das versteh ich gar nicht.
prescaler ist doch 1/256 ... ne feste größe, wie kann der gelöscht 
werden?
und was hat das mitm runden zu tun ... ich hab 54687,5Hz original und 
die auf 54687 abgerundet ... das seh ich doch so ...??


nochmal die bitte, ob jemand über den code (erster post) gucken könnte 
... allgemeine kommentare bitte (ist mein erster µC code)

Autor: speicherschorsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir jemand helfen ... im simulator tut sich gar nix, d.h. keine 
variablen ändern sich etc ...
bitte mal irgendjemand den code anschauen (erster post)
dankeschön.

ach ja: ich hab beim kompilieren folgende warnung:
> main.c: In function '_T1Interrupt':
> main.c:71: warning:  PSV model not specified for '_T1Interrupt';
>    assuming 'auto_psv' this may affect latency

was bedeutet das jetz schon wieder?

Autor: Wilhelm W. (tt-elek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
wo änderst du denn ison?

Wie wäre es mit:
/*ISR*/
void __attribute__((_interrupt_)) _T1Interrupt(void){
  if (ison == 1){
    alloff();
    ison = 0;
  }
  if (ison == 0){
    allon();
    ison = 1;
  }
  IFS0bits.T1IF = 0; /* reset timer 1 interrupt flag */
}

viele Grüße

Autor: Wilhelm W. (tt-elek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wer lesen kann, ist klar im Vorteil:

/*tools*/
void allon(void){
  LATA = 0xffff;
  LATB = 0xffff;
  LATC = 0xffff;
  LATD = 0xffff;
  LATF = 0xffff;
  ---------
  ison = 1;
  ---------
}

void alloff(void){
  LATA = 0x0000;
  LATB = 0x0000;
  LATC = 0x0000;
  LATD = 0x0000;
  LATF = 0x0000;
  ---------
  ison = 0;
  ---------
}


viele Grüße

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
speicherschorsch schrieb:
>>    assuming 'auto_psv' this may affect latency
>
> was bedeutet das jetz schon wieder?

Du solltest besser im "Handbook" lesen bei einem Interrupt hast du die 
Möglichkeit entweder alles einzeln auf dem Stack oder (für eine 
Interrupt-Ebene) in den schnellen Registern zu sichern.

speicherschorsch schrieb:
> prescaler ist doch 1/256 ... ne feste größe, wie kann der gelöscht
> werden?

Im Datenblatt steht: bei einem Schreibzugriff auf das Timer-Register 
wird der Prescaler gelöscht. Zumindest beim PIC16F876 wird im "Special 
Trigger Mode" auch der Prescaler gelöscht wenn der Vergleichswert 
erreicht ist. Die Periodendauer ist dadurch beim Prescaler 8:1 um 7 
Takte zu kurz.
Beim dsPIC habe ich es noch nicht überprüft.

Gruß Anja

Autor: speicherschorsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ha, habn billigen allgemeinen programmieranfängerfehler gem8 
(kommentar):
void __attribute__((_interrupt_)) _T1Interrupt(void){
  if (ison == 1){
    alloff(); //hierin wird ison = 0 gesetzt --> beim nächsten if ist die bedingung true
  }
  if (ison == 0){ //immer true, weil vorher auf 0 gesesetzt.
    allon();
  }
  IFS0bits.T1IF = 0; /* reset timer 1 interrupt flag */
}

aber danke für die antwort schonmal.
--- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
nochmal zu:
> PSV model
was ist das? im datasheet irgendwie nix verständliches gefunden...

Autor: Chris D. (m8nix)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void __attribute__((__interrupt__)) _T1Interrupt(void){
  if (ison == 1){
    alloff();
  }
  if (ison == 0){
    allon();
  }
  IFS0bits.T1IF = 0; /* reset timer 1 interrupt flag */
}

... da bist'e einem typischen Anfängerfehler auf den Leim gegangen.
Welchen Wert hat "ison" nach "alloff()" ? ... -> 0! - somit ist deine 2. 
if-bedingung auch erfüllt und "allon()" wird auch ausgeführt.

besser so...
void __attribute__((__interrupt__)) _T1Interrupt(void){
  if (ison == 1) alloff() else allon();
  IFS0bits.T1IF = 0; /* reset timer 1 interrupt flag */
}

Gruß
Chris


*** edit

hihi... bist ja von alleine drauf gekommen ;-)

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anja schrieb:
> Beim dsPIC habe ich es noch nicht überprüft.

Also bei mir läuft der Code im Simulator (MPLAB 8.33). Der Abstand 
zwischen 2 Interrupts ist im Simulator 14000127 Takte. Im ersten 
Durchlauf nach Reset 14000146 Takte. Ich hätte entweder 14000128 = 54688 
* 256 oder 13999873 = 54687 * 256 + 1 erwartet.

Gruß Anja

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Anja,
auf welchem Weg hast du das "Der Abstand zwischen 2 Interrupts ist im 
Simulator" erstellt/überprüft?
Siegfried

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.