Hallo,
Für meine Abschlussarbeit ist es erforderlich einen PIC12F675 in C zu
Programmieren. MPLAB und der Hitech C Compiler arbeiten einwandfrei.
Als Board habe ich das Vellemann V111 K8048 (oder so ähnlich geholt)...
Nun habe ich folgende Situation:
Zum testen habe ich einen PIC16F84A Programmiert. Das Programm und das
Brennen, sowie die Abarbeitung des Programms haben einwandfrei
funktioniert. (Dieser PIC wird über einen externen Quarz getaktet).
Nun wollte ich ein kleines Testprogramm in C für den PIC12F675
schreiben.
Das Problem ist dass ich keine Erfahrungen mit PIC Mikrokontrollern habe
und nicht weiß wie ich bei diesem PIC die Register setzen muss um die
Pins als Ein-Oder ausgänge zu verwenden.
Außerdem wird dieser PIC nicht über einen externen Quarz getaktet,
sondern muss den internen verwenden (das sollte ja möglich sein).
Ich hoffe dass es in diesem Forum einige Experten gibt, die mir einen
kleinen C-Code zukommen lassen könnten. ich benötige lediglich einen
eingang und einen Ausgang (Erstmal egal welche Pins, das zu ändern krieg
ich auch noch hin).
Wäre toll wenn mir jemand helfen könnte, vielleicht auch über MSN oder
ICQ oder sonnstwas.
Stefan
Stefan Haussmann schrieb:> Das Problem ist dass ich keine Erfahrungen mit PIC Mikrokontrollern habe> und nicht weiß wie ich bei diesem PIC die Register setzen muss um die> Pins als Ein-Oder ausgänge zu verwenden.
Es reicht völlig die "Erfahrung", daß man sich das Datenblatt vom
Hersteller runter laden kann.
Und dann einfach anschauen, wo die IO-Pins beschrieben sind und deren
Konfigurationsregister.
Peter
Kleiner Stolperstein, während bei den größeren PICs wie 16F84 die Ports
als PORTA, PORTB usw. bezeichnet ist, lautet die Bezeichnung beim 12F675
"GPIO" (general purpose I/O). Also statt
PORTA fuer den Port
TRISA fuer die Datenrichtung (Eingang/Ausgang)
verwendet man GPIO und TRISIO. Ansonsten hilft wie von Peter gesagt ein
Blick ins Datenblatt - Ansprechen der Ports ist bei beiden PICs
ansonsten identisch, bloss die RAM-Adressen sind anders. Die
Oszillatorauswahl ist auch ausführlich beschrieben, das wichtig Register
ist hier OSCCON.
Wolfgang
MPLAB versteht beim 12F675 sowohl GP4 als auch GPIO4 für das Bit4 des
Ports (wobei der 12F675 natürlich nur die Bits 0 bis 5 hat). Für das
Datenrichtungsregister gibt es TRISIO4 für das Bit4 (auch nur 0 bis 5).
Stefan Haussmann schrieb:> und nicht weiß wie ich bei diesem PIC die Register setzen muss um die> Pins als Ein-Oder ausgänge zu verwenden.
Tipp: vergiß nicht die Pins von Analog-Eingang auf Digital
umzukonfigurieren.
Ansonsten: Die Initialisierung steht prinzipiell im Datenblatt.
Gruß Anja
Wenn du den HI-Tech verwendest, kannst du mal in den "include"-Ordner im
Compilerverzeichnis schauen und nach der Datei "pic16f675.h" oder
ähnlich suchen; dort stehen alle definierten Symbole drin, die der
Compiler kennt.
Jetzt musst du das nur noch mit dem Datenblatt abgleichen, ist nicht so
wild. Für eine Abschlussarbeit sollte das drin sein ;-)
Wenn du dann detailliertere Fragen hast, kannst du dich hier ja noch
einmal melden.
Gruß
Jens
Also...
Vorweg erstmal besten Dank an euch...
Ich bin jetzt auf den micro C PRO Compiler vom Mikroelectronica
umgestiegen bei welchem die Konfiguration sofort Funktioniert hat.
Ein/Ausgänge ansprechen war überhaupt kein Problem mehr.
Jetzt kommt allerdings der Hauptteil.
Ich möchte (muss!!!) eine Pulsweitenmodulation Programmieren (für einen
Modellbauservo) Das heißt, dass alle 20ms ein Signal zwischen 900us und
2ms an einem Ausgang (Welcher ist egal) anliegen sollte.
Gibt es irgendwelche Ideen oder Tips, wie man das mit dem oben genannten
PIC (12F675) oder einem anderen PIC der 12F Reihe diese Aufgabe Lösen
kann.
Hier dachte ich an den PIC12F683, welcher laut Datenblatt einen
integrierten PWM Generator hat.
Das Programm sollte also so sein, dass über eine Variable alle 20ms eine
neue Pulslänge eingestellt werden kann (zum Beispiel soll nach 5 Minuten
das Signal die Pulsweite von 900us bis 1,5ms durchlaufen)
Der PIC ist in meiner Abschlussarbeit leider nur eine Nebensache mit der
ich fast schon auf Kriegsfuß stehe, aber man beißt sich irgendwie durch.
Wär cool, wenn wieder mal ein paar Experten ihr Know How zur verfügung
stellen würden...
Ja, MikroC gefaellt mir auch, weil da aben vieles gleich mal
funktioniert.
Das PWM-Modul kann leider so lange Perioden nicht erzeugen, ausser du
laesst den PIC auf einer sehr geringen Taktfrequenz laufen (dann wird
aber die Abarbeitungsgeschwindigkeit fuer alles andere sehr langsam).
Eine Periode von 20ms ist aber fuer den PIC ohnehin sehr lange, da kann
man das - wenn sonst nichts zu tun ist - einfach als Schleife
implementieren. Die Funktionen Delay_ms und Delay_us in MikroC (oder
Mikrobasic) kommen da gerade recht. Achtung, diese Funktionen akzepieren
nur Konstanten, und du musst built_in.h einbinden.
Also in etwa so
while (1)
{
hier Variable hochzaehlen, Zeit in 100usEinheiten
for (high_time = 90; high_time <= 150; high_time++)
{
low_time = period - high_time;
N-mal wiederholen (N so waehlen, dass die Aenderung
der Pulsbreite mir der gewuenschten Geschwindigkeit verlaeuft,
z.B. N=50 umd die Breite alles 1sec um 100us zu erhoehen):
for (j = N; j; j--)
{
pin auf low setzen
for (i=low_time; i; i--) { Delay_us(100); }
pin auf high setzen
for (i=high_time; i; i--) { Delay_us(100); }
}
}
} // Pulsbreite wieder auf Minimum und wieder vom Anfang an
Wenn mann es genauer machen will, muss man noch die Ausfuehrungszeit der
Befehle abziehen, das ist aber eine eher kleine Korrektur hier (deshalb
habe ich auch 100us als Basiseinheit gewaehlt - mit 1us waere das nicht
der Fall!).
Wolfgang
Ich habe das im Anhang hinterlegte Programm ja schon durch eure Hilfe
hinbekommen.
Allerdings scheitere ich bei der Implementierung folgender
Zusatzfunktionen:
-Wenn an GP0 kein Signal mehr anliegt, soll sich die Pulsweite nichtmehr
verändern.
-Wenn der obere Block (PWM UP) einmal durchlaufen ist, soll die
Pulsweite gehalten werden (Servo bewegt sich nicht)und es soll ein
Signal an GP4 ausgegeben werden. Mit einem Signal an GP5 soll dann der
untere Block (PWM DOWN) gestartet werden, welcher den Servo auf die
ursprüngliche Position zurücksetzt und das Signal an GP5 soll auf 0
gehen.
Ich hoffe ihr versteht was ich meine :-)
Danke im voraus
Stefan
Wolfgang M. schrieb:> Das PWM-Modul kann leider so lange Perioden nicht erzeugen, ausser du> laesst den PIC auf einer sehr geringen Taktfrequenz laufen (dann wird> aber die Abarbeitungsgeschwindigkeit fuer alles andere sehr langsam).
Bei dem PIC12F1822 oder 12F1840 kann man einen Prescaler von 64
einstellen, bei dem 683 nur von 16. D.h. bei internen 2Mhz sind das Als
Periodendauer: (PR2 + 1) 4 Tosc * TMR2Prescaler -> (155 + 1) 4
1/2MHz * 64 = 19,968ms. Bei dem 10bit PWMModul ist das eine Auflösung
von 19,5µs, was ja ausreichen sollte. Damit wäre 46 (0x00 0010 1110)
0,897ms und 77 (0x00 0100 1101) 1,5015ms.
Nur musst du entscheiden, ob eine Frequenz von 2Mhz (also intern 500kHz)
ausreichend ist und ob du den PIC nehmen kannst/willst. Was sind denn
deine Vorgaben bzw was musst du benutzen und was darfst du nicht
benutzen? Im ersten Beitrag meintest du ja, dass "es erforderlich einen
PIC12F675 in C zu Programmieren". Später bist du zum 683 gewechselt,
also warum nicht auch zum 1822 oder 1840 (oder was ganz anderes?)
Michael Skropski schrieb:> Bei dem PIC12F1822 oder 12F1840 kann man einen Prescaler von 64> einstellen, bei dem 683 nur von 16. D.h. bei internen 2Mhz sind das Als> Periodendauer: (PR2 + 1) 4 Tosc * TMR2Prescaler -> (155 + 1) 4> 1/2MHz * 64 = 19,968ms. Bei dem 10bit PWMModul ist das eine Auflösung> von 19,5µs, was ja ausreichen sollte. Damit wäre 46 (0x00 0010 1110)> 0,897ms und 77 (0x00 0100 1101) 1,5015ms.
Ich hab nochmal nachgeguckt. Die Maximale Frequenz, die du nehmen
kannst, gibt es sogar als Quarz bei Reichelt -> 3,2768 MHz (819,2kHz
intern). Dann hast du (255 + 1) mal 4 mal 1/3,2768MHz mal 64 = 20ms.
Auflösung bleibt so ziemlich gleich, da die Zeit ja kaum unterschiedlich
ist.
Aber wie gesagt, schreib mal deinen Auftrag bzw was musst du benutzen
und was darfst du nicht und was muss es am Ende können.
Also...hier die vollständige Eklärung:
Das Aktuelle Programm lässt einen servo im Prinzip hin und her fahren.
Der Obere Teil des Programms (PWM UP) lässt den servo ansteigen, der
untere Teil (PWM DOWN) lässt diesen kontrolliert zurückfahren.
Das Signal des Servos wird an GP4 Ausgegeben.
Nun sollen folgende Verbesserungen Stattfinden.
1. Die Pulsweite soll sich nur verändern wenn an GP5 ein High Signal
anliegt (Der Servo soll seine Position halten).
2. Das zurückfahren des Servos (PWM DOWN) soll erst erfolgen, sobald an
dem Eingang GP0 ein High Signal anliegt (Taster).
3.Sobald der Servo seinen Zielwert erreicht hat (im angefügten Programm
120 -->im PWM UP Teil) solll GP4 auf High schalten (LED Signalisiert,
dass der Servo seinen Zielwert erreicht hat).
Diese LED Soll nach dem Zurückstellen des Servos wieder Erlischen.
Ich hoffe diese Beschreibung ist etwas besser...
Also hattest du das Programm schon gegeben und sollst es nur erweitern?
Dann bringt dir auch kein PIC mit PWM-Modul was, auch wenn der Timer
einen großen Vorteiler hat.
Wenn du dein Programm, was du angehängt hast, benutzen bzw erweitern
musst, ist das ja nicht weiter tragisch, ein paar ifs an der richtigen
stelle. Z.b. Wenn GP5==1, high_time++, ansonsten das weglassen.
Ich glaube aber nicht, dass das Programm gegeben ist (es sei denn der
Aufgabensteller will nicht nur eine Erweiterung sondern auch eine
Fehlersuche), denn die Deklaration von Variablen kommen ganz am Anfang
der Funktionen. Also haben die in der while nichts zusuchen, sondern
gehören direkt unter das "void main(){".
Wenn du es denn so willst, was eine neue programmierung bedeutet, kannst
du (wenn du in der PIC12F Familie bleiben sollst) den von mir erwähnten
PIC12F1822 mit dem 3,2768MHz Quarz nehmen und kannst das PWM-Modul
benutzen. Es ist nicht nur angenehmer zu programmieren, sondern auch
übersichtlicher, eleganter und vorallem läuft das PWM-Modul automatisch
im Hintergrund. Das heißt, er gibt die PWM aus und du kannst im Programm
machen, was du willst. Wenn du eine Schleife mit wartefunktionen im
Programm stehen hast, verfälscht du die Zeit mit jedem Befehl (sogar
schon mit dem Setzen/Löschen des Ausgangs und der Schleife). Das ist bei
hoher Taktfrequenz und kleiner PWM-Frequenz natürlich weniger schlimm,
aber solche Module gibts ja nicht umsonst. Und ~800kHz reicht aus, um ne
LED zu setzen oder nen Eingang abzufragen. Die Konfiguration vom
PWM-Modul steht ja quasi schon oben, also wird es außer der einmaligen
Initialisierung am Anfang vom Programm nen 10-20 Zeiler.
OK, ich bin jetzt am Rande des Wahnsinns...
Ich habe hier nochmal die Aufgabe hineinkopiert:
Das Programm PWM.c findet ihr weiter oben.
Das Programm lässt einen servo im Prinzip hin und her fahren.
Der Obere Teil des Programms (PWM UP) lässt den servo ansteigen, der
untere Teil (PWM DOWN) lässt diesen kontrolliert zurückfahren.
Das Signal des Servos wird an GP4 Ausgegeben.
Nun sollen folgende Verbesserungen Stattfinden.
1. Die Pulsweite soll sich nur verändern wenn an GP5 ein High Signal
anliegt (Der Servo soll seine Position halten).
2. Das zurückfahren des Servos (PWM DOWN) soll erst erfolgen, sobald an
dem Eingang GP0 ein High Signal anliegt (Taster).
3.Sobald der Servo seinen Zielwert erreicht hat (im angefügten Programm
120 -->im PWM UP Teil) solll GP4 auf High schalten (LED Signalisiert,
dass der Servo seinen Zielwert erreicht hat).
Diese LED Soll nach dem Zurückstellen des Servos wieder Erlischen.
Ich bin absolut kein Programmiergenie so wie manch andere hier...ich
benötige deswegen einen Leitfaden oder persönlichen Kontakt.
Ich Programmier das Ding neu, anhand dem was ihr mir hier sagen
werdet...es reicht auch eine Strategie z.B.
Bit....Setzen
TCON....Setzen
...
...
...
Gibt es eine Möglichkeit die PWM Ohne den externen Oszillator zu machen?
Zum beispiel mit einem Timer oder sowas??? Das zurückfahren des Servos
könnte man ja Mithilfe eines Interrupts an GP2 machen. Also sobald an
GP2 eine High Flanke kommt kann ja das "Rückfahr Programm" Ausgeführt
werden und die Pulsweite im normalen Programm wieder zurückgesetzt
werden.
Danke an alle die mich so geduldig ertragen!!!
Viel Zeit habe ich gerade nicht, deshalb keine vollstaendige Loesung.
Aber ich hab mal einen Blick auf Dein urspruengliches Programm geworfen.
Da ist TRISIO=0 gesetzt. Das heisst aber, alle Pins sind als Ausgaenge
geschaltet - klar, dass Du da kein Eingangssignal lesen kannst.
Stattessen
// GP--> 76543210
TRISIO = 0b00100001; // binaer ist es leichter lesbar - ein bit pro Pin
macht GP0 und GP5 zu Eingaengen. JETZT kannst Du da Signale anlegen und
einlesen. Wenn das ueber Taster geschehen soll, brauchst Du noch
Pull-Down-Widerstaende. Also Taster zwischen VCC und Eingang, einen 1
kOhm-Widerstand zwischen Eingang und GND. Damit ist der Eingang solide
auf GND, wenn der Taster nicht betaetigt ist.
LED Einschalten: gp4_bit = 1;
LED Ausschalten: gp4_bit = 0;
GP5 high? abfragen:
if (gp5_bit) { .... }
oder
if (gp5_bit > 0) { .... }
warten solange GP0 noch low ist:
while (!gp0_bit) {}
oder
while (gp0_bit == 0) {}
PWM und externer Oszillator haben miteinander nichts zu tun. Du kannst
genauso den internen Oszillator verwenden, und den kann man auch
verschnieden schnell einstellen (oder genauer gesagt, den Takt
verschieden herunterteilen).
Wenn Du MikroC verwendest, gibt es vorgefertigte Funktionen in der
Library zum Einschalten der PWM sowie zum Veraendern des
Tastverhaeltnisses (= Pulsbreite, Duty Cycle).
Wolfgang
Das mit den Eingängen ist korrekt...die waren in dem ersten Programm
noch nicht mit drin...
Ich hoffe, dass die Aufgabe jetzt etwas klarer beschrieben ist.
Ich benutze MicroC...Wie komme ich auf die vorgefertigten Funktionen?
Das PWM Zeugs kenne ich bisher nur aus dem Datenblatt.
Theoretisch kann ich die Pausenzeit ja Fix auf 15ms lassen und mit dem
PWM Modul einen High Puls erzeugen der von ca. 500us bis 1500us
ansteigt, oder?
Ich weiß nicht ob mikroC eine Software PWM Library hat. Das normale
PWM1_Init ist jedenfalls für das interne PWM Modul. Das nützt dir nur
nichts, wenn du die Frequenz nicht weit genug teilen kannst.
Du kannst auch eine Fix-Pause von 18ms nehmen und die differenz von der
Highzeit zu 2ms zusätzlich auch Low schalten und warten. Nur bringt es
nicht unbedingt Vorteile. Du hast eine Variable die du hochzählst, wenn
GP5 und GP0 auf high ist und zusätzlich, wenn die Variable kleiner als
die maximale Highzeit ist. Beim runterzählen entsprechend. Und wenn der
maximalwert erreicht ist, soll gp4 gesetzt werden.
1
if(GP5)// musst gucken, wie die gp5 variable heißt
Ich bin am Handy also kann ich nichts nachgucken. Du musst gucken, ob
das Programm das so macht wie es soll. Ich weiß auch nicht die
konstanten für die Bits (GP5 z.b. glaube es is eher GPIO.GP5_bit oder
so) oder wie genau die funktion heißt, die eine variable zeit wartet
aber das kannst du ja nachgucken.
Vielleicht hilft das ja.
Einige schreiben, dass das mit dem internen PWM Modul nicht
funktioniert...ist das so oder nicht. Ich habe auch eine Lösung gesehen,
in der mit 2 Timern gearbeitet wird...allerdings wäre mir das PWM Modul
lieber...
Wie schon früher erwähnt: Das PWM-Modul hat Grenzen in der Frequenz nach
unten. PWM benutzt einen Hardware-Timer (Zähler), dessen Eingangstakt
kommt vom Oszillatortakt, u.U. heruntergeteilt (typischerweise in
Zweierpotenzen bis 2^8=256 möglich). Für eine bestimmte
Oszillatorfrequenz kann man also das PWM nicht beliebig langsam laufen
lassen.
Natürlich kann man sich selber ein Timer-PWM basteln. Du verwendest
MikroC, da schau mal in den mitgelieferten Beispielen unter Timer nach.
Da hast Du ein vollständiges, lauffähiges Programm dazu. Musst nur noch
Prescaler und Preload-Werte verändern, damit Du statt 1 Hz eben z.B. 20
Hz bekommst. (schau auch das "alte" MikroC an, also nicht MikroC Pro, da
gibt es sogar ein Besipiel genau für the 12F673).
Ich probier die Strategie mit den Timern, das klingt am
vielversprechensten.
Da kann man relativ leicht sachen hinzuprogrammieren.
Die werte ausrechnen ist kein problem..das hat nichts mit Syntax oder
erfahrung zu tun :-)
Tausend Dank
Wie ich weiter oben schon geschrieben hatte hat der 683 nur einen
prescaler von 16. Bei 20ms PWM Periodendauer, also 50Hz kannst du den
PIC nur bis zu einer bestimmten Frequenz takten. Da der PIC12F1822/1840
einen 64 Teiler haben, kannst du ihn also 4 mal schneller takten, da du
ihn halt mehr teilen kannst.
Deswegen frag ich ja auch was deine Aufgabe ist. Wenn du dieses von dir
gepostete Programm erweitern sollst, bringt dir ein PWM-Modul rein
garnichts, weil das im Programm ja garnicht vorkommst. Und wenn du die
Freiheit hast, das ganze Programm neu zu schreiben, nämlich mit einem
PWM-Modul, dann hast du ja evtl auch die Freiheit einen anderen PIC zu
wählen, eben den 12F1822. Das Beispiel dazu hab ich ja weiter oben schon
geschrieben. Wenn der PIC aber nichts anderes machen soll ist es egal ob
delay (aus dem letzten Post von mir), timer mit interrupt oder pwm modul
in Verbindung mit einem sehr langsamen Takt.
Das hier ist der Versuch das genze mit einem interrupt zu gestalten.
Das Programm (welches natürnich NICHT funktioniert) hat folgenden
Ablauf:
Timer0 löst alle 20ms einen interrupt aus
GP2 Ausgang geht auf 1
Timer1 Bestimmt die Pulslänge
Wenn Timer1 überlauf bekommt geht der GP2 Ausgang wieder auf 0.
Allerdings funktioniert da was nicht. Bitte mal durchschauen.
Das Programm ist ohne Extras, soll also nur mal eine feste Pulslänge
erzeugen (Länge ziemlich egal).
MfG
Stefan
Wenn ich mich nicht verrechnet habe,
komme ich auf ca. 65 ms für Timer 0.
Hier muß ein H hin:
TMR1H=253; //High Byte berechnen
TMR1L=232; //Low Byte berechnen
Stefan Haussmann schrieb:> Timer0 löst alle 20ms einen interrupt aus> GP2 Ausgang geht auf 1> Timer1 Bestimmt die Pulslänge> Wenn Timer1 überlauf bekommt geht der GP2 Ausgang wieder auf 0.
Welchen Grund gibt es, dafür verschiedene Timer zu nehmen?
Wenn Timings aufeinander folgen, nehme ich dazu auch den gleichen Timer,
das ist einfacher.
Ideal ist dazu ein Compareinterrupt. Dann kann der Timer durchlaufen und
man setzt einfach nur den nächsten Comparewert.
Peter
Stefan Haussmann schrieb:> Außerdem hab ich> nicht wirklich ahnung was du meinst.
Sorry, hab grad ins Datenblatt geschaut. Die Timer sind ja wirklich nur
sehr rudimentär ausgestattet. Comparemode gibt es keinen.
Ich bin das vom AVR so gewöhnt, daß selbst die kleinen 8-Pinner sehr
flexible Timerfunktionen haben.
Da gibt es mindestens 2 Compareregister, die auch einen Pin direkt
umschalten können. D.h. es entsteht kein Jitter durch die
Interruptlatenz.
Das Schalten erfolgt auf den CPU-Zyklus genau.
Gibt es irgendeinen Grund, warum Du gerade diesen PIC nimmst?
Ich würde einen mit leistungsfähigerem Timer nehmen.
Peter
Ich möchte keinen anderen Mikrocontroller verwenden...hab den 10 mal
hier rumliegen. Ich habe das Programm übertragen und es funktioniert
irgendwie nicht und ich weiß nicht warum. Ich bin im Programmieren nicht
unbedingt ein Experte. Falls du da ahnung hast kannst du dir mal die
Aufgabe durchlesen und schauen warum das nicht geht...bin schon am
verzweifeln.
Zweimal TMR1L?
Vielleicht kann Dein Compiler den Timer als 16Bit zugreifen, dann muß
man low und high-Byte nicht selber auseinanderfriemeln.
Auch kann C Konstanten selber ausrechnen. Man schreibt daher besser die
Formel hin und keine magischen Zahlenwerte.
Hier mal ein Beispiel für den AVR-GCC:
Ich muss doch nur GIE setzen, das tu ich in "void timer0()"...das ist ja
nicht die interrupt routine...Der schreibfehler (H und L) ist behoben.
Funktioniert aber nicht.
Ich möchte erstmal überhaupt einen Puls haben bevor ich die genauen
werte berechne.
3 dinge die mir aufgefallen sind:
1- Du startest Timer0 nicht (daher keinen interrupts)
2- Du sollst den Timer0 Int Flag am ende des ISR wieder löschen.
3- Wenn Timer1 geschrieben wird ist es empfohlen den Timer vorher
anzuhalten.
Stefan Haussmann schrieb:> Wie Starte ich Timer0?? ich hab da so nichts gefunden
Sorry hast recht, dachte an einen anderen PIC gerade.
Ich hab dein SW ein wenig angepasst. Es ist noch ungetestet da ich
keinen 12F675 da habe, aber vom Prinzip soll es gehen.
Ich glaub dein problem lag an den "TMR1IF". Anderseits sagts du
"T0IF_bit". Ich benutze den HiTech compiler zu wenig um das richtige zu
erkennen, also bitte nachschlagen.
------------------------------------------------------------------------
--
int Count; //Zähler für durchläufe
void Init()
{
ANSEL=0;
CMCON=7;
TRISIO=0;
OPTION_Reg=0b11000111;
/* 1-------; Betrifft nicht Timer0
-1------; Betrifft nicht Timer0
--0-----; Intern Takt für Timer0 verwenden
---0----; Bei ext. Takt b. stg Flanke inkr. (nicht
relevant)
----0---; Prescaler für Timer 0 verwenden
-----111; Prescaler (1:256)
*/
T0IF_bit=0; //Timer0 Interrupt Flag löschen
T1IF_bit=0; //Timer1 Interrupt Flag löschen
T0IE_bit=1; //Timer0 Interrupt erlauben
T1IE_bit=1; //Timer1 Interrupt erlauben
TMR0=180; // Timer0 Value
}
static void interrupt (void) //ISR
{
if (T0IF_bit) // Timer0 überlauf
{
GP2_bit=1; //Ausgang auf 1
TMR1H=253; //High Byte berechnen
TMR1L=232; //Low Byte berechnen
//Timer1 Starten
T1CON=0b00000001;
/* 0-------; Nicht relevant
-0------; Nicht relevant
--00----; Precsaler (1:1)
----0---; Sync. m. ext. Takt (Hier nicht relevant)
-----0--; Internet Tackt verwenden
-------1; Timer starten
*/
T0IF_bit=0; //Timer0 Interrupt Flag löschen
}
if (T1IF_bit) // Timer1 überlauf
{
GP2_bit=0; //Ausgang auf 0
Count++; //Zähler um 1 erhöhen
//Timer1 Stoppen
T1CON=0b00000000;
T1IF_bit=0; //Timer1 Interrupt Flag löschen
}
}
void main()
{
Init();
GIE_bit=1; //Alle unmaskierten interrupts erlauben
while(1) {}
}
----------------------------------------------------------------------
Stefan Haussmann schrieb:> Wie Starte ich Timer0?? ich hab da so nichts gefunden
RTFM Seite 29
> Timer mode is selected by clearing the T0CS bit> (OPTION_REG<5>).
Das ist dein erstes Kommando
> In Timer mode, the Timer0> module will increment every instruction cycle (without> prescaler).
Das macht er dann
> Counter mode is selected by setting the T0CS bit> (OPTION_REG<5>). In this mode, the Timer0 module> will increment either on every rising or falling edge of> pin GP2/T0CKI.
Das willst du nicht
> 4.2 Timer0 Interrupt> A Timer0 interrupt is generated when the TMR0> register timer/counter overflows from FFh to 00h. This> overflow sets the T0IF bit
Das Flag kannst du ohne Interrupt Abfragen.
Stefan Haussmann schrieb:> Ich hoffe dass es in diesem Forum einige Experten gibt, die mir einen> kleinen C-Code zukommen lassen könnten.> http://forum.htsoft.com/all/showflat.php?
Cat=0&Board=pic&Number=193402&Searchpage=1&Main=193122&Words=+NexxuSix&t
opic=&Search=true
Google: code example 12F675 hightech c (1 Eintrag)
Hey PICfan,
du bist klasse...das ding funktioniert...du bist einer der ersten die
mal konkret gesagt haben wo das Problem liegt und was zu tun ist. Dass
du das Pgogramm selber geändert hast finde ich riesig. Danke
Hi, um niedrigere Frequenzen zu
Stefan Haussmann schrieb:> Kann ich einzelne ports so ansprechen?:>> GPIO3=1;>> oder muss ich das hier anders machen (beim 16F84 sind die Bezeichnungan> ja RA, beziehungsweise RB...)
Also wenn du schon für die einfachsten Fragestellungen die Hilfe vom
Forum benötigst, dann wirst du es nicht weit bringen.
Willst du denn dann dein gesamtes Projekt durch Foren zusammenpicken?
Es gibt doch noch ein kleines Problem...ich erhalte mit dem Programm
eine gleichmäßige Pulsfolge, kann aber die Hochzeit nicht einstellen.
Irgend was ist da noch faul. Ich habe den Timer0 jetzt auf etwa 15ms
eingestellt.
Nun erhalte ich 15ms low und 15ms high...
Stefan Haussmann schrieb:> Nun erhalte ich 15ms low und 15ms high
Wenn du z.B den Pin nur toggelst
GPIOx != GPIOx
kann nur ein symmetrisches Puls/Pausenverhältnis rauskomnmen.
Der Rächer der Transisitormorde schrieb:> Stefan Haussmann schrieb:>> Nun erhalte ich 15ms low und 15ms high>> Wenn du z.B den Pin nur toggelst>> GPIOx != GPIOx>>> kann nur ein symmetrisches Puls/Pausenverhältnis rauskomnmen.
Also das klingt zwar gut aber ich weiß nicht was du meinst...
Hallo...
Also jetzt tick ich demnächst aus.
Ich hab eine Schaltung aufgebaut, so wie im Anhang.
Allerdings habe ich das Problem, dass ich aus irgend einem Grund die
Eingangssignale nicht lesen. Ich verwende folgende Konfiguration:
was ist des eigentlich für eine Abschlussarbeit?
Tüftelst du da jetzt schon 3 Monate an dem Problem?
Zeig halt mal dein ganzes Programm. Vielleicht ist ja auch die Abfrage
falsch...
Das mit dem Servo ist nur Bonus...also das sahnehäubchen...das wollt ich
nebenher machen...jetzt bin ich mit dem andern zeug fertig, doku ist
auch fast fertig und jetzt will ich das auch noch auf die reihe kriegen.
Also das Programm funktioniert auf der Vellemann-Entwicklungsplatine,
aber bei meiner selbst gelöteten schaltung ist das net so :-)
Das hier ist das Vollständige Programm:
Stefan Haussmann schrieb:> void main() //MAIN LOOP> {> Init(); //Konfiguration ausführen> } //END MAIN LOOP
Das ist keine Main-Loop, sondern eine Main-Funktion, die einmal
durchläuft. Da du kein "while(1);" drin hast, ist das Programm durch und
ist entweder irgendwo im undefinierten Programmspeicher oder aber am
Ende.
Stefan Haussmann schrieb:> counter=RateOfChange
Dir ist bewusst, dass das eine Zuweisung ist und kein Vergleich auf
Gleichheit? Meist wird in if-Bedingungen ja geprüft ob es gleich ist.
Stefan Haussmann schrieb:> if((HighTime<HighTimeMax)&&(counter=RateOfChange))> {> Hightime++; //Impuls verlängern> }>> if (Hightime==HighTimeMax) //Hochzeit erreicht?> {> GPIO.B1=1; //Ausgang HALTESIGNAL setzen> }> else> {> GPIO.B1=0; //Ausgang HALTESIGNAL löschen> }>> if (GPIO.B5==1) //Prüfen ob Reset Taster==1> {> Hightime=HighTime; //HighTime auf Startwert setzen> }
Also wenn ich das Programm richtig verstehe, dann müsste es hier überall
statt HighTime nur Time heißen, außer ganz unten dann time = HighTime.
Damit wäre Time die Variable, die hochgezählt wird und die immer größer
werdende Zeit, wielange das signal auf high ist und HighTime wäre der
Startwert (der demnach nicht hochgezählt werden soll). Doch dann muss
das Time = Hightime ganz oben weg, denn dann überschreibst du das
hochgezählte immer wieder mit dem Startwert. Dann müsste aber Time bei
der Definition den Startwert bekommen.
Wenn du das so wie oben geschrieben behalten willst, brauchst du eine
Variable mit dem Startwert der Hightime, den du nicht veränderst (so wie
im moment mit "HighTime++;"). Dann wäre aber folgendes überflüssig:
Stefan Haussmann schrieb:> Time=HighTime; //Timer auf High Pulslänge setzen> TMR1H=(65536-Time)/256; //Highbyte setzen> TMR1L=(65536-Time)%256; //Lowbyte setzen
Denn dann könntest du auch schreiben:
> TMR1H=(65536-HighTime)/256; //Highbyte setzen> TMR1L=(65536-HighTime)%256; //Lowbyte setzen
Und wenn du das so änderst und die Variable für den Startwert
hinzufügst, wirst du sehen, es ist genau das gleiche wie ich davor
beschrieben hab, nur dass die Variablen-Namen anders sind;)
Ansich ja. Ist die Schaltung da mit Target gezeichnet? Wenn ja ist
meines Wissens so ein Quadrat mit nem Kreuz drin ein Fehler, also keine
Verbindung oder zu dicht etc.
Ist deine Platine geätzt oder gefräst oder so iwie mit Lochraster. Wenns
bei einer Platine funktioniert und bei einer anderen nicht, liegt es
meist bei der Platine. Wobei ich bezweifle, dass das Programm da oben so
funktioniert, wie es soll.
Haha...ich hab das vorhin schnell abgezeichnet von meinem Blockblatt
gg....hab das mit Silberdraht gelötet. Und ja.....es ist Target.
Das dauert noch bis die Platine Ätzfertig ist...