FeuerTobi
28.10.2008, 01:07
Hallo!
Ich hab mich jetz doch tatsächlich an die µC Programmierung gewagt und muss sagen: Ihr habt recht! Soo schwer is es nicht. Man muss sich nur rantrauen.
Der Elektriker in unserer Werkstatt hat mich mit Testboard und einem Pic ausgerüstet hat und der Software zum C programmieren. Es kann losgehen!
Ich möchte jetz gern einen Servo schwenken lassen, je nachdem wie weit ich an einem Poti (steuerknüppel aus einer alten Fernbedienung) schiebe.
Das bestehende Grundprogramm hab ich soweit geändert/ ergänzt, dass es mir passt. Allerdings reagiert der Servo nicht so schnell auf eine Potiänderung. Außerdem ruckelt/korrigiert er auch in Ruheposition manchmal rum.
Woran liegt das, bzw. wie kann ich es besser machen?
/*Grundprogramm für PIC 12F629/675
zum Einlesen eines Analogwertes mit Anzeige auf dem LC-Display
belegt min.4 max.5 Ausgänge
825 Codewords
30 Bytes RAM
//Pinbelegung des 12F629: Funktion:
//Pin1 VPP +5V +5V
//Pin2 GP5 IOP INT on Ch./T1CKI/OSC1 in out Funktion5 SI Serielle Daten
//Pin3 GP4 AIOP INT on Ch./T1G/OSC2 in out Funktion4 CLK Serieller Takt
//Pin4 GP3 I INT on Ch./MCLR\ in Funktion3
//Pin5 GP2 AIOP INT on Ch./Cout/INT/T0CIin out Funktion2 RS Daten(1)/Steuerzeichen(0)
//Pin6 GP1 AIOP INT on Ch./Cin-/Vref+ in out Funktion1 Servo
//Pin7 GP0 AIOP INT on Ch./Cin+ in out Funktion0 AD-Kanal 0
//Pin8 Gnd 0V GND
*/
#pragma config |=0b000.1.1.1.0.0.0.100
// ||| | | | | | | +++----Oscillator Selection Bits (100=intern)
// ||| | | | | | |+-------Watchdog timer (1=enable)
// ||| | | | | +----------Power up timer (0=enable)
// ||| | | | +------------MCLR\ select *) (0:RA5=IO; 1:RA5=MCLR\)
// ||| | | +--------------Brown out reset (1=enable)
// ||| | +----------------Flash-Programm memory protection(0=enable)
// ||| +------------------EE-Prom memory code protected (0=enable)
// +++--------------------nicht implementiert
// Konstanten Portzuweisung I/O Funktionsbeschreibung
bit SI @ GPIO.5; //I/O Serial Input
bit CLK @ GPIO.4; //I/O Clock
//bit Taste_3 @ GPIO.3; //I
bit RS @ GPIO.2; //I/O Daten/Steuerzeichen (Da=1; St=0)
bit Servo @ GPIO.1; //I/O Hintergrundbeleuchtung (Option)
//bit CSB @ GPIO.0; //I/O Analogkanal
#include "delay4.c" //Timer0 wird verwendet
#include "LC_Display.c" //LC-Display Hilfsprogramme
#include "AD_Wandler.c" //AD-Wandler Hilfsprogramme
//#include "MATH24F.H" //Mathematikroutinen
// Variablen Funktionsbeschreibung
uns16 Z; //Zählervariable
uns16 i;
uns16 AD_wert; //eingelesener AD-Wert
uns16 Wert;
//float24 U;
//-------------------Hauptprogramm-------------------------------------------------------------
void main(void)
{
//-------------------Konfiguration des PIC
//Anm.: Erst Ausgänge setzen, dann Konfigurieren (wg. Spikes)
GPIO= 0b.00.00.0.000; //Port Grundeinstellungen Statusregister
TRISIO= 0b.00.00.1.001; //Port Eingänge definieren (1=Eingang; 0=Ausgang)
//--------------------AD-Wandler, nicht relevant für 12F629
ADCON0=0b.10.00.0001; //AD-Wandler konfigurieren
ANSEL=0b.0.001.0001; //Bit 0..3: GPIO 0..3=Analog(=1) / Digital(=0) Bit4..6:AD Clock
//--------------------Komperator
CMCON=0b.0.0.0.00111; //Komperator aus
//-------------------Timer 0 (8bit)
T0CS=0; //Timer0 externen/internen Takt verwenden (1=extern; 0=intern)
PSA=0; //Vorteiler: 1=WDT zuordnen; 0=Timer0 zuordnen
PS2=0; //Vorteiler: Teilerwert PS2..PS0; Tabelle gilt für Timer0,
PS1=0; //000=1:2; 001=1:4; 010=1:8; 011=1:16;
PS0=1; //100=1:32; 101=1:64; 110=1:128; 111=1:256;
T0IE=0; //Timer0 Interrupt erlauben (1=ja; 0=nein)
//--------------------Konfiguration der Variablen
//Z=0;
Servo=0;
//CSB=0; //Chipselect ein (Option)
//LCD_Init(); //LCD Anzeige initialisieren
//LCD_Back=1; //LCD Hintergrundbeleuchtung einschalten (Option)
ruecksprung:
//Hauptprogramm
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//U=AD_wert/10.23;
//U=U*25;
//Wert=U;
//ZahlString(' ',AD_wert,"mm",5,0,',',0,0,0);
//ZahlString(' ',Z," km/h",4,2,',',0,0,6);
//Vorz.,Zahl,Einheit,Stellen[1..5],Vorkommastellen,Trennzeichen,V.Nullen[0=nein,1=ja],Zeile,Position
Delay1ms(14);
AD_wert=Analogwert(0); //Kanal 0 einlesen
AD_wert=AD_wert/12;
Servo=1; //Servo bekommt Signal
i=0;
for (i=0; i<95; i++) //Signal soll gehalten werden bis i zu 60 hochgezählt hat: 60 ist starker Linksausschlag
{;} //für einen SchleifenDurchgang braucht er 12µs. 1000µs:12=85,3 also i gleich 85 setzten um 1 ms zu bekommen
//nop(); //No operation lässt µC genau 1 µs warten
//i=0;a
//while (i<AD_wert) {i++;}
for (i=0; i<AD_wert; i++) // Er braucht 85 Schleifen um 1ms zu warten. Der AD_Wert vom Poti kann 0 bis 1024 betragen. --> 1024/85
{;}
Servo=0; //Signal wird abgesetzt. Servo hat also 1 PWM Signal bekommen
//Z++; //Zählervariable inkrementieren
LCDPos(1,2);
LCDWriteByte ('+'); //Einzelzeichen darstellen
LCDWriteString ("Systemdynamik"); //Text ausgeben
//Delay1ms(50);
goto ruecksprung;
}
Bin für eure Hilfe dankbar,
Tobi
Ich hab mich jetz doch tatsächlich an die µC Programmierung gewagt und muss sagen: Ihr habt recht! Soo schwer is es nicht. Man muss sich nur rantrauen.
Der Elektriker in unserer Werkstatt hat mich mit Testboard und einem Pic ausgerüstet hat und der Software zum C programmieren. Es kann losgehen!
Ich möchte jetz gern einen Servo schwenken lassen, je nachdem wie weit ich an einem Poti (steuerknüppel aus einer alten Fernbedienung) schiebe.
Das bestehende Grundprogramm hab ich soweit geändert/ ergänzt, dass es mir passt. Allerdings reagiert der Servo nicht so schnell auf eine Potiänderung. Außerdem ruckelt/korrigiert er auch in Ruheposition manchmal rum.
Woran liegt das, bzw. wie kann ich es besser machen?
/*Grundprogramm für PIC 12F629/675
zum Einlesen eines Analogwertes mit Anzeige auf dem LC-Display
belegt min.4 max.5 Ausgänge
825 Codewords
30 Bytes RAM
//Pinbelegung des 12F629: Funktion:
//Pin1 VPP +5V +5V
//Pin2 GP5 IOP INT on Ch./T1CKI/OSC1 in out Funktion5 SI Serielle Daten
//Pin3 GP4 AIOP INT on Ch./T1G/OSC2 in out Funktion4 CLK Serieller Takt
//Pin4 GP3 I INT on Ch./MCLR\ in Funktion3
//Pin5 GP2 AIOP INT on Ch./Cout/INT/T0CIin out Funktion2 RS Daten(1)/Steuerzeichen(0)
//Pin6 GP1 AIOP INT on Ch./Cin-/Vref+ in out Funktion1 Servo
//Pin7 GP0 AIOP INT on Ch./Cin+ in out Funktion0 AD-Kanal 0
//Pin8 Gnd 0V GND
*/
#pragma config |=0b000.1.1.1.0.0.0.100
// ||| | | | | | | +++----Oscillator Selection Bits (100=intern)
// ||| | | | | | |+-------Watchdog timer (1=enable)
// ||| | | | | +----------Power up timer (0=enable)
// ||| | | | +------------MCLR\ select *) (0:RA5=IO; 1:RA5=MCLR\)
// ||| | | +--------------Brown out reset (1=enable)
// ||| | +----------------Flash-Programm memory protection(0=enable)
// ||| +------------------EE-Prom memory code protected (0=enable)
// +++--------------------nicht implementiert
// Konstanten Portzuweisung I/O Funktionsbeschreibung
bit SI @ GPIO.5; //I/O Serial Input
bit CLK @ GPIO.4; //I/O Clock
//bit Taste_3 @ GPIO.3; //I
bit RS @ GPIO.2; //I/O Daten/Steuerzeichen (Da=1; St=0)
bit Servo @ GPIO.1; //I/O Hintergrundbeleuchtung (Option)
//bit CSB @ GPIO.0; //I/O Analogkanal
#include "delay4.c" //Timer0 wird verwendet
#include "LC_Display.c" //LC-Display Hilfsprogramme
#include "AD_Wandler.c" //AD-Wandler Hilfsprogramme
//#include "MATH24F.H" //Mathematikroutinen
// Variablen Funktionsbeschreibung
uns16 Z; //Zählervariable
uns16 i;
uns16 AD_wert; //eingelesener AD-Wert
uns16 Wert;
//float24 U;
//-------------------Hauptprogramm-------------------------------------------------------------
void main(void)
{
//-------------------Konfiguration des PIC
//Anm.: Erst Ausgänge setzen, dann Konfigurieren (wg. Spikes)
GPIO= 0b.00.00.0.000; //Port Grundeinstellungen Statusregister
TRISIO= 0b.00.00.1.001; //Port Eingänge definieren (1=Eingang; 0=Ausgang)
//--------------------AD-Wandler, nicht relevant für 12F629
ADCON0=0b.10.00.0001; //AD-Wandler konfigurieren
ANSEL=0b.0.001.0001; //Bit 0..3: GPIO 0..3=Analog(=1) / Digital(=0) Bit4..6:AD Clock
//--------------------Komperator
CMCON=0b.0.0.0.00111; //Komperator aus
//-------------------Timer 0 (8bit)
T0CS=0; //Timer0 externen/internen Takt verwenden (1=extern; 0=intern)
PSA=0; //Vorteiler: 1=WDT zuordnen; 0=Timer0 zuordnen
PS2=0; //Vorteiler: Teilerwert PS2..PS0; Tabelle gilt für Timer0,
PS1=0; //000=1:2; 001=1:4; 010=1:8; 011=1:16;
PS0=1; //100=1:32; 101=1:64; 110=1:128; 111=1:256;
T0IE=0; //Timer0 Interrupt erlauben (1=ja; 0=nein)
//--------------------Konfiguration der Variablen
//Z=0;
Servo=0;
//CSB=0; //Chipselect ein (Option)
//LCD_Init(); //LCD Anzeige initialisieren
//LCD_Back=1; //LCD Hintergrundbeleuchtung einschalten (Option)
ruecksprung:
//Hauptprogramm
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//U=AD_wert/10.23;
//U=U*25;
//Wert=U;
//ZahlString(' ',AD_wert,"mm",5,0,',',0,0,0);
//ZahlString(' ',Z," km/h",4,2,',',0,0,6);
//Vorz.,Zahl,Einheit,Stellen[1..5],Vorkommastellen,Trennzeichen,V.Nullen[0=nein,1=ja],Zeile,Position
Delay1ms(14);
AD_wert=Analogwert(0); //Kanal 0 einlesen
AD_wert=AD_wert/12;
Servo=1; //Servo bekommt Signal
i=0;
for (i=0; i<95; i++) //Signal soll gehalten werden bis i zu 60 hochgezählt hat: 60 ist starker Linksausschlag
{;} //für einen SchleifenDurchgang braucht er 12µs. 1000µs:12=85,3 also i gleich 85 setzten um 1 ms zu bekommen
//nop(); //No operation lässt µC genau 1 µs warten
//i=0;a
//while (i<AD_wert) {i++;}
for (i=0; i<AD_wert; i++) // Er braucht 85 Schleifen um 1ms zu warten. Der AD_Wert vom Poti kann 0 bis 1024 betragen. --> 1024/85
{;}
Servo=0; //Signal wird abgesetzt. Servo hat also 1 PWM Signal bekommen
//Z++; //Zählervariable inkrementieren
LCDPos(1,2);
LCDWriteByte ('+'); //Einzelzeichen darstellen
LCDWriteString ("Systemdynamik"); //Text ausgeben
//Delay1ms(50);
goto ruecksprung;
}
Bin für eure Hilfe dankbar,
Tobi