Forum: Mikrocontroller und Digitale Elektronik Fast PWM Atmega8


von Heiner K. (Gast)


Lesenswert?

Hi,
ich habe ein Problem mit der Fast PWM einstellung beim Atmega8 am 
Timer1.

Haben die wie im folgenden Quellecode eingestellt. Der Prozessor läuft 
bei einem Takt von 3,6864MHz.

#include <mega8.h>

int tmp=0;
int tmp1=0;

interrupt [EXT_INT0] void ext_int0_isr(void)
{

}

interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
  if(tmp1==0)
  {
    PORTB |=(1<<1) ;
    tmp1=1;
  }
  else
  {
    PORTB &=~ (1<<1);
    tmp1=0;
  }
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
  if(tmp==0)
  {
    PORTB |=(1<<0) ;
    tmp=1;
  }
  else
  {
    PORTB &=~ (1<<0);
    tmp=0;
  }
}

void main(void)
{
  PORTB=0x00;
  DDRB=0xFF;

  PORTC=0x00;
  DDRC=0x00;

  PORTD=0x00;
  DDRD=0x00;

  TCCR1A=((0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | 
(0<<FOC1A) | (0<<FOC1B) | (1<<WGM11) | (0<<WGM10));
  TCCR1B=((0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (1<<CS12) 
| (0<<CS11) | (0<<CS10));

  ICR1H=((0<<7) | (0<<6) | (1<<5) | (1<<4) | (1<<3) | (0<<2) | (0<<1) | 
(0<<0));
  ICR1L=((0<<7) | (4<<6) | (1<<5) | (0<<4) | (1<<3) | (1<<2) | (1<<1) | 
(1<<0));

  OCR1AH=((0<<7) | (0<<6) | (0<<5) | (1<<4) | (1<<3) | (1<<2) | (0<<1) | 
(0<<0));
  OCR1AL=((0<<7) | (0<<6) | (1<<5) | (0<<4) | (1<<3) | (0<<2) | (0<<1) | 
(0<<0));

  GICR|=0x40;
  MCUCR=0x03;
  GIFR=0x40;

  TIMSK=((0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (1<<OCIE1A) | 
(0<<OCIE1B) | (1<<TOIE1) | (0<<TOIE0));

  ACSR=0x80;
  SFIOR=0x00;

#asm("sei")
  while (1)
  {

  };
}


Ich habe an die Ausgänge PB0 und PB1 LED's angeschlossen. Eigentlich 
sollte doch die LED an PB0 eher ansein als die an PB1 oder verstehe ich 
das grundsätzlich was falsch ?

von Vlad T. (vlad_tepesch)


Lesenswert?

wo ist dein eigendliches Problem?
gehts nicht, gehts anders als erwartet?

ich tippe mal:
die temp variablen sollten eventuell als volatile declariert werden, 
wobei ich die ganz wegschmeißen würde und direkt im Port-register 
nachschuen würde obs an ist, oder nicht.

#asm ist doof.
benutze sei()


#include <mega8.h> ist doof
es gibt einen header für alle, der die unterscheidung intern macht.
benutz den ich glaib avrio.h oder so, bin mir abernicht sicher

bei 16bit (2x8bit) registern muss man meist das unterste zuerst 
beschreiben und dann das höhere WICHTIG!!!.
in C gibt es meist ein define, das man als 16bit register anspricht:
ICR1  statt ICR1H  und ICR1L

denk auch an die (in den Compiler-settings) vordefinierte F_CPU 
constante

wenn das alles nichts hilf überprüfe noch mal bit für bit die Timer 
initialsierungen.

von Heiner K. (Gast)


Lesenswert?

Die PWM funktioniert an sich schon. Das Problem ist nur, sobald die PWM 
gestartet wird, wird erst ein Overflow Interrupt ausgelöst und dann im 
wechsel erst der Compare und dann der Overflow. Zweites sollte doch auch 
schon beime ersten durchlaufen passieren oder? Oder ist diese Abfolge 
beim starten doch richtig?
Kann man hieran was ändern ?

von Vlad T. (vlad_tepesch)


Lesenswert?

ich bild mir ein gesehen zu haben, dass im Datenblatt etwas stand, wann 
neue werte des compareregisters übernommen werden.
schau da mal rein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.