ATTINY13 - ADC im free running mode blockiert irgendwie den Hardware PWM

OP #3619989
Lesenswert?

Hallo,

für ein Exponat soll ich ein kleines ferngesteuertes langsamer fahren 
lassen. Das Auto selbst kann in 4 Stufen geradeaus fahren. Dafür wird in 
der Elektronik des Autos eine PWM erzeugt. Ich habe nun vor das 
PWM-Signal über den AD-Wandler des TINY13 aufzuzeichnen und das 
Tastverhältnis zu berechnen. So kann ich die 4 Stufen erkennen und kann 
entsprechend eine "langsamere" PWM ausgeben.
Die Berechnung des Tastverhältnisses funktioniert schon wunderbar, nur 
auf einmal will die von mir erzeugt PWM nicht mehr. Wenn ich den 
PWM-Teil in einem neuen Projekt kompiliere, funktioniert sie, also denke 
ich, ist der Code an sich nicht verkehrt. Kann es sein, dass sich die 
Interrupts gegenseitig beeinflussen ?
Nicht wundern, warum ich beide Hardware-PWM-Ausgänge konfiguriert habe. 
Rückwärtsfahren soll er schließlich auch noch.
1
/*
2
 * PWM_Mini_LNdW.c
3
 *
4
 * Created: 15.04.2014 15:40:50
5
 *  Author: schu_s2
6
 */ 
7

8
#define F_CPU 1200000UL
9
#include <avr/io.h>
10
#include <util/delay.h>
11
#include <avr/interrupt.h>
12
#define NUM_SAMPLES 16
13

14
volatile uint16_t x[NUM_SAMPLES];
15
uint8_t i = 0;
16

17
ISR(ADC_vect){
18
  x[i] = ADCW;
19
  i++;
20
  if (i == 16){
21
    i = 0;
22
  }
23
}
24

25
uint16_t average(uint16_t *Feld, unsigned char n_samples){
26
  uint16_t relation = 0;
27
  uint16_t sum = 0;
28
  for (int j = 0; j < n_samples; j++){
29
    sum = sum + Feld[j];
30
  }
31
  relation = sum / n_samples;
32
  return relation;
33
}
34

35
int main(void)
36
{
37
  DDRB = 0b00000111;
38
  TCCR0A |= (1<<WGM01) | (1<<WGM00);
39
  TIMSK0 |= (1<<OCIE0A)|(1<<OCIE0B);
40
  TCCR0B |= (1<<CS00);
41
  //OCR0A = 0x80;
42
  //OCR0B = 0x80;*/
43
  ADMUX |= (1<<MUX1);            //MUX1 für ADC2
44
  ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADATE) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);            
45
  //Teiler 128 //free running mode
46
  uint16_t Wert = 0;
47
  sei();
48
  
49
  for(int j=0;j<NUM_SAMPLES;j++){
50
    x[j]=0;
51
  }
52

53
  while(1){
54

55
    Wert = average(x, NUM_SAMPLES);
56
          
57
    if ( Wert <= 100 ){                //Wenn ADC-Mittelwert unter 100, schalte PWM aus
58
      TCCR0A &= ~((1<<COM0A1) | (1<<COM0A0));
59
      //PORTB |= (1<<PINB1);  
60
    }
61
    if ( Wert > 100 && Wert < 400){
62
      OCR0A = 0x19;                //10% Tastverhältnis
63
      TCCR0A |= (1<<COM0A1) | (1<<COM0A0);
64
      
65
    }
66
    if ( Wert >= 400 && Wert < 600){
67
      OCR0A = 0x33;                //20% Tastverhältnis
68
      TCCR0A |= (1<<COM0A1) | (1<<COM0A0);
69
      //PORTB ^= (1<<PINB2);
70
    }
71
    if ( Wert >= 600 && Wert < 750){
72
      OCR0A = 0x40;                //25% Tastverhältnis
73
      TCCR0A |= (1<<COM0A1) | (1<<COM0A0);
74
      //PORTB ^= (1<<PINB1);
75
    }
76
    if ( Wert >= 750){
77
      OCR0A = 0x4D;                //30% Tastverhältnis
78
      TCCR0A |= (1<<COM0A1) | (1<<COM0A0);
79
      //PORTB ^= (1<<PINB2);
80
    }  
81
    
82
    
83
  }
84
}
Gast #3620177
Lesenswert?

>Meinst du also, dass es durch den nun angewendeten sei()-Befehl und die
>jetzt fehlende Interrupt-Routine nicht funktioniert ?

Das meint nicht nur er. Wieso probierst du es nicht
ohne die Interruptfreigabe für die Timer aus?

Ist das denn so schwer?
Gast #3620208
Lesenswert?

Sebastian Schulz schrieb:
> Meinst du also, dass es durch den nun angewendeten sei()-Befehl und die
> jetzt fehlende Interrupt-Routine nicht funktioniert ?

Ja, das ist ganz sicher so. Ohne ISR zeigt der entsprechende 
Interruptvektor auf den Resetvektor und damit resettet der uC laufend.

Warum erlaubst Du überhaupt Interrupts, die offensichtlich nicht 
benötigt werden?
Gast #3620212
Lesenswert?

>Wenn ich die Interrupt-Freigabe weglasse, dann funktioniert ja der
>ADC-Interrupt nicht mehr. Oder ???

Wer hat denn gesagt das du sei() weglassen sollst?

Bist du irgendwie schwer von Begriff?
Und das war jetzt ein klein wenig unhöflich;)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren