PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funktioniert mein (erster) Code?



Robs0412
29.07.2006, 06:43
Hallo BASCOM User,

ich als absoluter Einsteiger habe eine Frage zu einem meiner ersten Codes.
Diese habe ich schon mal im www.mikrocontroller.de (http://www.mikrocontroller.net/forum/read-1-388117.html) Forum gepostet wollte mir aber auch noch einmal hier Rat holen.

Kurze Story:

Bin KFZ Student und für eine Studienarbeit (Benzineinspritzung) will ich ein einfaches Steuergerät „bauen“.
Dazu habe ich mir als einfachen Bausatz das myAVR Board besorgt, mit einem ATmega88.
Des Weiteren nutze ich BASCOM 1.11.8.3 Demo, da mir Basic als Newbie am verständlichsten ist.

Habe jetzt leider noch nichts mit meinem Board testen können, da mir immer noch die Kabel zum PC fehlen (an was man eben nicht alles denkt…)

Dennoch war ich in BASCOM schon aktiv und habe den Simulator zum Testen genutzt und mir auch schon mein Programmablauf zusammengestrickt.

Jetzt meine Bitte an euch: könntet Ihr bitte mal drüber schauen und sagen, ob das so funktioniert bzw. ob vielleicht „was fehlt“.

Hier mein Code:


$regfile = "m88def.dat"
$crystal = 8000000


Config Timer1 = Timer , Prescale = 8 , Compare A = Clear 'Timer1 konfigurieren und aller 8 µC Takte einen hochzählen, aktiver Compare um EV auszuschalten


Enable Interrupts 'generell Interrupts zulassen
Enable Int0 'schalte den Interrupt ein
Config Int0 = Change 'Konfiguriere Interrupt, immer bei sich ändernder Flanke auslösen
On Int0 Zuendimpuls 'verzweige bei Int0 zu Zuendimpuls


Config Adc = Free , Prescaler = Auto , Reference = Avcc 'konfigurieren des ADC; Referenzspannung ist AVCC
Start Adc 'starten des ADC


Dim Wandler As Word 'Wandler Wert vom ADC (0 - 1023)
Dim C As Single 'Comparewert
Dim T As Integer 'T als Timerwert für Drehzahlberechnung


Ddrb.1 = 1 ' Port B1 (Compare OC1A) auf Ausgang
Portb.1 = 0 ' Port B1 (Compare OC1A) auf 0 (aus)



Hauptprogramm: 'Berechnungen


Do

Wandler = Getadc(0) 'ADC auslesen PC0

C = 0.00000000000000131974135394725 * Wandler 'verschiedene Berechnungen um neuen Comparewert zu berechnen
C = C - 0.00000000000304531013708812
C = C * Wandler
C = C + 0.00000000293446297432095
C = C * Wandler
C = C - 0.0000013743960103502
C = C * Wandler
C = C + 0.000377268967063757
C = C * Wandler
C = C - 0.0404534637863069
C = C * Wandler
C = C + 0.0474943050494277


C = T * C
C = C * 0.00000007160759


C = 500000 * C

Loop

End



Zuendimpuls:


T = Timer1 'Timerwert zwischenspeichern

Portb.1 = 1 ' Port B1 (Compare OC1A) auf 1 (an), solange, bis compare ihn ausschaltet

Compare1a = C 'neuen Comparewert laden, um nach bestimmter Zeit EV wieder zu schließen

Timer1 = 0


Return


Zusammenfassung:

Immer, wenn ein Zündimpuls erkannt wird, soll Port B1 aktiviert werden (5V) und solange anbleiben, wie zwischendurch in der Hauptschleife berechnet wurde (Wert für Compare).
Port B1 soll dann mit Compare wieder ausgeschalten werden.


Meine Frage, die ich jetzt noch habe:

1) Würde mein Programm so funktionieren?
2) Welche Taktfrequenzen kann der 88er intern erzeugen (wollte für Berechnungen schneller als 3,6 MHz sein)
3) Laut anderem Forum muss ich den ADC Kanal (0) vorher noch als Eingang definieren ohne Pull up; wäre dieser Code richtig? :

