PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fast PWM mit Timer1



tschensen
27.04.2006, 21:55
Hoi,
bei mir funktioniert die Fast PWM mit Timer 1 (16BIT) nicht.

Der Timer sollte eigentlich bis zum Wert des Registers OCR1A (Top value) zählen (funktioniert meiner Meinung nach auch) und bei Erreichen des Wertes im Register OCR1B den Ausgang OC1B setzen.


Ich bin mir sicher, daß der Timer wie vorgesehen läuft bzw zählt. Die Interrupts Overflow, Capture und Compare Match OCR1B funktionieren wie gewollt.

Wenn ich die Pins D4,5 als Ausgänge setze, sind beide die ganze Zeit auf 1 gesetzt. Wobei ich OC1A ja garnicht verwende und sogar Port D5 auf 0 setze. Jemand ne Idee woran das liegen könnte?
Keine Ahnung warum OC1B nicht reagiert....

Hier der Code:




#include <avr/io.h>
#include <avr/interrupt.h>
#include "delay_ms.h"


volatile unsigned int zvz;


int main(void)
{
//**********IO-Init******************************

PORTB|=0xFF;
DDRB|=0xFF;

PORTD|=(1<<4);//PWM Ausgang Timer OC1B
DDRD&=~(1<<5);
PORTD|=(1<<5);
SREG|=(1<<7); //Global Interrupt enable


//***********16Bit Timer Init *************************

TCCR1A&=~((1<<COM1A1)|(1<<COM1A0)); //normale Port Funktion an PINB5
TCCR1A|= (1<<COM1B1)|(1<<COM1B0);// Set ORC1B On Compare Match, löschen bei Top-value
TCCR1A&=~((1<<3)|(1<<2)); // keine Funktion
TCCR1A|= (1<<WGM11); //FAST PWM , TOP=OCR1A
TCCR1A|= (1<<WGM10); //FAST PWM , TOP=OCR1A

TCCR1B&=~(1<<ICNC1); //Input Noise Canceler aus
TCCR1B|= (1<<WGM13); //FAST PWM , TOP=OCR1A
TCCR1B|= (1<<WGM12); //FAST PWM , TOP=OCR1A
TCCR1B&=~((1<<CS12)|(1<<CS11)); //Prescaler =1
TCCR1B|= (1<<CS10); //Prescaler =1

TIMSK|= (1<<TICIE1); //Interrupt Capture enable
TIMSK|=~(1<<OCIE1A); //Interrupt Output Compare Match A disable
TIMSK|= (1<<OCIE1B); //Interrupt Output Compare Match B enable
TIMSK|= (1<<TOIE0); //Interrupt Overflow enable
//************************************************** ********************************
unsigned char sreg;
sreg=SREG;
cli();
OCR1A=4000; //einstellen des Top Value des Counters
OCR1B=2000; //setzen des Compare matches
SREG=sreg;

//TCNT1=0;

while (1)
{

}





}

//***********Interrupt Routinen Timer1 interrupts****************

//***Interrupt Compare Match B
ISR(TIMER1_COMPB_vect)
{
PORTB&=~(1<<1);
PORTB|=(1<<0);

// delay_ms(500);
}
//***Interrupt Overflow

ISR(TIMER1_OVF_vect)
{
PORTB&=~(1<<0);
PORTB|=(1<<1);
// delay_ms(500);
}

//*****Interrupt Capture Event
ISR(TIMER1_CAPT_vect) // Tritt ein bei Positive Flanke an ICP1
{
zvz=TCNT1;
if (TCNT1<2000)
{
PORTB&=~(1<<5);
PORTB|=(1<<4);
}
if (TCNT1>2000)
{
PORTB&=~(1<<4);
PORTB|=(1<<5);
}
PORTB&=~(1<<7);
delay_ms(500);



}

SprinterSB
01.05.2006, 20:22
500ms in einer ISR waren ist nicht dein Ernst, oder? ;-)

Ausserdem wird nirgends Overflow-ISR für Timer0 implementiert.