Forum: Mikrocontroller und Digitale Elektronik Fast PWM - ATtiny13A


von mk (Gast)


Lesenswert?

Hallo zusammen,

ich habe leider ein Problem mit dem fast PWM mode des ATtiny13A. Hier 
mein Programm:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
void pwm_write (int val)
5
{
6
  OCR0A = val;
7
}
8
9
int main(void)
10
{
11
  DDRB |= (1<<DDB0);      // PB0 (OC0A) as output-Pin
12
  DDRB &= ~(1<<DDB3);      // PB3 as input-Pin
13
  PORTB |= (1<<PORTB3);    // activate pull-up transistor for PB3
14
  
15
  sei();            // enable global interrupts
16
  TIMSK0 |= (1<<OCIE0A);    // enable output compare match A interrupt
17
    
18
  // choose wave form generation mode
19
  TCCR0A |= (1<<WGM00);
20
  TCCR0A |= (1<<WGM01);
21
  TCCR0B &= ~(1<<WGM02);  
22
23
  // choose non inverted PWM
24
  TCCR0A |= (1<<COM0A1);
25
  TCCR0A |= ~(1<<COM0A0);
26
    
27
  // clock select/prescaler
28
  TCCR0B |= (1<<CS00);
29
  TCCR0B &= ~(1<<CS01);
30
  TCCR0B &= ~(1<<CS02);
31
  
32
  volatile int v=0;
33
  
34
  while(1)
35
  {  
36
    if ( (PINB & (1<<PINB3)) == 0 )
37
    {
38
      v = 200;  
39
    }
40
  pwm_write(v);
41
  }
42
}

Was ich erwartet habe ist folgendes:

Ausgabe am PWM-Pin: 0V, weil OCR0A = v und v = 0.
Wenn ich PB3 drücke (gegen GND), dann ändert sich v zu 200 und die PWM 
ändert sich dementsprechend.
FERTIG

So weit entspricht das Verhalten auch meinen Erwartungen - mit dem 
Unterschied, dass der PWM-Pin wieder permanent 0V ausgibt, wenn ich PB3 
loslasse - d.h., dass OCR0A wieder zu 0 wird - also v wieder irgendwie 0 
wird, obwohl das in der while-Schleife doch eigentlich nirgendwo 
geschehen kann... !?

... wo ist mein (Denk-)Fehler?

Schonmal danke für die Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

mk schrieb:

> Unterschied, dass der PWM-Pin wieder permanent 0V ausgibt, wenn ich PB3
> loslasse - d.h., dass OCR0A wieder zu 0 wird - also v wieder irgendwie 0
> wird, obwohl das in der while-Schleife doch eigentlich nirgendwo
> geschehen kann... !?

oder dein µC resetted, weil du einen Interrupt freigegeben hast
1
  TIMSK0 |= (1<<OCIE0A);    // enable output compare match A interrupt
für den du keine ISR hast.

Man gibt keine Interrupts frei ohne ISR. Und wenn man Code von woanders 
übernimmt, dann sucht man ihn ab, ob irgendwo ein Interrupt Enable Bit 
gesetzt wird. Wenn ja, und wenn man die ISR nicht braucht, dann wird das 
rausgeschmissen.

von mk (Gast)


Lesenswert?

... so einfach kann die Lösung sein - dankeschön !!

Ich dachte, dieser IR müsste aktiviert werden, weil sonst der PWM-IR 
nicht funktionieren würden - also das An-/Ausschalten vom OC0A-Pin, aber 
offenbar habe ich da falsch gedacht.

Ist es bei allen Interrupts so, dass der Mikrocontroller resettet, wenn 
der Interrupt freigegeben ist, aber keine passende Service Routine 
existiert?

von Carl D. (jcw2)


Lesenswert?

> Ist es bei allen Interrupts so, dass der Mikrocontroller resettet, wenn der 
Interrupt freigegeben ist, aber keine passende Service Routine
existiert?

Solange man die Deault-Imlementierung von ISR(BADINT_vector) nicht 
selber anders implementiert, wird die Default-Implementierung benutz, 
die nach 0x0000 springt, was für die Software ein Reset ist. Die HW 
beeindruckt das natürlich nicht. Die springt nicht automatisch auf 
ihre Reset-Werte
Randnotiz: das gehört zu C auf AVR!

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.