PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Analoge Ports ansteuern



addict
21.03.2005, 20:51
Hi

Ich benutze das Board von Robtikhardware Mega32....
Dazu habe ich 2 Getriebemotoren, welche einen Umdrehungssensor (Lichtschranke haben)
Nun möchte ich eine funktion, welche die Umdrehungen der Räder misst...
Wenn eine gewisse Anzahl umdrehungen erreicht ist, soll die Funktion eine Rückmeldung geben. Wie realisiere ich dies?

Arexx-Henk
21.03.2005, 21:46
Angenommen die Lichtschranke liefern ein digitalse signal '0' und '1'.

die einfachste (nicht schonsten) losung:

1. Lichtschrank an einem eingang anschliessen
2. eingang continuierlich abfragen ob eingang '0' ist, wenn '1', weitergehen
3. dann ein timer starten
4. eingang continuierlich abfragen ob eingang '1' ist, wenn '0', weitergehen

5. timer auslesen
6. wieder bei 2. anfangen

die timerwert ist ein mass fur die geswindigkeit


wie wurde ich dass machen?

Ich verbinde die lichtschrank mit einem mikrokontroller interrupt eingang.
Jedes mahl dass die lichtschrank von '0' nach '1' oder umgekehrt schaltet wird die interrupt function angerufen. In die interrupt function erhohe ich ein zahler variabele A.

ich configuriere ein timer so dass er 1 sekunde braucht um von einen voher betimmten startwert bis zum maxwert (beim hochzahlen) oder minwert (beim zuruckzahlen) ein interrupt generiert. In die interrupt software wird dan die startwert aufsneu geschrieben fur die nachtste sekunde. In die interrupt function lese ich die zahler variabele A (ein mass fur die geswindigkeit) und mache etwas damit und mache A wieder 0.

nur so einige ideen, bin uberzeugt gibts fast noch eine menge andere

gruss

Henk

addict
21.03.2005, 22:25
Ich möchte eine interrupt-Funktion schreiben, aber ich habe eben keine Ahnung, wie dies funktioniert, aus diesem Grund währe ein Beispiel sehr praktisch...

das 2. Problem ist, dass die Lichtschranke nicht immer einen gleichen Spannungswert liefert (aus diesem Grund kann ich keinen Digitalen Port brauchen) Wie lesen ich aber einen Port aus? (wenn ich die Adresse weiss)????

3. Wie programmiere ich einen Timer ein?

Wenn ich je ein Beispiel haben könnte, zu den drei Problemen, würde ich den Rest scho irgendwie hinkriegen....

Vielen Dank!

Alter Knacker
21.03.2005, 22:36
@ Arexx-Henk:

cool, danke!
so stell ich mir antworten vor!
man braucht ja nicht immer einen code, es geht ja viel öfter einfach nur um die vorgehensweise...
danke, hat zwar jetzt nicht mit dem thema zu tun, aber mir hilfts weiter ;-)
mfg knacki

Arexx-Henk
22.03.2005, 20:36
@addict

wass betrift interrupts, ein beispiel fur eingang INT0/PD2/pin16


//algemeine interrupt einschalten (sonst lauft uerhaupt kein einziges interrupt)
SREG|=(1<<7);

//speziales interrupt fur eingang INT0/PD2/pin16 einschalten
GICR|=(1<<INT0);

//interrupt soll entstehen wenn eingang INT0/PD2/pin16 von hoch zu niedrich geht
MCUCR|=(1<<ISC01) | (1<<ISC00);

//dazu sollte man INT0/PD2/pin16 als eingang schalten
DDRD&=^(1<<PD2);

//diese function, wenn so geschrieben, wird vollautomatisch, jedesmahl ausgefuhrt, so oft wie die eingang INT0/PD2/pin16 niedrich geht
SIGNAL SIG_INTERRUPT0
{
//mache etwas, ein LED an/aus
}

Da gibts so 15 verschiedene art von interrupts die sind alle definiert in die datei iom32.h irgendwo auf deinem computer.
z.B. ein interrupt, immer wenn timer0 hoch zahlt und dann von 0xFF nach 0x00 weiter zahlt.

Ein interrupt wird automatisch ein laufendes program unterbrechen, die interrupt function wird ausgefuhrt, und wenn die interrupt function fertig ist, geht das laufende program wieder weiter wo es geblieben war gerade vor dem interrupt unterbrechung.

gruss

Henk

Arexx-Henk
22.03.2005, 21:34
@addict


Wie lesen ich aber einen Port aus? (wenn ich die Adresse weiss)????


Mit 'C' ein port auslesen zb PortB auf adress 0x16


#define PINB _SFR_IO8(0x16)
#define DDRB _SFR_IO8(0x17)
#define PORTB _SFR_IO8(0x18)


//wenn PB0/XCK/T0/pin1 hoch ist,
if ( PINB & 0x01 )
{
//mach etwas
}


oder


unsigned char MeinWert ;
MeinWert = PINB ;
if ( MeinWert & 0x01 )
{
//mach etwas
}


PortB sieht so aus


bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
pin8 pin7 pin6 pin5 pin4 pin3 pin2 pin 1

Ports lassen sich bytewise/bitwise lesen/schreiben.
Pas mahl auf! Data schreibt man nach PORTB und data liest man von PINB.
Wenn mann PORTB lehst, lehst mann nur die weggeschriebene wert wieder zuruck und nicht die elektrischen pin-status
(hat mich schon manche Stunde gekostet)


#define PINB _SFR_IO8(0x16) usw
brauch mann nicht selber zu definieren, diese definitionen bevinden sich im datei iom32.h


gruss

Henk

Arexx-Henk
22.03.2005, 22:03
@addict


2. Problem ist, dass die Lichtschranke nicht immer einen gleichen Spannungswert liefert (aus diesem Grund kann ich keinen Digitalen Port brauchen)

analogue port benutzen



3. Wie programmiere ich einen Timer ein?

Die Atmega32.pdf studieren. O:)

beispiel timer0
Timer0 zahlt hoch bis 255 (0xFF) und fangt dan wieder bei 0 an.

//prescaler (Getriebegehause) /256 nutzen, macht die taktfrequenz vom timer0: 8Mhz (externen oszillator) / 256 = 31,250KHz. TCCR0 |= (1<<CS02);

Jetzt fangt die timer0 an zu laufen.


timer0 zahlt bis 255, so angesteurt mit 31,250KHz mach 1/31250 = 32us pro schritt.
256 (0 bis 255) schritte mahl 32us = 8192us = 8,192ms so lange daurt jeden 'rundgang'.

Jetzt kan mann register TCNT0 auslesen und wird immer ein anderen Wert bekommen. TCNT0 ist die aktuellen timer wert.

//Da blinkt die LED an jedes mahl wenn timer0 64 ist und blinkt aus wenn timer0 186 ist.
//so jeden 8,192ms geht die LED mahl an und aus, (mit die augen nicht zu sehen, sollte nur etwas weniger hell leuchten.
while(1){
if(TCNT0==64)
{
//mach LED an
}
if(TCNT0==186)
{
//mach LED aus
}
}
Die timer0 lauft hardwaremassig unabhangig vom programablauf.

Mann kann beliebig die aktuellen timerwert andern, zb mit TCNT0=33;, da fangt die timer direkt an weiter zu zahlen ab 33.

mit dem prescaler (Getriebegehause) kann mann die timer anhalten.
Bit 0,1 und2 niedrich machen.
TCCR0 &= ~((1<<CS02)|(1<<CS01)|(1<<CS00));

Dass auslesen vom TCNT0 liefert jetz immer dieselben wert.

gruss

Henk