Beiträge anzeigen

Diese Sektion erlaubt es ihnen alle Beiträge dieses Mitglieds zu sehen. Beachten sie, dass sie nur solche Beiträge sehen können, zu denen sie auch Zugriffsrechte haben.


Nachrichten - Monika

Seiten: [1] 2 3
1
Timer (Allgemein) / Timer0 bei PIC18F2620 - Ungenaue Durchlaufzeit??
« am: Januar 08, 2018, 16:28:25 Nachmittag »
Hallo,

ich arbeite seit Jahren mit dem PIC18F2620 und alle "normalen" Anwendungen von Timer0, auch in Kombination mit anderen Interrupts, verhalten sich meistens so, wie ich es mir erwarte.

Heute steht allerdings ein eher zeitkritisches Projekt an, das einige Verständnisfragen aufwirft.

Kurz zum Ablauf:
Abhängig von einem Potentiometer sollen Impulse mit einer Frequenz von 100 - 15750Hz ausgegeben werden.

Da ich mir nicht sicher war, wie sich der PIC bei so hohen Ausgangsfrequenzen verhält, habe ich damit begonnen, das 15750Hz-Signal zu erzeugen:

(Insert Code funktioniert leider nicht!)
void highprio_int(void)
{
   if(INTCONbits.TMR0IF)
   {
      INTCONbits.TMR0IF = 0;
      WriteTimer0(timer_startwert);
      
      AUSGABE_PIN = 1;  //Impulsausgabe
      AUSGABE_PIN = 0;
      
      laufvariable1++;
      laufvariable2++;      
   }
}

Den Timer-Startwert habe ich mir mit 65028 berechnet, allerdings stimmt dann die Ausgangsfrequenz nicht, sondern es wird ein Wert von 65108 benötigt, damit ich mit dem Oszilloskop das richtige Ausgangssignal messe.
Das ist für mich auch noch relativ plausibel, da ja bei so einer kurzen Durchlaufzeit das Rein-/Rausspringen in die Interruptroutine ein nicht zu vernachlässigender Zeitfaktor ist.

Das Hauptprogramm ist sehr einfach gehalten: Nach jedem 270. Impuls soll mit dem ADC der Potentiometer-Wert eingelesen und dann die Frequenz gegebenenfalls angepasst werden.

void main(void)
{
   Init();                  // Funktionsaufruf für alle notwendigen Einstellungen

   while(1)      
   {   
      TESTPIN = 1;
   
      if(laufvariable1 >= 270)
      {
         laufvariable1 = 0;
         
         ConvertADC();
         while(BusyADC());

         //ADC_result = ReadADC();      
      }
      TESTPIN = 0;
   }
}

Die beiden Zeilen ConvertADC() und while(BusyADC()) ändern am Ausgangssignal nichts, aber sobald ReadADC() aufgerufen wird, ändert sich die Ausgangsfrequenz 15700Hz auf 15000Hz. Wenn dann noch die Berechnung für den Timer-Startwert aus dem ADC_result dazukommt, liegt die Frequenz überhaupt nur mehr bei 12kHz!
Mit Hilfe des Testpins kann ich nachmessen, dass das Hauptprogramm schnell genug läuft und ich noch lange nicht an der Grenze des Möglichen angelangt bin.

Ich hätte mir erwartet, dass bei jedem 270. Impuls irgendeine Verzögerung oder ähnliches auftritt, aber nicht, dass sich dadurch die gesamte Zeitbasis des Timers ändert!!! Wie kann das passieren? Ist das nicht die Definition des Timer-Interrupts, dass dieser immer zu einer voreingestellten Zeit aufgerufen wird und das restliche Programm in der verbleibenden Zeit dazwischen abgearbeitet wird?

Durch weitere Messungen habe ich noch versucht, die Ungenauigkeit genauer zu definieren und ich glaube, dass der größte Zeitfehler beim Zurückspringen von der Interruptroutine in das Hauptprogramm passiert. Ist diese Zeitspanne vielleicht davon abhängig, welche Variablen im Hintergrund gesichert werden müssen?

Hat jemand dafür eine Erklärung?

Vielen Dank,
Monika

2
Schnittstellen (Allgemein) / Re: Initialisierung SD-Karte
« am: Juli 17, 2014, 13:36:38 Nachmittag »
Vielen Dank für eure Antworten! :)

Ich werde das gleich mal austesten

Viele Grüße
Monika

3
Schnittstellen (Allgemein) / Re: Initialisierung SD-Karte
« am: Juli 14, 2014, 13:27:11 Nachmittag »
Nach langem Herumprogrammieren habe ich meinen Fehler selbst gefunden:
init_ok = sd_command_byte(CMD41,0x40,0x00,0x00,0x00,0x01);
Byte 2+3 von CMD41 waren vertauscht, somit wurden keine SDHC-Karten unterstützt und
die Initialisierung nie beendet.

