PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer Problem



Funky
18.07.2006, 08:20
Hallo,

ich habe ein Programm für einen Atmega48 geschrieben welches mir ein Signal mit welchselden Impulslängen erzeugen soll. Bis zu 2 Werten klappt alles wunderbar und ich bekomme ein sauberes Signal. Nur sobald es mehr werden überlagern sich die Signale. Hat jemand ne Ahnung woran das liegen kann....??


#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char Preloads[] = {15, 100, 20, 100, 20, 100, 20, 100, 20, 100, 20, 100, 5, 100, 5, 200};
unsigned char NrOverflow = 0;


ISR(TIMER2_COMPA_vect)
{
PORTB =~ PORTB; // PORTB inventieren

NrOverflow++;
if( NrOverflow == 16)
NrOverflow = 0;


OCR2A = Preloads[ NrOverflow ]; // Den Timer damit laden

}

int main()
{

DDRB = 0xFF; // PORTB als Ausgang schalten
PORTB = 0x00; // Alle Ausgaenge auf 0 schalten


TCCR2B |= (1 << CS21); // Teiler 8

TCCR2A |= (1 << WGM21); // CTC Modus

TIMSK2 |= (1 << OCIE2A); // Timer 2 Compare Interrupt enable


sei(); // Interrupts einschalten

while(1); //ever
}

Gruß Funky

SprinterSB
18.07.2006, 09:04
Zum Kommentar "PortB invertieren" passt eher ein


PORTB = !PORTB;

nochn Tip:

Anstatt der magischen 16 die aufn ersten Blick vom Himmel fällt geht auch ein


sizeof (Preloads) / sizeof (unsigned char)

das ist was mehr zu tippseln, wertet aber ebenfalls zu einer Konstanten aus. Diese ist immer die Länge deines Arrays!

Funky
18.07.2006, 09:19
Danke für den Tip!

Das mit dem sizeof ist echt ne gute Idee!

Das Problem mit dem Timer ist auch gelöst, lag an der Triggerung....!!

Gruß Funky

SprinterSB
18.07.2006, 09:21
ginge auch so:


sizeof (Preloads) / sizeof (Preloads[0])

dann ist's auch vom Typ das Arrays unabhängig :-)

Funky
18.07.2006, 12:16
Wie kann ich denn dem ganzen Array neue 'Werte geben, z.B. in einer
switch-anweisung?

Bekomme da immer Fehlermeldungen.......

SprinterSB
18.07.2006, 13:42
zeich ma den Code

Funky
18.07.2006, 14:02
//Interrupt UART
SIGNAL(SIG_USART_RECV)
{

unsigned char buffer;

if(UCSR0A & (1 << RXC0)) {


buffer = UDR0;

switch(buffer) {

case '1': // LED ein/ausschalten
if (PORT_LED & (1 << PB2))

PORT_LED &= ~(1 << PB2);
else
PORT_LED |= (1 << PB2);
break;

case '2': // OutputCompare1A Interrupt aktivieren
f (TIMSK1 & (1<< OCIE1A))

TIMSK1 &= ~(1 << OCIE1A);
else
TIMSK1 |= (1 << OCIE1A);
break;

case '3': //neue Werte ins Array laden
????????????????????????????
break;

default:
break;
}

}
}

Gehört zu obigen Code, den UART und den anderen Timer hab mal weggelassen. Nun soll er bei case '3', andere Werte in das Array
Preloads[] schreiben. Nur irgendwie haut das nicht hin........

SprinterSB
18.07.2006, 14:48
Preloads[1] = 42;

-- schreib mal if anstatt f
-- rück mal gscheit ein, sons blickst nimmer was abgeht

Wär übrigens hilfreich die Fehlermeldung zu sehen anstatt ein "es geht nix"

Funky
24.07.2006, 13:17
Hi Sprinter,

bin jetzt wieder da! Ein paar Tage Urlaub haben richtig gut getan.

Das i bei der if-Anweisung hab ich wohl beim kopieren vergessen.

Das mit den Werten ins Array schreiben klappt nun auch, hatte versucht mit einem Befehl sofort 16 Werte neu ins Array zu scvhreiben. Geht halt wohl nur bei der Initialisierung. Hab es jetzt mit

Preloads[...] = ...;

gemacht, klappt alles bestens.

Hab nun versucht einen Servo(kein Standard) anzusteuern. Dieser benötigt 8Bit + ein Startbit.

Die Ansteuerung klappt soweit, nur nach dem Einschalten
zittern die Servos. Wenn ich sie dann über ein gesendetes Zeichen in die
gewünschte Stellung bringen will, klappt das nur ab und zu. Nach ein
paar gesendeten Zeichen hört das zittern irgendwann auf und es klappt
alles wie es soll!

Woran kann das liegen? Müssten die Servos nicht trotz zittern in die entsprechende Position fahren?

Gruß Björn

SprinterSB
24.07.2006, 17:04
Keine Ahnung. Wenn du denkst daß dein Problem nicht mit der AVR-Programmierung zu tun hat, frag doch mal bei den Servos...

Funky
24.07.2006, 21:23
Bin mir ja nicht sicher! Vielleicht liegt es auch am Programm!

Hab leider noch nicht so viel Erfahrung mit Servos und wollt jetzt auch nicht direkt mit Doppelposts anfangen.....