volpi
13.08.2014, 12:43
Hallo zusammen,
ich habe eine Funktion erstellt welche ein PPM Signal für den Trainerport meiner Futaba Funke erzeugt. Das Startsignal ist ein 0,4ms LOW gefolgt von dem ersten HIGH Signal für Kanal 1 (0,7ms - 1,54ms). Das ganze Wiederholt sich bis wir an Kanal 8 angekommen sind. Nach Kanal 8 kommt nochmal ein 0,4ms LOW Signal welches in einem 11ms langen HIGH Signal endet. Das ganze fängt dann wieder von vorne an.
Es wird also mit sehr kurzen Timings gearbeitet. Sodass der Interrupt nur 210x im Bereich von 0,7ms bis 1,54ms getriggt wird. Ich benutze Timer0 im CTC Modus, ohne Prescale. Den gewünschten Endwert von 64 habe ich das Register OCR0 geladen. Soweit funktioniert auch alles. Wenn ich nun eine 32 als gewünschten Endwert wähle sollte der Interrupt ja nun 2x 210x also 410x durchlaufen werden. Irgendwie funktioniert das Programm dann aber nicht mehr.
Ich benutze einen ATmega32 mit 16MHz Quarz. Fuses sind gesetzt. Das Signal prüfe ich mit einem Logic Analysator. Der Code schaut folgendermaßen aus:
#define F_CPU 16000000L
#include <avr/io.h>
#include <avr/interrupt.h>
void g_ppm(int Kanal[]);
void init();
int Werte[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile int counter = 0;
int main(void)
{
init();
while(1)
{
g_ppm(Werte);
}
}
void init(void)
{
DDRD = 0xFF;
PORTD = (1<<PD0);
sei();
TCCR0 = (1<<WGM01); // CTC Modus
TCCR0 |= (1<<CS00); // Kein Prescale - CPU Takt
OCR0 = 64; // Endwert
TIMSK |= (1<<OCIE0); // Compare Interrupt erlauben
}
void g_ppm(int Kanal[])
{
counter = 0;
do // Startsignal
{
PORTD = (0<<PD0);
} while (counter != 100); // 100 = 0,4ms
for (int i = 0; i <= 7; i++)
{
counter = 0;
do // Signal
{
PORTD = (1<<PD0);
} while (counter != Kanal[i]+175 );
counter = 0;
do // Pause
{
PORTD = (0<<PD0);
} while (counter != 100); // 100 = 0,4ms
}
do // Endsignal
{
PORTD = (1<<PD0);
} while (counter != 2800); // 2750 = 11ms
}
ISR (TIMER0_COMP_vect)
{
counter++;
}
Meine Frage lautet nun:
Wieso funktioniert das Programm nicht, wenn ich den Endwert auf 32 neheme?
Liebe Grüße
volpi
ich habe eine Funktion erstellt welche ein PPM Signal für den Trainerport meiner Futaba Funke erzeugt. Das Startsignal ist ein 0,4ms LOW gefolgt von dem ersten HIGH Signal für Kanal 1 (0,7ms - 1,54ms). Das ganze Wiederholt sich bis wir an Kanal 8 angekommen sind. Nach Kanal 8 kommt nochmal ein 0,4ms LOW Signal welches in einem 11ms langen HIGH Signal endet. Das ganze fängt dann wieder von vorne an.
Es wird also mit sehr kurzen Timings gearbeitet. Sodass der Interrupt nur 210x im Bereich von 0,7ms bis 1,54ms getriggt wird. Ich benutze Timer0 im CTC Modus, ohne Prescale. Den gewünschten Endwert von 64 habe ich das Register OCR0 geladen. Soweit funktioniert auch alles. Wenn ich nun eine 32 als gewünschten Endwert wähle sollte der Interrupt ja nun 2x 210x also 410x durchlaufen werden. Irgendwie funktioniert das Programm dann aber nicht mehr.
Ich benutze einen ATmega32 mit 16MHz Quarz. Fuses sind gesetzt. Das Signal prüfe ich mit einem Logic Analysator. Der Code schaut folgendermaßen aus:
#define F_CPU 16000000L
#include <avr/io.h>
#include <avr/interrupt.h>
void g_ppm(int Kanal[]);
void init();
int Werte[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile int counter = 0;
int main(void)
{
init();
while(1)
{
g_ppm(Werte);
}
}
void init(void)
{
DDRD = 0xFF;
PORTD = (1<<PD0);
sei();
TCCR0 = (1<<WGM01); // CTC Modus
TCCR0 |= (1<<CS00); // Kein Prescale - CPU Takt
OCR0 = 64; // Endwert
TIMSK |= (1<<OCIE0); // Compare Interrupt erlauben
}
void g_ppm(int Kanal[])
{
counter = 0;
do // Startsignal
{
PORTD = (0<<PD0);
} while (counter != 100); // 100 = 0,4ms
for (int i = 0; i <= 7; i++)
{
counter = 0;
do // Signal
{
PORTD = (1<<PD0);
} while (counter != Kanal[i]+175 );
counter = 0;
do // Pause
{
PORTD = (0<<PD0);
} while (counter != 100); // 100 = 0,4ms
}
do // Endsignal
{
PORTD = (1<<PD0);
} while (counter != 2800); // 2750 = 11ms
}
ISR (TIMER0_COMP_vect)
{
counter++;
}
Meine Frage lautet nun:
Wieso funktioniert das Programm nicht, wenn ich den Endwert auf 32 neheme?
Liebe Grüße
volpi