PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Quelltext Erklärung



tomkay
04.10.2004, 14:01
Hallo zusammen!

Das ist mein erster Beitrag und ich muß loswerden, dass das Forum hier echt spitze ist :)!

Nach langem lesen der Threads hab ich mich entschlossen, dass RN-Control zu bestellen. Kaum bei mir angekommen, alles zusammengelötet, das Testprogrammen laufen gelassen und "AHHHH, es funktioniert alles"..

Nachdem ich nun die ersten LED's zum leuchten gebracht habe, der erste Motortest lief, will ich natürlich selbst mal nen Quelltext zusammenfrimmeln ;)!

Das hab ich auch gemacht - Ziel war es, mit der Taste 1 auf dem RN Control Board eine LED zum leuchten zu bringen, mit der Taste 2 es wieder ausschalten, mit Taste 3 alle zum leuchten zu bringen und mit Taste 4 alle wieder ausschalten - was soll ich sagen, ich habs hinbekommen und es klappt!

Nur versteh ich meinen eigenen Quelltext nicht :^o

Hier mal der Quelltext:


$crystal = 16000000
$baud = 9600

Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung

Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein

Config Portc = Output
Dim Ws As Word

Do


Start Adc
Ws = Getadc(7)
If Ws < 1010 Then

Select Case Ws

Case 410 To 450 'Taste 1: erste LED wir angeschalten
Ddrc = &B00000001
Case 340 To 380 'Taste 2: erste LED wird ausgeschalten
Ddrc = &B00000000
Case 265 To 305 'Taste 3: Alle LED's werden angeschalten
Ddrc = &B11111111
Case 180 To 220 'Taste 4: Alle LED's werden ausgeschalten
Ddrc = &B00000000

End Select

End If

Waitms 100

Loop

End

Jetzt zu meinen Fragen (hab schon im Forum und im Internet gesucht, doch leider nichts brauchbares gefunden):

- Kann mir jemand erklären, was genau die begriffe PORTX, PINX und DDRX bedeuten bzw wie sie zusammen eine Rolle spielen?

- Bei der Tastenabfrage die Zahlen bis 1010 eine Rolle spielen (Taste eins wir mit dem Befehl "Case 410 To 450" abgefragt -> was bedeutet 410 bis 450??

- Was der Begriff config ADC = ... , Start ADC und getadc(x) bedeuten

- Warum die Variable Ws als Word deklariert wird, und nicht zum beispiel as Integer.

- Ob es ne Seite im Internet gibt, die sich mit dem Einstieg in Bascom beschäftig (quasi ein online Einsteigerbuch für Bascom)

Ok, soweit sind das mal meine ersten Fragen dazu. Ich weiß, ich könnt mir ja ein Buch kaufen, aber die Fragen interessieren mich gerade ziemlich ;)!

Ich bedank mich schonmal für evtl Antworten :)!

RCO
04.10.2004, 14:28
Also alle Fragen kan ich dir auch nciht beantworten, aber einige:
POrtX ist der geamte Port, also 8 ein bzw. ausgänge. du akknst dann ein Byte darüber parallel ausgeben.
PinX ist ein einziger Pin, deshalb auch die nummer dahinter.
Bei der Tastatur sind mehrere Widerstände in Reihe geschaltet, je nach dem welche Taste du drükst, kommt halt ein verschieden 'hoher' Spannungswert raus. ADC ist der Analog Digital-Converter. er liefert dir in diesem Fall einen WErt zwischen 0 und 1023. Wenn der WErt größer 1010 ist, ist keine Taste gedrückt, man könnte vermutlich auch < 1023 schreiben, aber eine gewisse Toleranz ist besser, oder es fließt immer eine geringer Strom, das häng vom Aufbau der Tastur ab. Liefert der ADC einen Wert zwischen 410 und 450. ist halt die 1 gedrückt. diese werte sollte man am besten ausmessen, wenn man nciht genau weiß, wie man sie errechnet. WS wird als Word deklariert, weil der gespeichert Wert zu groß für einen Integer ist, Integer gehen von 0 bis 255. Da die Wert aber halt bis 1024 gehen, braucht man eine Variable mit mindestens 10 Bits. Der Integer hat nur 8 das Word 16.
So ich hoffe, ich konnte dir ein wenig helfen, wenn du noch fragen hast frag nur. Das mit Start DC und get ADS ist glaub ich deshalb so, weild er ADC initialisert werden muss, und dazu ein wenig Zeit benötigt. So ungefähr müsste das sein. Warum es getadc(7), also 7 heißt, weilß ich nicht, schau mal in der hilfe nach. Ne vernünftige Anleitung im Internet hab ich nicht gefunden. Ich geh da eher nach Try and error vor, und schau mir halt an, wie es in anderen Codes ist, bzw. frage einfach im Forum nach.

