Forum: Compiler & IDEs Spannungskomperator über ATMEGA8


von Kevin H. (raeak)


Lesenswert?

Hallo,

ich bin gerade mitten in einem kleinen Projekt.

Es geht um ein simples Programm was eine Spannungsdiverenz anzeigen soll 
und mir Visuell dann anzeigt.

Hierzu habe ich auf der nicht invetierenden Seite eine variable Spannung 
von 10 - 3.3 Volt und auf der invertierenden Seite eine konstante 
Spannung von ca. 3.3V. Wenn die Spannung von dem invertierenden Eingang 
unterschritten wird (also unter 3.3V) soll eine rote LED mit einem Herz 
blinken. (soweit die Theorie).

Ich habe auch schon ein Programm geschrieben, dass hoffentlich ein 
bissche aufschlussreicher für euch sein wird. Aaaabbber jetzt kommt das 
große Problem... es geht irgendwie nichts, ich habe das Programm schon 
auf mein uC (ATMEGA 8) geladen, aber es fäng nicht an zu blinken, wenn 
ich den nicht invertierenden Eingang auf high lege und den 
invertierenden auf low. Ich bin im Programmieren noch nicht so der 
übersteiger, ich eigne es mir momentan selber an, also habt Rücksicht 
mit mir ;)

Mit freundlichen Grüßen

Kevin


Programm ist durch die Kommentare ein wenig durcheinander...
1
#define FCPU 3860000UL
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
#define LED PB0                    // Definition, dass PB0 = LED zur besseren Übersicht
7
8
int init();                      // Unterprogramm Pfad für Konfiguration (Line 27)
9
int LEDblinken();                  // Unterprogramm Pfad für LED Blinken (Line 36)
10
ISR (ANA_COMP_vect);                // Unterprogramm Pfad für Interruptserviceroutine
11
12
13
int main(void)                    // Hauptprogramm
14
{
15
  init();                      // Aufruf des Unterprogrammes Konfiguration
16
 
17
    while(1)                    
18
    { 
19
    //PORTB |= (1>>LED);
20
    PORTC |= (1<<PC3);              // Wenn kein Interrupt ausgelöst, LED aus        
21
    }
22
}
23
24
int init()                      // Konfiguration der Register
25
{
26
  DDRB = 0xFF;                  // Datenrichtungsregister - PortB als Ausgang definiert
27
  PORTB = 0x00;                  // Definition des Grundzustand Logisch 0
28
  DDRC = 0xFF;
29
  
30
  ACSR = 0x0B;                  // Analog Comparator Control And Status Register configuration (0b00001011)
31
  SFIOR = 0X08;                  // Special Funkction IO Register
32
  
33
  sei();                      // Befehl um das I-Bit zu setzen (Schalter um Interrups zu aktivieren)
34
}
35
36
int LEDblinken()                  // Unterprogramm LEDblinken für visuellen Ausgabewert mit einer Frequenz von 1Hz
37
{
38
  PORTB |= (1<<LED);                // PB0 auf Logisch 1 shiften
39
  _delay_ms(0.5);                  // Delay 0.5ms nach einstalten
40
  PORTB &=~ (1>>LED);                // PB0 auf Logisch 0 shiften
41
  _delay_ms(0.5);                  // Delay 0.5ms nach Ausschalten
42
}
43
44
ISR (ANA_COMP_vect)                  // Interruptserviceroutine (ISR) des Analogkomperators
45
{
46
  LEDblinken();                  // Aufruf des Unterprogrammes LEDblinken
47
}

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Kevin Honey schrieb:
> Hierzu habe ich auf der nicht invetierenden Seite eine variable Spannung
> von 10 - 3.3 Volt und auf der invertierenden Seite eine konstante
> Spannung von ca. 3.3V.

Du gibst die 10V aber nicht ernsthaft direkt an den µC weiter, oder 
doch?

von 4toTakoe (Gast)


Lesenswert?

Kevin Honey schrieb:

> soll eine rote LED mit einem Herz blinken.


> int LEDblinken()                  // Unterprogramm LEDblinken für visuellen 
Ausgabewert mit einer Frequenz von 1Hz
> {
>   PORTB |= (1<<LED);                // PB0 auf Logisch 1 shiften
>   _delay_ms(0.5);                  // Delay 0.5ms nach einstalten
>   PORTB &=~ (1>>LED);                // PB0 auf Logisch 0 shiften
>   _delay_ms(0.5);                  // Delay 0.5ms nach Ausschalten
> }


Also entweder du meinst wirklich ein Herz, aber dann sieht man nichts 
blinken, oder du solltest dir die Werte nochmal genau anschauen.

Und zur eigentlichen frage: Da gehört ein Spannungsteiler hin, oder 
wenigstens eine Diode die die Überspannung ableitet.

von Peter D. (peda)


Lesenswert?

