PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Hilfe bei Atmega8 Timer/Counter1 für CTC Modus



robotka
22.03.2013, 13:05
Hallo liebe Experten und Kenner,

Ich bin schon etwas länger mit der C++ Programmierung dabei und habe erste Erfahrung bei Mikrocontrollern.
Nun möchte ich mein Wissen etwas vertiefen und beschäftige mich etwas mehr um die Controller besser kennenzulernen um später mal meinen eigenen Roboter zu bauen. Momentan beschäftige ich mich mit den Atmega8.

Mit den 8bit Timer/Counter0 und 2 bin ich schon zurecht gekommen nun wollte ich mich mit den 16-Bit Timmer/Counter1 beschäftigen.
Ich möchte, damit man es auch sieht, eine LED mit 4 Hz blinken lassen. später soll es als Signalgabe benutzt werden.

Ich stelle euch mal mein Code zur Verfügung und ich hoffe ihr findet meinen Fehler bezw. falschen Ansatz.




#define F_CPU 8000000 // CPU Taktfrequenz intern 8 MHz

// Einbindung der Includedateien
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

// Ein-und Ausgangsbestimmung
#define _zu_Eingang(Register,Pin) Register&=~(1<<Pin) // Beispiel:
// setze PB1 als Eingang
// _zu_Eingang(DDRB,PB1);

#define _zu_Ausgang(Register,Pin) Register|=(1<<Pin) // Beispiel:
// setze PB1 als Ausgang
// _zu_Eingang(DDRB,PB1);
// Funktion Warte
void warte (int ms){
for (int i=1;i<ms;i++)
{
_delay_ms(1);
}
}

// Funktionen Schalte Ausgänge
void set_PortB_Pin(int Pin){
DDRB |= (1<<Pin);
}

void clear_PortB_Pin(int Pin){
PORTB &= ~(1<<Pin);
}

void toggle_PortB_Pin(int Pin){
PORTB ^= (1<<Pin);
}

void ini_PWM(void){
cli(); //sperre interrupte
//1. Prescaler
TCCR1B |= (1<<CS10) | (1<<CS11); // Prescaler = 64

//2. Modus
TCCR1B |= (1<<WGM12); // CTC Modus

TIMSK |= (1<<TOIE1); // setze interrupt beim Überlauf

//3. Frequenz
OCR1A = 0xF424; // 8MHz /
OCR1B = 0xF424; // 2Hz * 64(Prescaler)
// = 62500 =0xF424 in HEX
sei(); //erlaube interrupte
}

void stoppe_PWM(void){
TCCR1B &= ~(1<<WGM12);
}

void starte_PWM(void){
TCCR1B |= (1<<WGM12);
}

ISR(TIMER1_COMPB_vect){
toggle_PortB_Pin(PB1);

}

int main(void)
{
DDRB=0xFF;
set_PortB_Pin(PB1);
clear_PortB_Pin(PB2);
starte_PWM();
while(1)
{
toggle_PortB_Pin(PB2);
warte(500);
}
}




Das ist der Code, wie man vll sieht sollte Die LED an PB1 per CTC ISR alle 2 Sek getogglet werden, jedoch bleibt sie aus wieso kann mir da wer helfen wo der falsche Ansatz ist?

Ich hoffe an viele Antworten und Kritik

Grüße aus Hamburg

markusj
22.03.2013, 13:29
Du rufst die Initialisierungsfunktion nie auf.

Davon abgesehen finde ich die komischen Hilfsfunktionen zum setzen und löschen von Bits reichlich unnötig ...

mfG
Markus

Liquidator
22.03.2013, 13:35
Guten Tag,

auf Anhieb hätte ich die Frage, warum du die wait() einsetzt, wenn du die LED per Timer+Interrupt toggelst?
Auch fällt ein, dass du mit


TIMSK |= (1<<TOIE1);


einen Interrupt beim Überlauf setzt, nicht beim Erreichen des Vergleichswertes.

MfG Nik

robotka
22.03.2013, 19:51
Hey vielen Dank euch beiden! das ich die init nicht eingebunten habe war natürlich ganz schön doof :D und peinlich :D und das mit der falschen ISR vielen dank das habe ich auch übersehen! danke ihr habt mir weitergeholfen und ich kann nun weiter daran basteln!