www.mikrocontroller.net

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


Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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



#include <avr/io.h>
#define F_CPU 8000000UL


int messwert;

ISR(ADC_vect)
{
  // Wert im ADCH in "messwert" ausgeben
  messwert = ADCH;


}


int main(void)
{
  // *** PWM-Ausgang festlegen ***
  // OCR1A-Ausgang (PD5)
  DDRD |= (1<<PD5);
  

  // *** PWM konfigurieren ***
  // -- Max-Wert festlegen
  TCCR1A |= (1<<WGM10);    // (OFF = 255)

  // -- Zählergeschwindigkeit festlegen
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz

  // -- Impulslage festlegen
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
  
  // *** Impuls einstellen ***
  OCR1A = 0;      


  

  //PA0-PA7 als ADC-Eingang
  DDRA = 0b00000000;  

  // ADC für ADC5-Eingang Konfiguration
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX0); //ADC5

  // ADC einschalten
  // Free-Running-Mode (d.h. kontinuierlich messen)
  // Verwendung von Interrupts
  // Prescaler = 64 (d.h. schnelle Messung)
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
  
  

  while(1)
  {
    OCR1A = messwert;
  }
}

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

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

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn ich "volatile" hinzufüge macht er nichts.

Autor: Edi R. (edi_r)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um welchen Controller geht es überhaupt?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einmal sei(); aufrufen?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: seier (Gast)
Datum:

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

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

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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")

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL


ISR(ADC_vect)
{
  // Wert im ADCH auf Port C ausgeben
  OCR1A = ADCH;
}


int main(void)
{
  // PORTD als Ausgang konfigurieren
  DDRD |= (1<<PD5);

  //PA0-PA7 als ADC-Eingang
  DDRA = 0b00000000;  

  // ADC für ADC7-Eingang Konfiguration
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0); //ADC7

  // ADC einschalten
  // Free-Running-Mode (d.h. kontinuierlich messen)
  // Verwendung von Interrupts
  // Prescaler = 64 (d.h. schnelle Messung)
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
  
  sei();



  // *** PWM-Ausgang festlegen ***
  // OCR1A-Ausgang (PD5)
  DDRD |= (1<<PD5);
  PORTD = 0b00001100;  // PULL-UPs für S1 & S2

  // *** PWM konfigurieren ***
  // -- Max-Wert festlegen
  TCCR1A |= (1<<WGM10);    // (OFF = 255)

  // -- Zählergeschwindigkeit festlegen
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz

  // -- Impulslage festlegen
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
  
  // *** Impuls einstellen ***
  OCR1A = 0; 


  while(1)
  {
    // mach was ...
  }
}


Autor: seier (Gast)
Datum:

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

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hier nochmal richtig überarbeitet:

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL


ISR(ADC_vect)
{
  // Wert im ADCH auf OCR1A ausgeben
  OCR1A = ADCH;
}


int main(void)
{
  // PORTD Bit 5 als Ausgang konfigurieren
  DDRD |= (1<<PD5);

  //PA0-PA7 als ADC-Eingang
  DDRA = 0b00000000;  

  // ADC für ADC7-Eingang Konfiguration
  ADMUX  = (1<<ADLAR) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0); //ADC7

  // ADC einschalten
  // Free-Running-Mode (d.h. kontinuierlich messen)
  // Verwendung von Interrupts
  // Prescaler = 64 (d.h. schnelle Messung)
  ADCSRA  = (1<<ADEN) | (1<<ADSC) | (1<<ADATE);
  ADCSRA |= (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1);
  
  sei();



  // *** PWM-Ausgang festlegen ***
  // OCR1A-Ausgang (PD5)
  DDRD |= (1<<PD5);
  

  // *** PWM konfigurieren ***
  // -- Max-Wert festlegen
  TCCR1A |= (1<<WGM10);    // (OFF = 255)

  // -- Zählergeschwindigkeit festlegen
  TCCR1B |= (1<<CS11);  // CK/8 = 1MHz

  // -- Impulslage festlegen
  TCCR1A |= (1<<COM1A1);   // Impuls am Anfang
  
  // *** Impuls einstellen ***
  OCR1A = 0; 


  while(1)
  {
    // mach was ...
  }
}



Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joe schrieb:
> ADC7 ist ein Potentiometer ich möchte eine Lampe dimmen

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

Autor: Edi R. (edi_r)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.