Hi, Ich find beim Winavr nur
__MMIO_BYTE () u.
__MMIO_WORD ()
und die in <sfr_defs.h>
Soll nix heißen, aber wenn keiner was besseres weiß, kannst du ja probieren. mfg
Hallo,
Ich möchte gern meinen AVR dazu benutzen eine Regelung zu machen.
Dazu muss ich mehrere Potis einlesen in nur einen µC.
Ich hab mir das so vorgestellt:
Dazu muss der Pin am µC als Ausgang auf HING gesetzt werden.Code:Vcc | C1: 100nF | +---(R2 220)---->µC | | Poti 10K | - GND
Dadurch dass an C1 nun an beiden Seiten +5V anliegen, wird dieser entladen.
Schaltet man nun den Pin des µC als Eingang, so wird C1 über das Poti geladen.
Nach einer bestmmten Zeit unterschreitet die Spannung am Pin des µC die "schwellspannung von ca. 2.2V und der µC hat ein LOW auf seinem Eingang.
Diese Methode habe ich aus einer Anleitung herausgelesen und hoffentlich richtig interpretiert.
Leider weiss ich nochnicht wie ich einen Pin des µC als Eingang und gleichzeitig als Ausgang benutzen kann.
in der anleitung ging es mit dem Befehl "__mmio" (Memory mapped I/O)
Das will der Compiler aber nicht, sagt immer error.
hier mal mein Code (Verwendet wurde pin 0 von Port A):
Kann von euch jemand evtl den Fehler finden?Code:#include <io.h> typedef unsigned short WORD; typedef unsigned char BYTE; int main (void) { volatile WORD x; register WORD y; // Portpin auf Ausgang setzen. __mmio (DDRA) = __mmio (DDRA) | (1 << 0); // Portpin auf HIGH setzen __mmio (PORTA) = __mmio (PORTA) | (1 << 0); // Kondensator entladen, indem der Ausgang auf HIGH (Vcc) gesetzt wird. for (x=0; x<50;) x++ /* Zaehlen */; y = 0; // Portpin auf Eingang schalten. __mmio (DDRA) = __mmio (DDRA) & ~(1 << 0); /* Zaehlschleife. Wir zaehlen y so lange hoch bis der Kondensator unter die Schwellwertspannung geladen ist. */ while (__mmio (PINA) & (1 << 0) && y < 65535) y++; // Zählerwert zurückgeben return y; }
Oder mir eine einfachere Programmvariante nennen?
Ich hab schon das ganze Forum durchstöbert und konnte leider nichts treffendes finden.
Hi, Ich find beim Winavr nur
__MMIO_BYTE () u.
__MMIO_WORD ()
und die in <sfr_defs.h>
Soll nix heißen, aber wenn keiner was besseres weiß, kannst du ja probieren. mfg
Wie auch immer, der Trick is nicht schlecht, den verwendet im Prinzip LEGO Mindstorms für seine Sensoren. Alle (aktiven) Sensoren haben Graetz-Gleichrichter, mit dem sie den kurzen Out-Impuls in passenden Saft verwandeln. Man spart draht und kann anstecken, wie man will (is ja für Kinder). mfg robert
Hallo,
@ Pascal
A/D Wandler wollt ich auch schon benutzen, aber die µC haben leider, so viel ich weiß, keine 5 Stück...
Ich finde das Prinzip auch super,
Vor allem weil man fast keine Komponenten braucht und jeden beliebigen Port-Pin verwenden kann.
Im Prinzip bräuchte ich nur einen Befehl mit dem ich einen Pin als ausgang UND Eingang verwenden kann...
Falls das nicht gehd muss ich halt nen zweiten Pin benutzen, und mit diesem immer wieder den Kondensator Entladen ( über Diode dazuschalten ):
(Diode ist nötig, da ja sonst wenn der Ausgang auf LOW steht, GND am eingang anliegt und das ergebnis hinfällig macht....Code:Vcc+5V | | C1 100nF | | +--- ( |< Diode )---( 220R )---µC "entlade Pin " | +-----------------------µC "lesepin" | | Poti 10K | | _ GND
Der Programmablauf müsste im Grunde nur folgendermaßen aussehen:
- Entlade C1: Ausgang auf HIGH ( zB 50ms lang, je nach Kondensatorgröße )
- Umschalten auf Eingang (entladevorgang abschalten) und zählen bis LOW anliegt
- Zählerwert ausgeben und zurücksetzen
das Ganze ständig wiederholen.
Wär halt cool wenn man dafür nur einen Pin bräuchte.
Vielen Dank für eure Bemühungen!
mfg
Hi, also das Out-definieren mach ich beim Winavr direkt DDRx = 0x11
Mit dem AD Wandler müßtest du dich noch auseinandersetzen, damit er inzwischen Ruhe gibt
Vielleicht geht das auch überlappt, d.h wenn du einen PIN High setzt zum C-Laden, kann er ja derweil einen anderen Kanal digitalisieren, mfg
Hallo
hier ein Link zum Thema
http://www.atmel.com/dyn/resources/p...ts/DOC0942.PDF
Dieter
die haben vielleicht keine 5 ADCs, aber dafür einen 6 oder 8 kanaligen ADC, du kannst also, je nach AVR, bis zu 8 analoge Signale einlesen(zeitlich versetzt)A/D Wandler wollt ich auch schon benutzen, aber die µC haben leider, so viel ich weiß, keine 5 Stück...
@ Pascal
Muss ich ganz ehrlich zugeben, das mit den Kanälen hab ich nicht gewusst... Muss ich mich noch einlesen.
@ Gast,
Danke für den Link, werd ich mir demnächst mal vornehmen
Ich hab in der zwischenzeit schon experimentiert und das Programm für die " 2-Pin-Variante" geschrieben. ist evtl. noch ein bisschen umständlich,
muss noch optimiert werden:
Code:#include <avr/io.h> typedef unsigned char BYTE; typedef unsigned int WORD; WORD entladedauer; // Variable für Entladungsdauer WORD entladen_1; // Variable zum zählen der Entladungsdaue WORD poti_1; // Variable zum zählen des Widerstandswertes int main(void) { outp (0x01,DDRA); // PORT A: PIN 0 als Ausgang, Rest Eingang outp (0xFF,DDRB); // PORT B: Ausgabe des ermittelten Wertes entladedauer = 500; // hier wird die entladedauer festgelegt... entladen_1 = 0; poti_1 = 0; for(;;) { if( entladen_1 >= entladedauer ) { // Wenn lange genug entladen cbi (PORTA, 0); // entladung stoppen ( Pin0 auf LOW ) if( !bit_is_clear (PINA, PIND1)) { // solange der zählpin HIGH ist, zählen poti_1++; } if( bit_is_clear (PINA, PIND1)) { //wenn Zählpin LOW wird, outp (poti_1, PORTB); //Wert des Widerstands ausgeben poti_1 = 0; //Wert zurücksetzen für neue Messung entladen_1 = 0; //Wert zurücksetzten für neue Entladung } }else{ // ansonsten wenn Kondensator nicht genügend entladen, sbi (PORTA, 0); // entladen ( PIN0 auf HIGH ) entladen_1++; } } }
Bei einem Poti mit 10K und einem Kondensator mit 100nF
Erhalte ich am Ausgangsport Werte zwischen 0 und 40.
nicht gerade die beste Auflösung, aber ich werd mal mit den Kondensator und Potiwerten Experimentieren.
Ansonsten Funktioniert es einwandfrei.
Was meint ihr dazu?
ist es umständlicher oder einfacher als über A/D wandler?
(hier bin ich nicht pingebunden....)
Lesezeichen