Die einzige Frage, die jetzt noch offen ist, betrifft die maximale Geschwindigkeit der SPI-Schnittstelle.
Ich arbeite jetzt mit 'PLL enabled', d.h. 32MHz, und SPI-Clk-Frequenz fOsc/64 = 500kHz.
Die SD-Karte lässt sich jetzt problemlos initialisieren ... hab ich nur Glück und dieses Exemplar ist pflegeleicht oder sind die 400kHz sowieso nur eine grobe Richtlinie und eine höhere Frequenz wird generell auch akzeptiert??

Falls es später irgendjemandem weiterhelfen sollte, hier noch die Antworten auf meine anderen Fragen:
Vor jeder ACMD41-Abfrage muss ein CMD55 stehen, sonst wird ACMD41 nicht als gültiges Kommando erkannt. Laut Datenblatt soll das Timeout für das ACMD41 mindestens 1 Sekunde sein und dabei laufend abgefragt werden.
Ein Delay ist zwischen den Abfragen nicht notwendig.

Ich würde diesen Post hier gerne als gelöst markieren, allerdings funktioniert das nicht...

Viele Grüße
Monika

4
Schnittstellen (Allgemein) / Re: Initialisierung SD-Karte
« am: Juli 14, 2014, 08:40:55 Vormittag »
Alternativ zu ACMD41 habe ich auch die Initialisierung mit CMD1 versucht:

while(timeout++ < 1000 && init_ok != 0)
{
init_ok = sd_command_byte(CMD1,0x00,0x40,0x00,0x00,0x01);
Delay1KTCYx(25);

}

aber egal, ob mit oder ohne Delay kommt auch hier immer die Antwort 0x01

5
Schnittstellen (Allgemein) / Initialisierung SD-Karte
« am: Juli 14, 2014, 08:12:47 Vormittag »
Hallo!

Ich versuche im Moment gerade, Daten auf einer SD-Karte abzuspeichern, allerdings hänge ich schon bei der Initialisierung. Das Forum habe ich auch schon durchsucht und ein paar Einträge gefunden mit diesem Thema, allerdings haben mir die Tipps dort nicht weitergeholfen.

Ich arbeite mit dem PIC18F2620 und mit einer SDHC 4GB Karte.
Die SPI-Schnittstelle läuft in folgendem Modus:
SSPCON1bits.CKP = 1;
SSPSTATbits.CKE = 0;

was die Geschwindigkeit betrifft:
die PLL hab ich jetzt abgedreht, weil ich im Forum gelesen hab, dass man die SD-Karte nur mit max. 400kHz initialisieren darf, Clock läuft jetzt mit 125kHz (nachgemessen mit Oszi).

dazu gleich eine erste Frage: gilt die 400kHz-Grenze nur für die Initialisierung oder generell für die Ansteuerung?

hier meine Initialisierung:
CMD0 ... Antwort 0x01, Idle State ... ok
CMD8 ... Antwort mit passendem Spannungsbereich und 'check pattern' ... ok
ACMD41 ... Antwort immer 0x01, Initialisierung nie abgeschlossen

for(i=0; i<10; i++) //80 clock pulses to SCLK
WriteSPI(0xff);

if(sd_command_byte(CMD0,0x00,0x00,0x00,0x00,0x95) != 1)
{
SD_Disable();
return 1;
}


timeout = 0;
while(sd_command_byte(CMD8,0x00,0x00,0x01,0xaa,0x87) != 0x01)
{
if(timeout++ > 400)
{
SD_Disable();
return 2;
}
}
for(i=0;i<4;i++)
data[i] = ReadSPI_SD();

if(data[2] != 0x01 || data[3] != 0xaa)
{
SD_Disable();
return 2;
}


timeout = 0;
init_ok = 1;

while(timeout++ < 1000 && init_ok != 0)
{
if(sd_command_byte(CMD55,0x00,0x00,0x00,0x00,0x01) <= 1)
init_ok = sd_command_byte(CMD41,0x00,0x40,0x00,0x00,0x01);
}

und hier ist auch mein Problem:
Die Antwort auf ACMD41 sollte irgendwann 0x00 sein, wenn die Initisalisierung abgeschlossen ist, aber egal, wie oft ich auch abfrage, es bleibt bei 0x01 (idle state).

Wo liegt mein Fehler?
Muss nicht vor jeder ACMD41-Abfrage ein CMD55 stehen?
Gehört irgendwo ein Delay eingebaut?

Vielen Dank schon im Vorhinein für eure Antworten!
Viele Grüße
Monika