Ddrc.0=0
Portc.0=0

4) Muss ich Int0 auch noch als Eingang definieren?
5) Was mach ich mit den restlichen Ports? In einen definierten Zustand bringen?
6) Im Simulator schaltet sich die LED für den Port B1 nicht an und aus, wie gedacht, liegts am Code oder funzt dies nicht im Simulator


Vielen Dank und viele Grüße!

Robert :-)

Ruppi
29.07.2006, 07:34
Hallo!
Du hast in deinem programm sehr viele berechnungen mit fließkommazahlen, das macht den code sehr langsam! oftmals lässt sich für schwierige berechnungen eine geeignete approximation finden, um die berechnung zu vereinfachen. im simulator kannst du unten die zeit sehen (bzw in zyklen umrechnen), die das programm für die abarbeitung braucht. zu deinen fragen:
1) es würde so nicht funktionieren, portb.1 wird im timer-interrupt ein- aber nie wieder ausgeschaltet.
2) der 88er ist fast baugleich wie der atmega8. bei dem weiß ich, dass er intern schon 8MHz erzeugen kann, also auch ohne externen quartz. der 88er wird das sicher auch können.
3) stimmt nicht. wenn du config adc... schreibst, sind automatisch ALLE adc-pins des controllers als eingänge geschaltet.
4) nein, die deklaration als config int0 reicht aus, um pind.2 als eingang zu deklarieren
5) wenn du die restlichen ports nicht brauchst, lass sie einfach weg und kümmer dich nicht um sie
6) wird im simulator auch der timer-interrupt ausgeführt? eigentlich sollte die led zumindest angehen!

nochwas zur ansteuerung. bei einem zündimpuls würde ich nicht den flankenwechsel mit change prüfen. eher würde ich auf die steigende flanke des impulses warten, so würde die dauer des impulses keine rolle spielen, was ja sicher so sein soll. da hast du dir eine interessante sache vorgenommen, ich hoffe, du berichtest über deine fortschritte in dieser sache! der kommentar, der an deiner timer-deklaration steht, stimmt auch nicht ganz: wenn du eine vorteilung von 8 verwendest und ein 8mhz takt hast, ist das genau eine µs, der timer könnte also mit frequenzen zwischen 15Hz und 1MHz zum überlauf gebracht werden.


so, ich hoffe, ich konnte dir zumindest etwas weiterhelfen. wenn nicht, immer fleißig fragen!

guten gelingen, ruppi

Robs0412
29.07.2006, 11:16
Hallo,

danke erstmal für die schnelle erste Antwort!

Mal noch zur näheren Erläuterung meiner Studienarbeit (an der FH Zwickau, wen´s interessiert):

Wie schon geschrieben möchte ich eine einfache Einspritzanlage konzipieren. Das ganze soll dann mal in einem Trabant auf Funktion getestet werden.
Das ganze System ist insoweit recht einfach, da man als Minimum für die Anlage nur die Luftmasse, die der Motor gerade ansaugt, und die Drehzahl (Zündimpulsabstand) braucht.

Das Signal von einem Luftmassenmesser hole ich mir über ADC(0) rein und führe dann meine nötigen Berechnungen zur Ermittlung der Einspritzzeitdauer im Hauptprogramm durch.

Die vielen Fließkommazahlen ergeben sich durch die Kennlinie meines Luftmassenmessers. Diesen habe ich am Prüftsand mit einem Labormessgerät abgeglichen und die Werte im Excel mit einem Regressionpolynom 6. Grades zusammengefasst (der Genauigkeit wegen).

In meiner Berechnung wird dann ein aktueller Comparewert ermittelt, der dann bei einem Zündimpuls eingesetzt wird (Compare1a = C).

Bei 8 MHz Takt würde ich für die Berechnungen laut Simulator nicht mal eine ms benötigen.
Zeit spielt bis jetzt auch noch keine Rolle, da ich zwischen 2 Zündimpulsen >6ms habe (bei 4500 1/min, 2 Zündimpulse je Umdrehung)