MFg moritz

RCO
04.10.2004, 14:29
Ach so, vermutlich sind ADC nur an PortA möglich, von daher getADC(7)!
Buchempfehlung schreibe ich noch, uss nur gerade mal schauen wies heißt.

fzehner
04.10.2004, 14:42
- PORTx, PINx und DDRx beschreiben den Zustand des Ports. Mit DDRx wird festgelegt, ob der Port als Ein- oder als Ausgang verwendet werden soll, mit PORTx wird der Port entweder auf Low oder High geschaltet bzw. wenn der Port als Eingang verwendet wird, wird damit der Interne PullUp Widerstand eingeschaltet. Mit PINx wird der Port abgefragt.

- die Tasten hängen bei der RN-Control alle an einem analogen Eingang, bedingt durch Unterschiede bei der Vertigung und bedingt durch Schwankungen bei der Messung kann sich der Wert ändern, deshalb wird ein Bereich angegeben indem sich der Wert befinden muss.
Bei der Messung wird die Spannung abgefragt, die am Eingang anliegt.
Wert = Umess / Uref * 1024

- Ws wird als Word definiert, weil es eine positive 16bit Zahl ist (10bit wenn man die Auflösung des analog Wandlers nimmt).

tomkay
04.10.2004, 15:21
Ah, also alle Taster sind am Pina.7 angeschlossen und anhand der Spannung wird ausgemessen, welcher Taster gedrückt wird! Ok, ist einleuchtend, nur stellt ich mir (als waschechter Neuling) die Frage, warum die On-Board Taster nicht jeweils einen anderen Pin zugewiesen bekommen haben (z.B. Taster 1 -> PC0, Taster2-> PC1, Taster 3 -> PC2, usw...)! Wäre doch naheliegend, oder? Wird sicherlich seinen Grund haben, dass das nicht so ist, aber von diesem Grundgedanken bin ich ausgegangen und deshalb hat mich das mit der Spannungsmessung doch etwas verwirrt ;)!
Aber gut, jetzt weiß ich es ja!

Danke für die echt schnellen Antworten, werd jetzt mal ein wenig rumbasteln und rumprogrammieren!

RCO
04.10.2004, 15:59
Also der Grund dafür, dass man nicht jedem Taster einen eigenen Wert zuweist, ist einfach der, das man da halt teilweise enorm viele Ports spraen kann. ICh weiß nciht, wie viele Taster auf deinem Bord da dran hängen, aber wenn du mal überlegst, das ein einfaches Tastenfeld mit * und # 12 Tasten hat, kannst du dir sicher vorstellen, warum man es so macht.

MFg Moritz

Frank
04.10.2004, 17:18
So ist es. Wenn man die Taster an einen analogen Port hängt wird halt nur ein Port belegt. Die anderen Ports kann man noch fein für andere Dingen nutzen, freie Ports kann man nie genug haben.
Ist also wirklich nur um Ports zu sparen, ansonsten hätte man natürlich pro Port einen Taster machen können.
Im übrigen könnte man an den gleichen analogen Port auch noch weitere taster anhängen wenn man geschickt die Widerstände wählt. Man muß dann nur die Abfrage anpassen.

martin
04.10.2004, 17:25
Hallo,