6
PIC Mikrocontroller Allgemein / Re:Logarithmus-Berechnung mit PIC
« am: November 05, 2010, 13:25:21 Nachmittag »
Ich kann es zwar nicht erklären, aber ich hab in einem anderen Forum einen
entsprechenden Hinweis gefunden und folgendes gemacht:

In der Datei math.h habe ich die Zeile
float log10 (float x);
ersetzt durch
float log10 (auto float x);

Und damit ist auch die Fehlermeldung verschwunden. Ob die Funktion jetzt
auch die korrekten Werte berechnet, habe ich noch nicht ausgetestet, werde
das aber bei Gelegenheit tun.

Wie gesagt, ich kann es nicht begründen, warum das jetzt funktioniert,
aber vielleicht hilft mein Eintrag jemand anderem weiter, wenn dieses Problem
auftaucht.

Schönen Tag!
Monika

7
PIC Mikrocontroller Allgemein / Re:Logarithmus-Berechnung mit PIC
« am: November 05, 2010, 08:05:56 Vormittag »
Guten Morgen!

Ich hab heute deine Tipps ausprobiert ... hat leider auch nichts genutzt! :-(
Alle Pfade sind korrekt eingetragen, es funktioniert ja auch sonst alles.
In meinen Programmen verwende ich auch z.B. Delays (delay.h) oder den AD-Wandler (adc.h).
Aber so eine Fehlermeldung hatte ich noch nie. Nur die ganzen Funktionen aus math.h
laufen einfach nicht! Kann das vielleicht an der Datei math.h liegen? Die ist
nur 1KB groß ... ist das in Ordnung?

Freundliche Grüße
Monika

8
PIC Mikrocontroller Allgemein / Re:Logarithmus-Berechnung mit PIC
« am: Oktober 20, 2010, 12:52:29 Nachmittag »
Danke für deine Antwort!

Die Library-Datei p18f2620.lib ist 485 KB groß.

Jetzt hab ich das ganze für den PIC 18F2525 ausprobiert, aber da
funktioniert das auch nicht ... selbe Fehlermeldung

9
PIC Mikrocontroller Allgemein / Re:Bedienung MPLAB IDE 8.1
« am: Oktober 20, 2010, 11:36:57 Vormittag »
Hallo!

Also, ich bin ja auch nicht unbedingt ein Profi beim Programmieren.
Aber soweit ich das verstanden habe, werden beim Auslesen aus einem
Mikrocontroller nur die Daten heruntergeladen und stehen dir dann
in dem Dateiformat zur Verfügung, das von deinem Compiler auch
generiert wird, wenn du deinen eigenen Code compilierst.

Du kannst dir diesen Code aber nicht anzeigen lassen, weil der
umgekehrte Vorgang zum Compilieren ja nicht durchgeführt werden kann.

Ob das jetzt so stimmt, wissen andere sicher besser als ich. ;-)

Ich arbeite selbst mit MPLAB IDE v7.20 und dort ist es so, dass ich Daten
auslesen kann, dabei ändert sich auch die angezeigte Check-Summe.
Wenn ich dann gleich wieder einen PIC programmiere, wird dazu das zuvor
ausgelesene Programm verwendet.

10
PIC Mikrocontroller Allgemein / Logarithmus-Berechnung mit PIC
« am: Oktober 20, 2010, 11:22:06 Vormittag »
Hallo!

Ich verwende einen PIC 18F2620 und arbeite mit MPLAB IDEv7.20, C18 Compiler.
In einem meiner Projekte bin ich jetzt auf folgendes Problem gestoßen:
Ich möchte den 10er-Logarithmus einer Zahl berechnen. Hört sich an sich ja
nicht so kompliziert an, weil die Funktion ja in math.h schon ausprogrammiert
ist und eigentlich alles funktionieren sollte, wenn ich diese Bibliothek einbinde.

Allerdings bring ich das einfach nicht zum Laufen! Ich hab auch schon das
Forum durchforstet und einen Beitrag gefunden, in dem ihr einem Kollegen
erklärt habt, er soll die math.h in sein Projekt einbinden. Aber das löst leider
nicht mein Problem, weil ich das ja sowieso schon vorher gemacht hab.

Ich poste euch mal die entsprechenen Zeilen von meinem Programm, vielleicht
hat jemand von euch eine Idee dazu und sagt mir, wo mein Denkfehler liegt:

Alle eingebundenen Bibliotheken:
#include <p18f2620.h>   
#include <portb.h>
#include <delays.h>
#include <timers.h>
#include <usart.h>
#include <adc.h>
#include <math.h>
#include <pwm.h>
#include <stdio.h>
#include <stdlib.h>

Eine globale Variable:
float ADC_ber[8] = {0};
Und die zugehörige Berechnung:
ADC_ber[i] = 20 * log10(ADC_ber[i]); //in dB umrechnen

