Hallo Ich brauche dringend eure Hilfe. Ich arbeite momentan an einem Projekt. Ziel dieses Projektes ist es eine Sende/Empfangseinrichtung für ein RC car zu bauen.mit dieser soll 1 Servo und 1 fahrtregler per PWM gesteuert werden. Mithilfe der von Microchip Solutions mitgelieferten Mikrocontroller Firmware habe ich es bereits geschafft code vom PC zum uc über den usb serial emulator zu senden. Leider habe ich zu spät gemerkt das der PIC18 keine Hardware PWM mit 20ms Periodenlänge unterstützt. Nach ca 3h googlen mit einem Freund haben wir versucht anhand dieser Anleitung http://www.ermicro.com/blog/?p=771 eine Interruptgesteuerte PWM zu Programmieren. Leider ist uns das nicht gelungen. Könnt ihr mir sagen was wir falsch gemacht haben? Hier der code: [c]void Interrupt_PWM (void); // Interupts #pragma code _HIGH_INTERRUPT_VECTOR = 0x000808 void _high_ISR (void) { _asm goto Interrupt_PWM _endasm } #pragma code _LOW_INTERRUPT_VECTOR = 0x000818 void _low_ISR (void) { _asm goto Interrupt_PWM _endasm } #pragma code /** I N C L U D E S **********************************************************/ #include <p18cxxx.h> #include <usart.h> #include <delays.h> #include "system\typedefs.h" #include "system\usb\usb.h" #include "io_cfg.h" // I/O pin mapping #include "user\user.h" /** V A R I A B L E S ********************************************************/ #pragma udata char input_buffer[64]; char output_buffer[64]; unsigned int counter; int NurEinmal = 1; int Puls_Max = 0; int Puls_Top = 0; int Top_Wert = 0; const int Max_Wert = 200; /** P R I V A T E P R O T O T Y P E S ***************************************/ void BlinkUSBStatus(void); void User_Process(void); void SendADC(void); void ReadPOT(void); #pragma code void UserInit(void) { mInitAllLEDs(); mInitPOT(); ADCON2bits.ADFM = 1; // ADC result right justified }//end UserInit void ReadPOT(void) { ADCON0bits.GO = 1; // Start AD conversion while(ADCON0bits.NOT_DONE); // Wait for conversion return; }//end ReadPOT void SendADC(void) { ReadPOT(); input_buffer[0] = ADRESH; input_buffer[1] = ADRESL; if(mUSBUSARTIsTxTrfReady()){ mUSBUSARTTxRam((byte*)input_buffer,2); } } void Interrupt_PWM (void) { Puls_Max++; Puls_Top++; if (Puls_Max >= Max_Wert) { Puls_Max = 0; Puls_Top = 0; PORTCbits.RC2 = 0; PORTBbits.RB7 = 1; } if (Puls_Top == Top_Wert) { PORTCbits.RC2 = 1; } if (Puls_Max == 100) { PORTBbits.RB7 = 0; } INTCONbits.TMR0IF = 0; } //pwm /*void init_pwm(void){ TRISCbits.TRISC2 = 0; PORTCbits.RC2 = 1; PR2 = 0b00001110; T2CON = 0b00000111; CCP1CON = 0b00011100; } void User_Process(void) { // FOSC/4 PS TMR0 if (NurEinmal = 1) { TRISB = 0x00; T0CON = 0b10001000; TMR0H = 0b00000100; TMR0L = 0b11000100; INTCONbits.TMR0IF = 0; INTCONbits.TMR0IE = 1; INTCONbits.GIE = 1; Puls_Max = 0; Puls_Top = 0; Top_Wert = Max_Wert; NurEinmal = 0; }[c/]
Boah Leute, das wurde im Microchip-Forum rauf und runter diskutiert, wie man eine 20 ms Periode erreichen kann...
Danke Da werde ich mich jetzt erstmal reinlesen. Und sorry bin erst seid heute hier im Forum angemeldet.Ich hatte eig die sufu verwendet,aber bin auf nichts brauchbares gestoßen. Liegt warscheinlich daran weil das alles noch recht neu ist für mich^^.
Das hat ja nichts mit diesem Forum zu tun. ;) Aber da haste erstmal was zu lesen. Ich empfehle dir die "steering method", wirst beim Lesen dann schon sehen was das ist. Bevor du das dann in den PC reinhackst, empfehle ich dir zusätzlich noch einen Programmablaufplan vor der Programmierung zu erstellen. Viel Spaß!
So, ich hab mir das jetzt alles mal durchgelesen . Aber irgendwie werde ich jetzt noch nicht wirklich schlau daraus. Das Problem ist das ich diese pwm dringend brauche da das Projekt ein Schulprojekt ist und ich schon ganz schön im Zeit Stress bin. Deswegen habe ich nochmal ein bisschen was gebastelt. Aber leider ohne erfolg. Für das Projekt ist es egal ob der Code optimiert ist oder wie fein die pwm ist. Die pwm muss einfach für 10 min(die Präsentation) laufen. Später wenn ich die Zeit dafür habe bin ich der letzte der nein sagt und will die pwm auch "richtig" machen. Könntest du bitte mal über den hier Angehängten code schauen und mich berichtigen bzw sagen ob die pwm überhaupt auf diese weise funktionieren kann?
Nur weil du eine Funktion Interrupt_PWM nennst, heißt das nicht dass sie durch ein Interrupt aufgerufen wird! Weißt du eigentlich was ein Interrupt ist? Bei den PIC18 gibt es nur zwei verschiedene Interruptadressen für die zwei verschiedenen Prioritäten von Interrupts. In deinem Programm sind dafür schon die Interrupt-Service-Routinen dafür angelegt. Sie heißen _high_ISR und _low_ISR. Jetzt musst halt schauen, wie es eingestellt ist, ob Timer0 die hohe oder die niedrige Priorität bei einem Interrupt auslöst.
Wenn der Controller eh nichts anderes macht ausser den Servo anzusteuern und du vom Programmieren auch keine Erfahrung hast, dann mach es doch so, dass du den Ausgang setzt und über entsprechende Zeitfunktionen deine gewünschten 1-2ms wartest und dann den Pin wieder zurücksetzt. Danach wartest du 18ms.
Ja das stimt leider nicht ganz ich muss wie in meinem 1. Post gesagt 1 Servo und 1 Fahrtregler ansteuern die Stellung der "servos" bestimme ich über die Softwarekomponente am pc
Ahh mist ich habe dein vorherigen Post zu spät gesehen.
Sorry wenn ich mich irre aber eigendlich dachte ich das ich das high
interupt richtig "konfiguriert" habe
siehe hier:
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
_asm goto Interrupt_PWM _endasm
}
Laut meiner interpretation des Programmes müsste ich mit der zuvor
angehängten Datei eine Pwm mit 20ms Periodenlänge und 1.5ms Duty Cycle
erzeugen.
PS:Ich weis schon was ein interrupt ist, allerdings heißt das nicht das
ich es auch direkt fehlerfrei im Code anwenden kann.^^
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.