Hallo, ich will mit einem Tiny13 per ADC eine Spannung messen, die ich
dann proportional als Blinkfrequenz eines LEDs ausgeben möchte.
Dazu habe ich folgenden Code geschrieben:
1
#define F_CPU 1200000UL // Quarz mit 1,2 Mhz (interner Oszillator)
2
3
#include<avr/io.h> // Library für Hardwaredefinitionen etc.
4
#include<avr/interrupt.h> // Definitionen für Interruptroutinen
5
#include<avr/signal.h> // Interruptroutinen 2
6
#include<stdint.h> // Integer Datentypen
7
#include<util/delay.h> // Verzögerungsschleifen
8
9
10
11
// Funktionen:
12
13
uint16_tMessung(void);//ADC Messung
14
15
16
// Variablen:
17
18
uint16_trfsignal=0;
19
uint8_tcounter=0;
20
uint8_tcompare=0;
21
22
23
// Hauptprogramm:
24
25
intmain(void)
26
{
27
28
// Timer initialisieren:
29
30
TIMSK0&=~((1<<TOIE0)|(1<<OCIE0A)|(1<<OCIE0B));//Interrupts für Timer 0 deaktivieren
//Dummy-Messung zwecks ADC Initialisierung bzw. nach Referenzspannungswechsel
88
89
ADCSRA|=(1<<ADSC);// eine ADC-Wandlung
90
while(!(ADCSRA&(1<<ADIF)));// auf Abschluss der Konvertierung warten (ADIF-bit)
91
ADCSRA|=(1<<ADIF);// ADIF löschen
92
93
// Eigentliche Messung
94
95
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
96
while(!(ADCSRA&(1<<ADIF)));// auf Abschluss der Konvertierung warten (ADIF-bit)
97
result=ADCW;// Wandlungsergebnis
98
ADCSRA|=(1<<ADIF);// ADIF löschen
99
100
ADCSRA&=~(1<<ADEN);// ADC deaktivieren (2)
101
ADMUX=0x00;// ADMUX löschen
102
103
returnresult;// Rückgabewert der Funktion = Messwert
104
}
Mein Problem ist, dass egal wie groß das Eingangssignal ist (liegt
zwischen 1 und 2,5V), die LED immer gleich schnell blinkt, und zwar so
schnell, als wäre der Wert rfsignal = 0 (als meiner Meinung nach, obwohl
ich die Blinkfrequenz nicht genau nachgemessen habe).
Es muss fast an der ADC Funktion liegen (diese habe ich aus dem AVR GCC
Tutorial), da ich bereits probiert habe in meine Formel statt der
Variable rfsignal Werte einzusetzen und da hat alles wunderbar geklappt.
Mache ich bei der Messung irgendetwas falsch?
Zur Info, ich verwende den Pin ADC3 als Eingang und die LED hängt an
PB0.
Ich habe auch schon probiert, den sleep Modus wegzulassen, dies ändert
aber nichts.
Christof Kauba wrote:
>> ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); //Initialiserung> ADC, Frequenzteiler: 8> ADMUX = 0x03; //Zu verwendender Pin, ADC3>> //Versorgungsspg. als Referenz
Denke mal, dass das beim Tiny ähnlich ist. Bei den Megas
ist es so, dass kein REF Bit gesetzt externe Referenz bedeutet.
Wenn du also an ARef nichts angeschlossen hast, dann ist deine
Referenz auf 0.
Schau aber zur Sicherheit noch mal ins Datenblatt des Tiny.
Der Tiny13 kann keine externe Referenz. REFS = 0 ist VREF = VCC. Müsste
also zumindest was Sinnvolles rauskommen.
@Christof:
Was soll denn die Multiplikation mit -2517 bewirken? Ist mir grad etwas
schleierhaft...
Und counter ist nicht volatile deklariert, wird aber in ISR und
Hauptprogramm verwendet. Außerdem sollte SIGNAL (und auch die signal.h)
nicht mehr verwendet werden. Ist veraltet.
>Was soll denn die Multiplikation mit -2517 bewirken?
compare = 125 - 0.2517*rfsignal
Ich schätze mal, je größer die Spannung umso kleiner die compare-Zeit,
damit das Blinken schneller wird ?!
Hi Christof,
Problem noch aktuell?
Zufällig hab ich was mit 'nem ATtiny13 gemacht und konnte es mal eben
hier ausprobieren. Und bei mir funktioniert dein Programm einwandfrei.
Lass mich raten: Du machst das alles mit einem STK500. Und um dort einen
ATtiny13 zu programmieren muss man 2. "Drähte verlegen".
Und der eine geht von XT1 auf PB3. XT1 gibt ständig das Clocksignal
raus.
Zieh die Verbindung mal ab so das auch nur deine zu messende Spannung an
PB3 anliegt. Sollte dann funktionieren.
Gruß, Jan
Hallo,
ja das Problem ist noch aktuell.
Nein ich verwende kein STK500, sondern eine selbstgeabute Schaltung.
Ja laut Datenblatt des ATTiny13 kann er nur die interne Referenzspannung
von 1,1V oder die Versorgungsspannung als Referenz verwenden.
Das Programmieren funktioniert einwandfrei (ich verwende PonyProg).
Außerdem ist mir gerade aufgefallen, dass eigentlich statt
1
#include<avr/signal.h> // Interruptroutinen 2
1
#include<avr/sleep.h> // Library für Sleep-Modes
stehen sollte. Muss mir wohl ein Fehler beim Kopieren unterlaufen sein.
Muss ich die variable counter unbedingt als volatile deklarieren?
Denn wie gesagt, wenn ich statt rfsignal einen fixen Wert verwende,
funktioniert das Ganze.
> Das Programmieren funktioniert einwandfrei (ich verwende PonyProg).
ne, ja, nein, doch - ich hab mich vielleicht falsch ausgedrückt. ALLES
funktioniert bei mir. also die LED blinkt hier proportional zur spannung
mit genau dem oben gepasteten programm!
am programm liegt es ja dann wohl nicht. dann zeig bitte mal den
schaltplan.
Christof Kauba wrote:
> Muss ich die variable counter unbedingt als volatile deklarieren?
Schaden kann es auf keinen Fall.
> Denn wie gesagt, wenn ich statt rfsignal einen fixen Wert verwende,> funktioniert das Ganze.
Ich würde mal folgenden Versuch machen.
Nur den ADC auslesen und das Ergebnis auf ein paar Leds ausgeben
(je mehr desto besser). Dann ein Poti an den ADC und schauen ob
sich an den LED was tut. Damit möchte ich feststellen, ob vom
ADC überhaupt irgendein Wert daherkommt, der ADC also grundsätzlich
funktioniert, oder ob der Wert erst danach irgendwo versickert.
Offensichtlichen Fehler seh ich sonst keinen im Programm und
Jan hat auch gepostet, dass es bei ihm funktionieren würde.
Vielleicht ist es ja auch was ganz Banales wie: den falschen Pin
am Tiny erwischt.
Schaltplan hab ich jetzt so nicht explizit gezeichnet.
Wie schon erwähnt ist die Spannung (Ausgang eines Funkempfängers) auf
dem ADC3 Pin angschlossen, und die LED an PB0 und über einen 470 Ohm
Widerstand zu GND.
Ansonsten ist eigentlich nichts angschlossen, außer ein 100 nF
Kondensator zwischen Vcc und GND.
Ich messe am ADC Eingang eine Spannung von 2V, wenn ich ein Signal
empfange, und wenn ich keines empfange, bzw eigentlich wenn ich keines
sende messe ich immer noch 1,3V auf Grund von Störsignalen, die das
Modul empfängt.
Aber die Blinkfrequenz ändert sich nicht.
Hast du genau die gleichen Pins verwendet?
OK, ich glaube ich habe den Fehler gefunden.
Mein Tiny13 dürfte hardwaremäßig nicht in Ordnung sein, ich habe es
jetzt mit einem anderen Tiny13 getestet und da funktioniert alles
einwandfrei.
Hmmmm...
Da ich hier grad ein STK500, einen Tiny13, ein JTAG ICE MKII und eine
LED liegen hatte dachte ich mir ich schau mal nach.
- Tiny13 in STK500
- JTAG ICE MKII dran
- Dein Programm über GNU Plug-In, Copy-Paste in AVR Studio
- LED und externe DC Spannungsquelle an GENAU DIE SELBEN Pins
- Programm rein, JTAG loslaufen gelassen und an der Spannung gedreht.
- Mit steigender Spannung wächst die Blinkfrequenz
(wie gesagt, außer das es zuerst nicht ging weil XT1 noch an PB3 hing)
Vielleicht ist die Ausgangsfrequenz deines Funkempfängers ja die gleiche
wie die Abtastung deines ADC ;-)
Ne, bin jetzt grad auch ratlos...
> OK, ich glaube ich habe den Fehler gefunden.
also doch was banales. wahrscheinlich ADC3 geschrottet. kann unter
umständen mal eine Spannung > 5V aus deinem Funkempfänger kommen? Dann
würde ich mal eine Schutzbeschaltung davorhängen.
gruß, jan
Also laut Datenblatt des Funkempfänger ist die maximale Spannung an
diesem Ausgang 2,53V.
Ich habe auch um sicherzugehen mal beim Einschalten nachgemessen, ob
nicht vielleicht Spannungsspitzen auftreten, habe da aber auch keine
Spannung größer 2,5V gemessen.