Es ist natürlich herrlich bequem, im Forum andere die Fehler suchen zu 
lassen.

Aber man darf auch selber suchen.
Unterteile einfach die Aufgaben.
Gib erstmal den ACO auf eine LED aus, ganz ohne Interrupts.

Es reicht nicht, Programmieren zu lernen, man muß auch Fehlersuche 
lernen. Und da ist die einfachste Methode, in Teilschritte zerlegen und 
diese zu prüfen.


Peter

von xfr (Gast)


Lesenswert?

Kevin Honey schrieb:
> PORTB &=~ (1>>LED);

Das ist mal eine neue Variante. :-D Funktioniert aber nur zufällig, weil 
LED 0 ist.

von Karl H. (kbuchegg)


Lesenswert?

Ich werde auch aus der Hardwarebeschreibung, jetzt mal vom 
Spannungsteiler abgesehen, nicht wirklich schlau.

Auf der einen Seite klingt das

> Hierzu habe ich auf der nicht invetierenden Seite eine variable
> Spannung von 10 - 3.3 Volt und auf der invertierenden Seite eine
> konstante Spannung von ca. 3.3V. Wenn die Spannung von dem
> invertierenden Eingang unterschritten wird

nach
* die eine Spannung ist an AIN0 angeschlossen
* die andere Spannung ist an AIN1 angeschlossen


Auf der anderen Seite lese ich im Code
1
  SFIOR = 0X08;                  // Special Funkction IO Register

und die Doku sagt zum Bit ACME
1
• Bit 3 – ACME: Analog Comparator Multiplexer Enable
2
When this bit is written logic one and the ADC is switched off
3
(ADEN in ADCSRA is zero), the ADC multiplexer selects the negative
4
input to the Analog Comparator. When this bit is written logic zero,
5
AIN1 is applied to the negative input of the Analog Comparator.

d.h. das Bit sollte überhaupt nicht gesetzt sein, damit AIN1 auf den 
Comperator geschaltet wird.


Daher wieder mal:
Beschreibe nicht deine Schaltung sondern zeige den Schaltplan! Dann muss 
man nicht aus vagen Beschreibungen irgendwelche Details rauslesen, von 
denen nicht klar ist, wie sie zu interpretieren sind. Ein Schaltplan ist 
eindeutig: so und nicht anderes ist die Hardware aufgebaut.



Und PS:
Mit deinen Kommentaren kann man eigentlich nur eines tun: ignorieren.
Denn die Kommentare erzählen nichts. Da steht einfach immer nur in einem 
deutschen Satz(-fragment) genau dasselbe, was auch im Code steht. Aber 
warum und wieso du etwas machst, das steht nicht dort.

Ich greif einfach mal irgendeinen raus
1
  ACSR = 0x0B;                  // Analog Comparator Control And
2
                                // Status Register configuration
3
                                // (0b00001011)

OK, das ACSR das Analog Comperator Control And Status Register ist, mag 
vielleicht wirklich nicht jeder wissen. Wenn man sich aber klar macht, 
worum es im Programm geht, sollte eigentlich klar sein, dass es sich 
dabei wohl kaum um ein Konfigurationsregister für die UART handelt. Dass 
du mir als Leser die 0x0B in Bits aufdröselst, ist zwar nett, bringt 
mich aber auch nicht weiter wenn ich mir die Frage stelle: Was, zum 
Henker, stellt er da eigentlich ein?
Was ich mir wünschen würde ist, dass da steht, dass der Interrupt 
enabled wird und auf welche Flankenrichtung der Interrupt reagiert. Aber 
das steht nicht da. Um das rauszukriegen muss ich das Datenblatt 
rauskramen und erst mal nachblättern und Bits vergleichen.

von Kevin H. (raeak)


Lesenswert?

Vielen Dank für eure Antworten, sie waren auf jeden Fall 
aufschlussreich.

Ja kann ja sein, dass ich das Programm einzeln auflösen sollte und es 
mir genauer anschauen muss, darauf bin ich aber selber schon gekommen 
und ich habe den Fehler nicht gefunden.

Das mit den Kommentaren, nehme ich mir wirklich zu herzen, wenn ich 
erlich bin, ist das einer meiner ersten "richtigen" Programme und bin 
ich total neu in der Materie.

Natürlich gebe ich keine 10V auf den Controller, die Spannungen sind 
fest vor gegeben worden und werden über einen Spannungsteiler geteilt.

Ich werde mir jetzt noch einmal das Datenblatt genauer anschauen, 
vielleicht habe ich ja wirklich ein paar Fehler gemacht.

Vielen Dank euc vorerst!

PS:
Klar scheint es für manche Menschen den Anschein erwecken, ich klatsch 
hier mal mein Fehler rein und lasse andere suchen... naja ist ja 
indirekt auch so... aber für was würde es den dann dieses Forum hier 
geben, wenn man sich nicht untereinander helfen kann?

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.