ich behaupte jetzt nicht von mir, ein Bascom-Spezialist zu sein, aber warum werden die Ports mit 'DdrC' an und ausgeschalten?
Sollte das nicht eher PortC heißen ???

Kann ja durch Zufall sein, daß es funktioniert, aber ist das richtig?



Ddrc = &B00000001


Grüsse, Martin

RCO
04.10.2004, 17:30
Also so weit ich weiß, kann man beides schreiben, mit:
PortC deklariert man den ganzen port als ein oder Ausgang
mit:
DDRC = &B00000001 deklariert man die ersten 7 (oder letzten 7?) als Eingang (oder Ausgang?), und den letzten umgekehrt.
Wenn du viele Ports gemsicht hast, also z.B:
Port C1, C3 und C4 als Asugang, und die anderen von C als Eingang, dann ist die DDRC Methode sinnvoller, aber es wird ja nunmal der Ganze Port zum Ausgang gemacht.

MFg Moritz

tomkay
04.10.2004, 18:00
Genau so habe ich es als Anfänger auch verstanden!

Port X = input/output bennent den ganzen Port zum Ein- bzw Ausgang...

DdrX benennt nur die einzelnen Pins!

Im Endeeffekt sind beide Befehle gleich, wenn man den kompletten Port zum Ein- bzw Ausgang machen will!(also es ist egal ob man PortC = output oder Ddrc = &B11111111 schreibt)

Ist dann wohl Geschmacksache, wie mans macht (es sei den, man will wirklich nur einen Pin ansprechen), wobei ich die DdrX methode irgendwie übersichtlicher finde... jede Ziffer im code steht für einen Pin, den man nach belieben konfigurieren kann!

Hoffe ich erzähl hier keinen Müll ;)!

04.10.2004, 19:15
Das gleiche geht glaub ich auch mit Conifg Portx = &b00001111 (0 = Eingang / 1 = Ausgang)

öhm...RCO... war nicht ein Byte (8Bit)von 0 bis 255 und ein Integer wie ein Word (16 Bit) aber mit zulässigen Wertzuweisungen von
-30tausendirgentwas bis +30tausendirgentwas?!??!? (und ergäbe nicht -(-30tausendirgentwas) + +30tausendirgendwas zusammen 65534 ?!?)Lass mich nicht verzweifeln. Bin grad ganz schön am grübeln... ;)

RCO
04.10.2004, 19:48
öhm...ja möglich! :oops: ;-)

