Forum: Compiler & IDEs Tiny13 free running ADC will nicht wie ich will.


von Kopfkratzer (Gast)


Lesenswert?

Hallo,
stehe gerade voll auf dem Schlauch.
Das Programm soll einen Poti auslesen mit 8bit vertüten und dann je nach 
Wert in Sekunden eine PWM ausgeben.
Zwecks debugging ist die PWM nun erstmal draussen, statt dessen soll 
eine LED angehen was sie aber nicht will ...
Wo habe ich meinen Fehler (PB1 toggelt im Sekundentakt, Timer läuft 
also)?
Danke !
1
volatile uint8_t sekunden;
2
volatile uint8_t ADCWert;
3
//Timer-IRQ
4
ISR(TIM0_OVF_vect)
5
{
6
  static uint8_t tick;
7
  // 1,2 MHz / 256 = 4,687 => 5000 Durchgänge/s Prescaler 1024 => 5 Durchgänge/s
8
  // 1,2 MHz / 256 + Prescaler 256 => 20
9
  // 1,2 MHz / 256 + Prescaler 64 => 80
10
  // 1,2 MHz / 256 + Prescaler 8 => 640
11
  // 1,2 MHz / 256 + Prescaler 0 => 4700
12
  // 9,6 MHz => 36,6 ca. 37
13
  if(tick++ > 30)
14
  {
15
    sekunden++;
16
    tick=0;
17
    PORTB = PINB ^ ( 1 << PB1 );
18
  }
19
}
20
21
ISR(ADC_vect)
22
{
23
  ADCWert=ADCH;
24
}
25
26
void init(void)
27
{
28
  // Internal RC
29
  
30
  //PIN-Settings
31
  DDRB = 0; // Alles Eingänge
32
  //DDRB |= (1<<PB0); // PWm Ausgang
33
  DDRB |= (1<<PB1);
34
  DDRB |= (1<<PB3);//TESTAUSGÄNGE
35
  //PORTB|= (1<<PB3);//active low !
36
  
37
  //Timer0 Fast-PWM 50:50 Tast, Prescaler 1024
38
  TCCR0A = 0;
39
  TCCR0A = (1<<WGM00)|(1<<WGM01);//|(1<<COM0B1);//|(1<<COM0A0);
40
  TCCR0B = 0;
41
  TCCR0B = (1<<WGM02)|(1<<CS00)|(1<<CS02);
42
  OCR0A = 32;
43
  OCR0B = 16;
44
  TIMSK0 = 0;
45
  TIMSK0 = (1<<TOIE0);
46
  
47
  //ADC Free running, ADLAR=1 Mux=0 1,2MHz/8=150kHz
48
  ADCSRA = 0;
49
  ADCSRA = (1<<ADEN)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADATE)|(1<<ADSC);
50
  ADCSRB = 0;
51
  //ADCSRB =();
52
  ADMUX = 0;
53
  ADMUX = (1<<ADLAR);//|(1<<)|(1<<);
54
  DIDR0 = (1<<ADC0D)|(1<<ADC1D)|(1<<ADC2D); //PB5,PB2,PB4
55
  
56
  //IRQs
57
  sei();
58
}
59
60
int main(void)
61
{
62
  
63
  init();
64
  
65
  while(1)
66
  {
67
68
    
69
      if(sekunden < ADCWert)
70
      {
71
        DDRB &= ~(1<<PB3);//TESTAUSGÄNGE
72
      }
73
      else
74
      {
75
       DDRB |= (1<<PB3);//TESTAUSGÄNGE
76
       sekunden=0;
77
      }
78
    
79
  }
80
  
81
82
}

von Stefan E. (sternst)


Lesenswert?

Ich weiß ja nicht, welche Art von PWM du eigentlich erwartest, aber ich 
kann dir sagen, was du von dem Code zu erwarten hast, nämlich einen sehr 
kurzen (µs) High-Impuls gefolgt von einer langen ADC abhängigen 
Low-Periode.

von Karl H. (kbuchegg)


Lesenswert?

Kopfkratzer schrieb:
> Hallo,

>       if(sekunden < ADCWert)
>       {
>         DDRB &= ~(1<<PB3);//TESTAUSGÄNGE
>       }
>       else
>       {
>        DDRB |= (1<<PB3);//TESTAUSGÄNGE
>        sekunden=0;
>       }

Welchen Sinn erhoffst du dir davon, den Pin von Eingang auf Ausgang 
umzuschalten?

von Kopfkratzer (Gast)


Lesenswert?

Uups, typisches Copy&Paste der falschen Zeile rotwerd
Allerdings bleibt die LED dauerhaft an, egal ob der Poti nun 0 Volt oder 
5 Volt hat ...
Im ADCH sollte doch 0 stehen bei 0 Volt oder habe ich da das mit dem 
ADLAR falsch verstanden ?
Danke !
1
int main(void)
2
{
3
  
4
  init();
5
  
6
  while(1)
7
  {
8
9
    
10
      if((sekunden < ADCWert)&&(ADCWert > 1))
11
      {
12
        PORTB &= ~(1<<PB3);//TESTAUSGÄNGE
13
      }
14
      else
15
      {
16
       PORTB |= (1<<PB3);//TESTAUSGÄNGE
17
       sekunden=0;
18
      }
19
    
20
  }
21
  
22
23
}

von Karl H. (kbuchegg)


Lesenswert?

Was ich an deiner Stelle tun würde.

Ich würde mir hier
1
ISR(ADC_vect)

erst mal eine LED einschalten um zu sehen ob die ISR aufgerufen wird.

Als nächstes würde ich mir den Wert von ADCH ansehen. Notfalls direkt 
auf einen 8_Bit Port legen und mit dem Voltmeter die einzelnen Pins 
abklappern. Dann Poti verdrehen und nachsehen ob sich der Wert ändert.

Und erst dann, wenn ich sicher gehen kann, dass vom ADC auch tatsächlich 
Werte kommen, die irgendetwas mit der Potistellung zu tun haben, erst 
dann baue ich weiter und mache eine Auswertung mit diesem Wert.

Und meine erste Auswertung wäre
1
  ....
2
3
4
  while(1)
5
  {
6
    if( ADCWert < 127 )
7
      PORTB &= ~(1<<PB3);
8
    else
9
      PORTB |= (1<<PB3);
10
  }

und beim Drehen am Poti muss die LED irgendwo bei Potimittelstellung 
ein/aus gehen.

Zuviele Schritte auf einmal machen führt oft dazu, dass man über 
irgendeinen stolpert und nicht weiß, welcher es war.

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.