Forum: Mikrocontroller und Digitale Elektronik Wo ist der Denkfehler? ADC -> PWM


von Joe (Gast)


Lesenswert?

Hallo!

Ich möchte gerne den Wert den ich per ADC Eingang einlese an den PWM 
Ausgang
(PD5) ausgeben, doch es klappt nicht. Hab ich irgendwo einen denkfehler? 
Oder kann ich den "int messwert;" in der (while) nicht einfach so auf 
den OCR1 übergeben?

Hier der Code



1
#include <avr/io.h>
2
#define F_CPU 8000000UL
3
4
5
int messwert;
6
7
ISR(ADC_vect)
8
{
9
  // Wert im ADCH in "messwert" ausgeben
10
  messwert = ADCH;
11
12
13
}
14
15
16
int main(void)
17
{
18
  // *** PWM-Ausgang festlegen ***
19
  // OCR1A-Ausgang (PD5)
20
  DDRD |= (1<<PD5);
21
  
22
23
  // *** PWM konfigurieren ***
24
  // -- Max-Wert festlegen
25
  TCCR1A |= (1<<WGM10);    // (OFF = 255)
26
27
  // -- Zählergeschwindigkeit festlegen
28
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz
29
30
  // -- Impulslage festlegen
31
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
32
  
33
  // *** Impuls einstellen ***
34
  OCR1A = 0;      
35
36
37
  
38
39
  //PA0-PA7 als ADC-Eingang
40
  DDRA = 0b00000000;  
41
42
  // ADC für ADC5-Eingang Konfiguration
43
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX0); //ADC5
44
45
  // ADC einschalten
46
  // Free-Running-Mode (d.h. kontinuierlich messen)
47
  // Verwendung von Interrupts
48
  // Prescaler = 64 (d.h. schnelle Messung)
49
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
50
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
51
  
52
  
53
54
  while(1)
55
  {
56
    OCR1A = messwert;
57
  }
58
}

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Zunächst einmal "volatile int messwert".
Den Rest habe ich mir noch nicht genauer angesehen.

von Anja (Gast)


Lesenswert?

messwert sollte als "volatile" deklariert werden ansonsten optimiert der 
Compiler den Zugriff in der Schleife weg.

Beim ADC: ist er "links" oder "rechtsbündig" konfiguriert?

Gruß Anja

von Joe (Gast)


Lesenswert?

Auch wenn ich "volatile" hinzufüge macht er nichts.

von Edi R. (edi_r)


Lesenswert?

Um welchen Controller geht es überhaupt?

von Joe (Gast)


Lesenswert?


von Flo (Gast)


Lesenswert?

Einmal sei(); aufrufen?

von spess53 (Gast)


Lesenswert?

Hi

Fehlt da nicht ein 'sei' (natürlich in C-Schreibweise)?

MfG Spess

von seier (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
> Fehlt da nicht ein 'sei' (natürlich in C-Schreibweise)?
>
> MfG Spess

Jap, das fehlt.
Füge ein:
1
sei();   // setzt globale Interrupts enable

von Joe (Gast)


Lesenswert?

So bin dahinter gekommen. Falls jemand den funktionierenden Code haben 
will:

(ADC7 ist ein Potentiometer ich möchte eine Lampe dimmen) und (OCR1 der 
Ausgang PD7 die "Lampe")
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 8000000UL
4
5
6
ISR(ADC_vect)
7
{
8
  // Wert im ADCH auf Port C ausgeben
9
  OCR1A = ADCH;
10
}
11
12
13
int main(void)
14
{
15
  // PORTD als Ausgang konfigurieren
16
  DDRD |= (1<<PD5);
17
18
  //PA0-PA7 als ADC-Eingang
19
  DDRA = 0b00000000;  
20
21
  // ADC für ADC7-Eingang Konfiguration
22
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0); //ADC7
23
24
  // ADC einschalten
25
  // Free-Running-Mode (d.h. kontinuierlich messen)
26
  // Verwendung von Interrupts
27
  // Prescaler = 64 (d.h. schnelle Messung)
28
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
29
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
30
  
31
  sei();
32
33
34
35
  // *** PWM-Ausgang festlegen ***
36
  // OCR1A-Ausgang (PD5)
37
  DDRD |= (1<<PD5);
38
  PORTD = 0b00001100;  // PULL-UPs für S1 & S2
39
40
  // *** PWM konfigurieren ***
41
  // -- Max-Wert festlegen
42
  TCCR1A |= (1<<WGM10);    // (OFF = 255)
43
44
  // -- Zählergeschwindigkeit festlegen
45
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz
46
47
  // -- Impulslage festlegen
48
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
49
  
50
  // *** Impuls einstellen ***
51
  OCR1A = 0; 
52
53
54
  while(1)
55
  {
56
    // mach was ...
57
  }
58
}

