Forum: Compiler & IDEs Atmega32 und ADC Interruptfunktion klappt nicht


von Atmega32 (Gast)


Lesenswert?

Hallo Mikrocontroller.net
ich bin gerade dabei den Atmega32 zu programmieren.
Ich habe auch schon den ADC zum laufengebracht allerdings nur mit dem 
"Pollingverfahren". Nun wolte ich mal die Interrupts benutzen, aber dies 
will nicht ganz funktionieren.

Ich habe keine keine Ahnung wo der Fehler liegt.
Hier mal mein Quelltext:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
5
unsigned int adwert = 100;
6
7
//--------------------------
8
#ifndef F_CPU
9
#warning "F_CPU war noch nicht definiert, wird nun mit 1600000 definiert"
10
#define F_CPU 16000000UL 
11
#endif
12
#include <util/delay.h> 
13
//--------------------------
14
void waitms(unsigned int ms)
15
{
16
    for(; ms>0; ms--) _delay_ms(1);
17
}
18
//--------------------------
19
20
int main (void)
21
{
22
  DDRA = 0xc0;
23
  ADMUX = 0x24;
24
  SFIOR = 0x00;
25
  sei();
26
  ADCSRA = 0xC4;
27
28
  while(1)
29
  {  
30
   PORTA = 0x80;  
31
   waitms(adwert);
32
   PORTA = 0x40;
33
   waitms(adwert);
34
   }
35
  return(0);    
36
}
37
38
ISR(ADC_vect)
39
{
40
  adwert = ADCH;
41
  ADCSRA = 0xC4;
42
}

Vielen dank schonmal.
MfG Atmega32

von Edi R. (edi_r)


Lesenswert?

Was mir auf Anhieb auffällt:

- "adwert" ist nicht volatile deklariert
- "adwert" ist ein int, aber es reicht ein char, weil ADCH auch nur 8 
bit breit ist.

Mehr fällt mir auf Anhieb nicht auf, weil die Initialisierungen recht 
nichtssagen sind (ADCSRA = 0xC4 ???) und ich keine Lust habe, die 
Hexwerte manuell zu zerpflücken.

von Hc Z. (mizch)


Lesenswert?

Edi R. schrieb:
> (ADCSRA = 0xC4 ???) und ich keine Lust habe, die
> Hexwerte manuell zu zerpflücken.

Zustimmung.  Wäre die 0xc4 in Einzelwerten (Bits mit Benennung) 
ausgeschrieben, wäre dem TE wahrscheinlich vor dem Absenden schon klar 
gewesen, dass dort (1<<ADIE) fehlt und dieser Fehler hätte vermieden 
werden können.

von Atmega32 (Gast)


Lesenswert?

Hallo,
habe den fehler auch gerade gefunden.
Hier der funktionierende Quelltext:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
5
volatile unsigned int adwert = 100;
6
7
//--------------------------
8
#ifndef F_CPU
9
#warning "F_CPU war noch nicht definiert, wird nun mit 1600000 definiert"
10
#define F_CPU 16000000UL  
11
#endif
12
#include <util/delay.h>    
13
//--------------------------
14
void waitms(unsigned int ms)
15
{
16
    for(; ms>0; ms--) _delay_ms(1);
17
}
18
//--------------------------
19
20
int main (void)
21
{
22
  DDRA = 0xc0;
23
  ADMUX = 0x24;
24
  SFIOR = 0x00;
25
  sei();
26
  ADCSRA = 0xC8;
27
28
  while(1)
29
  {  
30
     PORTA = 0x80;  
31
     waitms(adwert);
32
     PORTA = 0x40;
33
     waitms(adwert);
34
   }
35
  return(0);    
36
}
37
38
ISR(ADC_vect)
39
{
40
  adwert = ADCH;
41
  ADCSRA = 0xC8;
42
}

@ Hc Zimmerer
--------------
Ich weis den Fehler hätte man vermeiden können, jedoch muss man beachten 
das ich erst seit heute den Atmega32 programmiere und dadurch noch nicht 
viel Ahnung habe.

MfG Atmega32

von Hc Z. (mizch)


Lesenswert?

Es ging mir darum, dass Code selbsdokumentierend gestaltet wird, wenn es 
möglich ist, statt dem Leser die Bitklamüserei zu überlassen.  Dass also
statt
1
ADCSRA = 0xC8;  //SO NICHT
besser
1
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE);
geschrieben wird.  Dann wäre Dir auch sofort aufgefallten, dass Du 
soeben nicht nur den Interrupt Enable dazugemacht, sondern auch den 
Taktvorteiler gegenüber der ersten Version geändert hast.

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.