Das ganze führt dann zu folgender Fehlermeldung:
Error - could not find definition of symbol '__log10:0' in file 'M:\GI735 AudiomonDby\GI735v01.o'.

Muss ich vielleicht noch irgendwelche anderen Einstellungen vornehmen, die ich
übersehen habe?

Danke schon mal im Vorhinein für eure Bemühungen!

Beste Grüße
Monika

11
Programmiersprache C / Re: String in mehrdimensionales Feld kopieren?
« am: November 26, 2009, 15:43:49 Nachmittag »
also, ich hab jetzt alle datentypen dementsprechend geändert ... und jetzt funktioniert es! anscheinend hat sich das auch auf einiges andere ausgewirkt, nicht nur auf den kleinen code-teil, den ich in meinem beitrag angegeben hab.

kann aber nicht 100%ig sagen, ob das nur an dem gelegen ist, weil ich ja schon einiges am programm herumprobiert hab, bevor ich den hinweis von dir bekommen hab


danke nochmal!

mfg
Monika

12
Programmiersprache C / Re: String in mehrdimensionales Feld kopieren?
« am: November 26, 2009, 13:34:08 Nachmittag »
DANKE, Daniel!!!!

alleine schon der tipp mit dem char anstatt unsigned char hat mir schon weitergeholfen! hätte nicht gedacht, dass das probleme macht ... anscheinend hatte ich bis jetzt immer glück  :)

ich werd das mal überall im programm ändern, vielleicht lösen sich dann plötzlich alle probleme von selbst.

mfg
Monika

13
Programmiersprache C / Re: String in mehrdimensionales Feld kopieren?
« am: November 26, 2009, 09:55:53 Vormittag »
also, ich arbeite mit einem PIC 18F2620 und C18-Compiler ... weiß nicht, ob das wichtig ist für meine frage ...

14
Programmiersprache C / String in mehrdimensionales Feld kopieren?
« am: November 26, 2009, 09:51:43 Vormittag »
hallo!

im forum hab ich leider nichts brauchbares gefunden...aber vielleicht kann mir jemand von euch helfen

ich hab bei meinem Programm 2 Arrays und 2 Pointer:
unsigned char inputbuf[LEN];
unsigned char data_out[14][18];
unsigned char *p_in, *p_out;

Daten werden über USART eingelesen, im Eingangsbuffer (inputbuf[]) abgespeichert, bis bestimmtes Zeichen empfangen worden ist. Soweit funktioniert auch alles.

Dann füge ich ein '\0' ein, um diese Zeile dann als String behandeln zu können:
inputbuf[zeichenzaehler+1] = '\0';
ist das soweit richtig?

Die gesamte Zeile (max. 17 Zeichen) bis '\0' soll dann in jeweils eine Zeile des Feldes kopiert werden:
p_in = &inputbuf[0];
p_out = &data_out[zeilenzaehler][0];
strncpy(p_out, p_in, 17);
zeichenzaehler++;
in dem Feld steht dann aber nichts drin...
kann man das generell nicht so machen? oder hab ich nur etwas mit den Pointer falsch gemacht? Ich bekomm nämlich in der Zeile mit dem strncpy eine Warnung: "suspicious pointer conversion"

Danke an jeden, der versucht, mir etwas klarheit in dieser sache zu verschaffen!  :)

15
PIC Mikrocontroller Allgemein / Re: Adressierungsproblem bei LCD
« am: März 20, 2009, 13:06:43 Nachmittag »
Hallo Oerni,

disp_pos ist meine Positionsnummer für die Stelle, wo der Text ausgegeben wird (Anfangsposition, dann springt der Cursor eh von alleine weiter), diese Variable kann die Werte 01 - 80 annehmen.

LCD_1ZEILE hat den Wert 40 (und nicht 0x40) ... mein Programm macht also (zumindest wie ich das verstehe) folgendes:
Eingabe zwischen 01 und 80 ... als Beispiel 55:
- 55 größer 40 ==> Ausgabe in zweiter Zeile (y = 2), x-Position = 55 - 40 = 15
- also Funktionsaufruf: LCD_gotoxy(15,2);
- da in zweiter Zeile: address = 0x40 + 15 - 1 = 0x4E = 78
- dieser Wert wird ans Display übergeben

ist das so nicht richtig? Ich kann ja nicht vom Benutzer verlangen, dass er mir gleich die Adresse vom LCD richtig eingibt - daher muss ich mir das eben erst in der Funktion berechnen.

und wegen Hex/Dez-Verwechslung: dann würde es ja immer falsch sein, aber ich geb immer wieder die selben Daten ein und es tritt nur manchmal auf. und das ist ja genau das, was ich nicht verstehe...

danke, dass du dich da so reindenkst!

baba Monika

Seiten: [1] 2 3