von seier (Gast)


Lesenswert?

Im übrigen sollte vermutlich auch noch die include <avr/interrupt.h> 
inkludiert werden

von Joe (Gast)


Lesenswert?

Ich hab direkt gesagt: OCR1A = ADCH;
Ohne "int messwert"

manche Kommentare haben auch kleine fehler da ich die nicht mehr 
geändert hab weil ich ein funktionierendes "ADC-Programm" hatte und ein 
"PWM-Programm" hab die beide nur zusammengefügt.
Wollte es nur auf die schnelle zum funktionieren bringen.


Grüße Joe

von Joe (Gast)


Lesenswert?

So hier nochmal richtig überarbeitet:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 8000000UL
4
5
6
ISR(ADC_vect)
7
{
8
  // Wert im ADCH auf OCR1A ausgeben
9
  OCR1A = ADCH;
10
}
11
12
13
int main(void)
14
{
15
  // PORTD Bit 5 als Ausgang konfigurieren
16
  DDRD |= (1<<PD5);
17
18
  //PA0-PA7 als ADC-Eingang
19
  DDRA = 0b00000000;  
20
21
  // ADC für ADC7-Eingang Konfiguration
22
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0); //ADC7
23
24
  // ADC einschalten
25
  // Free-Running-Mode (d.h. kontinuierlich messen)
26
  // Verwendung von Interrupts
27
  // Prescaler = 64 (d.h. schnelle Messung)
28
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
29
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
30
  
31
  sei();
32
33
34
35
  // *** PWM-Ausgang festlegen ***
36
  // OCR1A-Ausgang (PD5)
37
  DDRD |= (1<<PD5);
38
  
39
40
  // *** PWM konfigurieren ***
41
  // -- Max-Wert festlegen
42
  TCCR1A |= (1<<WGM10);    // (OFF = 255)
43
44
  // -- Zählergeschwindigkeit festlegen
45
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz
46
47
  // -- Impulslage festlegen
48
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
49
  
50
  // *** Impuls einstellen ***
51
  OCR1A = 0; 
52
53
54
  while(1)
55
  {
56
    // mach was ...
57
  }
58
}

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Joe schrieb:
> ADC7 ist ein Potentiometer ich möchte eine Lampe dimmen

Wofür man heutzutage nicht überall einen Prozessor benötigt.

von Edi R. (edi_r)


Lesenswert?

Christian H. schrieb:
> Wofür man heutzutage nicht überall einen Prozessor benötigt.

Und? Früher war so eine Lösung entweder nicht möglich oder nicht 
wirtschaftlich, sonst hätte man das damals auch schon mit Prozessoren 
gemacht.

von Joe (Gast)


Lesenswert?

Der µC wird auch noch andere Dinge erledigen. Ich schreibe nur erstmal 
diverse Funktionen die ich nacher in mein Projekt "Haussteuerung" 
einfügen kann. Hat auch einen guten Lerneffekt... Man kann nunmal als 
einsteiger in der Controllertechnik nicht direkt einen Webserver 
programmieren.
Methoden mit Diacs, Triacs und Thyristoren sind jetzt auch nix neues für 
mich. Wenns um Phansenanschnitt geht... PWM könnte man auch mit einem 
NE555 bauen ;)

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.