05.10.2004, 10:51
Einen guten Einstieg in Bascom gibt es auf der Seite von Roland Walter( http://www.rowalt.de/mc/index.htm). Kann auch sein Buch dazu empfehlen.

Gruß Jens

fzehner
05.10.2004, 10:52
viele Wege führen nach Rom

config portX = input / output 'setzen des ganzen Ports
config portX.Y = input / output 'setzen eines einzelnen Pins
ddrX = &B00001111 'setzen des Ports

wenn das Programm leicht zu lesen sein soll, dann würde ich config verwenden; soll das Programm vielleicht nach Assembler übersetzt werden, dann sollte ddrX verwendet werden.

ein Byte (8 Bit) - 0 bis 255
ein Integer (16 Bit) - -32768 bis 32767
ein Word (16 Bit) - 0 bis 65535
bei Integerzahlen wird das höchstwertige Bit als Vorzeichen verwendet, das ist ansich der ganze Unterschied zum Word

05.10.2004, 11:06
Kleine Korrektur:

config portX.Y = input / output 'setzen eines einzelnen Pins

Das funktioniert nur bei Output.
Wenn eine Leitung als Input fungieren soll, muß man es so definieren:

config pinX.Y = input

Toastbrot
23.01.2005, 19:58
Das ist ein super Thread, genau das habe ich gesucht! Vielen Dank an alle.

Das ganze hat jetzt jedoch noch einige Fragen bei mir aufgeworfen! Warum das "Waitms 100" am ende der Schleife, dadurch hat man doch nur unnötige Verzögerung! Bei mir funzt es ohne das Wait eigentlich genauso nur eben schneller. Daraus entsteht jetzt die nächste Frage: wenn ich alle LEDs an/aus schalte, passiert das sofort beim drücken. Wenn ich nur eine anschalten will, muss ich den T1 dafür einige Sek. gedrückt halten, warum?

So, genug erstmal. Jetzt werd ich mieder Learning by doing und Try & error machen :D

Toastbrot
24.01.2005, 18:11
Hallo,
ich habe einiges Probiert und auch vieles davon früher/später hinbekommen. Jetzt habe ich mir eben mal ein Taster mit 2 Drähtchen zusammen gebastelt, den ich als Test-Sensor erstmal verwenden wollte. Den habe ich an meiner RN-Control zwischen +5V und Port A.2 (also den 3.) geklemmt. Mein ganz simples Motoren Test Progg soll anhalten bzw. den Motor anders herum drehen, sobald dieser Port durch den Taster auf High gesetzt wird.

Das tut es leider nicht. Programmier-technisch ist das auch noch nicht so schön gelöst, noch ist diese Prüfung in ner While Endlos Schleife, wodurch alle anderen Taster (die oboard) in der Zeit blockiert sind.

Vllt kann mir ja jemand helfen, hier erstmal der Code:


$crystal = 16000000
$baud = 9600
$regfile = "m32def.dat"


Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung

Config Pina.2 = Input 'Testsensor
Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein
Porta.2 = 1

Config Portc = Output
Config Portb = Output

Dim Taster As Word
Dim Sensor As Word
Dim I As Integer
Dim N As Integer
Dim B As Boolean

Ddrc = &B00000001

Do


Start Adc
Taster = Getadc(7)
Sensor = Getadc(2)

If Taster < 1010 Then

Select Case Taster

Case 410 To 450 'Taste 1: Motor 1 Dreht 1
Sound Portd.7 , 100 , 200
Ddrc = &B10000000

Do While Not B 'Dauernd prüfen
If Sensor < 1000 Then
Ddrc = &B00000000 'Wenn Hindernis, dann Rückwärts bzw. aus!
Exit Do
End If
Loop

Case 340 To 380 'Taste 2: Motor 1 Dreht 2
'Sound Portd.7 , 100 , 400
Ddrc = &B01000000

Case 265 To 305 'Taste 3: Motor 2 Dreht 1
'Sound Portd.7 , 100 , 200
Ddrb = &B00000010

Case 180 To 220 'Taste 4: Motor 2 Dreht 2
'Sound Portd.7 , 100 , 400
Ddrb = &B00000001

Case 80 To 150 'Taste 5: Motoren Stop
'Achtung, das Funzut auch noch nicht ganz, es geht nur der erste Motor aus!!
Ddrc = &B00000000 'Motor 1
Ddrb = &B00000000 'Motor 2


End Select

End If

Loop

End

Danke!

RCO
24.01.2005, 18:29
Mal ne Frage, wenn du doch den Pullup von A.2 anschaltest un den Taster gegen +5 V schaltest, wo soll da was passieren? Entweder der Taster ist nciht gedrück --> Pullup zieht den Eingang hoch oder Taster ist gedrückt, Taster und Pullup ziehen hoch.

Schalte den taster gegen GND.

MFG Moritz

Toastbrot
24.01.2005, 21:47
Erscheint logisch, danke. Hab das gerade mal umgesteckt... Aber auf die Schnelle habe ich keinen Erfolg verzeichnen können. Muss ich dann abfragen ob der Wert näherungsweise 0 oder 1000 und paar zerquetschte ist?

Toastbrot
25.01.2005, 21:48
N'abend!
Learning by doing hat sich wieder einmal bewährt! Habe das jetzt hinbekommen und weiß auch woran es lag! Ich habe als Endlosschleife eine For Schleife genutzt die nie Endet. Das mag er anscheind nicht. Mit Do Loop gehts ohne Probleme. Außerdem habe ich die Sache mit den Sub's hinbekommen. Alles eigentlich nicht schwer.

Hier mein kleines Programm zum Fahren mit 2 Motoren. Wird ein Hinderniss erfasst, wird kurz zurück gesetzt, etwas nach rechts gedreht und weiter gefahren... Ob die Zeiten in der Praxis OK sind kann ich nicht sagen, aber das ist ja egal.

Was meint ihr, kann man da etwas besser machen? Wie lasst ihr den Bot ausweichen?

Code:
$crystal = 16000000
$baud = 9600
$regfile = "m32def.dat"

Declare Sub Fahren()



Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung


Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein

Config Portc = Output
Config Portb = Output


Dim Taster As Word


Ddrc = &B00000001 'Zu Beginn eine LED an

Do


Start Adc
Taster = Getadc(7)


If Taster < 1010 Then

Select Case Taster

Case 410 To 450 'Taste 1: Fahren bis Hindernis

Call Fahren()


'Case 340 To 380 'Taste 2:



'Case 265 To 305 'Taste 3:



'Case 180 To 220 'Taste 4:



'Case 80 To 150 'Taste 5:



End Select

End If

Loop

End

'#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+# +#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#

Sub Fahren()
Dim Sensor As Word

Sensor = Getadc(2) 'Sensor 1 aktivieren
Config Pina.2 = Input 'Port als Input
Porta.2 = 1 'Port hoch setzen



Ddrc = &B10000000 'Motor 1 Vorwärts
Ddrb = &B00000010 'Motor 2 Vorwärts

Do 'Endlosschleife
If Getadc(2) < 1010 Then 'Wenn Port runter gesetzt wird (Low)

Ddrc = &B01000000 'Motor 1 Rückwärts
Ddrb = &B00000001 'Motor 2 Rückwärts

Print "Hindernis, setze zurueck!"

Waitms 100

'Rechtsdrehung
Ddrc = &B10000000 'Motor 1 Vorwärts
Ddrb = &B00000001 'Motor 2 Rückwärts

Waitms 50

'Geradeaus
Ddrb = &B00000010 'Motor 2 Vorwärts

Print "Setze Fahrt fort!"

End If
Loop

End Sub

albundy
26.01.2005, 15:03
Hallo,
das mit den Port's wird so nicht funktionieren. Kann man im Simulator auch nachverfolgen.
> Config Portc = Output
> Config Portb = Output
Das bedeutet, dass alle Pins auf beiden Ports Ausgänge sind, aber noch hochohmig.
Weiter unten dann:
> Ddrc = &B00000001
Jetzt wird das Datenrichtungsregister direkt angesprochen. ( Im Prinzip das gleiche wie oben )
Nur werden jetzt Pin1 - 7 als Eingänge definiert
Nur "Portc.0 = 1" oder "Set Portc.0" setzt die mit Output definierten Portpin's auf "High" bzw. Logisch "1".

Toastbrot
26.01.2005, 17:14
Es hat aber so funktioniert ;)

Ich habe heute Mittag aber noch was anders gemacht, was die selbe Funktion hat. Ich denke das meinst du auch.

Hier ist meine neue Sub zum Fahren:


Sub Fahren()
Dim Sensor As Word

Sensor = Getadc(2) 'Sensor 1 aktivieren
Config Pina.2 = Input 'Port als Input
Porta.2 = 1 'Port hoch setzen


Portc.7 = 1 'Motor 1 Vorwärts
Portb.1 = 1 'Motor 2 Vorwärts

Do 'Endlosschleife
If Getadc(2) < 1010 Then 'Wenn Port runter gesetzt wird (Low)


Portc.6 = 1 'Motor 1 Rückwärts
Portc.7 = 0

Portb.0 = 1 'Motor 2 Rückwärts
Portb.1 = 0

Print "Hindernis, setze zurueck!"

Waitms 100

'Rechtsdrehung
Portc.7 = 1 'Motor 1 Vorwärts
Portc.6 = 0

Waitms 50

'Geradeaus
Portb.1 = 1 'Motor 2 Vorwärts
Portb.0 = 0


Print "Setze Fahrt fort!"

End If
Loop

End Sub