jetzt zu meinen Fragen:

zu 1)

verstehe ich nicht ganz; habe doch Timer1 so konfiguriert:

Config Timer1 = Timer , Prescale = 8 , Compare A = Clear

ich dachte compare = clear bedeutet, dass bei Erreichen des Comparewertes der Port OC1A ausgeschaltet wird, oder?


2) bis 5) geht klar


zu 6)

habe folgenden Code einfach mal probiert:


$regfile = "m88def.dat"
$crystal = 8000000

Config Timer1 = Timer , Prescale = 1

Enable Interrupts
Enable Timer1

On Timer1 Zeit

Hauptprogramm:

Do

Print Timer1

Loop

End


Zeit:


Ddrb.1 = 1
Portb.1 = 1

Print "test"

Return

Simulator springt in die Interruptschleife und bringt mir "test", LED bleibt aber aus, andere Ports gehn auch nicht...?


Nochmal zu Prescale: wenn ich 8 MHz und Prescale 8 habe zählt er alle 1 µs einen hoch, genau; ich hatte mir notiert, dass aller 8 Takte eins hochgezählt wird, sind dann ja auch 1 µs

Wegen der Zündung:

Beim Trabant 2 Takter wird die Zündung über einen Hall-Sensor gesteuert. Eine halbe Umdrehung 0V, andere halbe Umdrehung +10....11V am Signalkabel gegen Masse; bei jedem Wechsel gibts dann einen Zündfunken.
Diese Sprünge möchte ich nun für meine Einspritzung abgreifen, so dass mir "change" am einfachsten erschien.

Hoffe ich konnte euch meine Idee ein wenig näher bringen und meinen Code verständlich machen, in der Hoffnung, dass wir ihn zum laufen bekommen.

Also, alle Meinungen bitte posten

Danke!

Robert :-)

Robs0412
31.07.2006, 06:54
Hallo,

habe jetzt mit meinem Board herausgefunden, dass man, wenn compare = clear den Port ausgeschaltet hat, ihn mit portb.1=1 nicht wieder an bekommt.

Wie kann ich dann diesen Compare wieder zurücksetzen, so dass ich den Port wieder schalten kann?

Toggle möchte ich nicht nutzen, da ich sicher gehen will, dass später mal das Einspritzventil auch wirklich zu ist...

Grüße

Robert :-)

Olle_Filzlaus
31.07.2006, 09:06
Tach auch,

1) erstmal herzlich willkommen in Forum.
2) hättest du dich hier nicht eher anmelden können, war auch an der fh-zwickau und habe nie jemanden gefunden der mit sowas bastelt.

3) Atmega8 und interne 8MHz, das wäre mir neu. intern macht der nur 1MHz. habe kürzlich erst neue bestellt und die zeigen auch nur intern 1MHz. also ohne externen quarz geht es nicht.

cu arno

Jahn Kohlhas
31.07.2006, 09:47
Hallo nach Zwickau,

doch der ATmega8 hat intern 1, 2, 4 und 8 MHz. das muss man über die Fusebits umschalten. Das geht jetzt ganz gut mit dem neuen Workpad:

http://www.myavr.de/download/myAVR_WorkpadPLUS_Demo.exe

Schaut unter Extras, Fuse- und Lockbits!

Gruß Jahn

Hanni
31.07.2006, 15:05
3) Atmega8 und interne 8MHz, das wäre mir neu. intern macht der nur 1MHz. habe kürzlich erst neue bestellt und die zeigen auch nur intern 1MHz. also ohne externen quarz geht es nicht.


Sicherlich nicht.
Ein Blick ins Datenblatt (http://atmel.com/dyn/products/datasheets.asp?family_id=607#760) würde Klarheit schaffen !!

Robs0412
01.08.2006, 06:12
Hallo,

werde das Workpad gleich mal testen...

habe in der Zwischenzeit mit meinem myAVR Board verschiedenes getestet. Bekomm sogar ein Lauflicht hin *freu* ;-)

Könnt Ihr mir noch bei meiner Frage helfen?

Grüße

Robert