Hallo, ich arbeite gerade an einem kleinen Projekt mit dem ATMega8 und brauche dringend Hilfe mit der Programmierung in C++. Ich habe bisher nur wenig Erfahrungen mit der µC-Welt an sich, aber auch mit der C++ Programmierung. Für das Programmieren benutze ich das Programm "SiSy" (myAVR), welches jede menge vorgefertigte Klassen bereitstellt. Diese vereinfachen das Programmieren ungemein, aber ich stoße damit gerade an Grenzen. (vor allem deshalb, weil die Beschreibungen in der Hilfe leider nur sehr dürftig ausfallen) Für die Programmierung mit C findet man zwar ein haufen Beispiele, allerdings kann ich diese anscheinend nicht korrekt auf C++ übertragen... Zum Problem: Der µC soll von mittels dem ADC die Spannungswerte von zwei Potentiometern ermitteln (zwei Kanäle). (Danach sollen die gemessenen Werte entsprechend interpretiert und an irgendeinem Port ausgegeben werden.) -> Kann mir jemand vielleicht ein einfaches Codebeispiel zum Konfigurieren der entsprechenden Register (ADCSRA, ADMUX) und Auswerten eines Messwertes für eine kontinuierliche Messung (Referenzsp. AVCC) zeigen? (MUSS dabei mit Interupts gearbeitet werden?) -> Oder kennt sich jemand mit der Verwendung der Klasse "AdcMultiChannel" im Programm "SiSy" aus? Vielen schonmal! Chris
:
Verschoben durch User
Chris K. schrieb: > Für die Programmierung mit C findet man zwar ein haufen Beispiele, > allerdings kann ich diese anscheinend nicht korrekt auf C++ > übertragen... die kannst du 1:1 übernehmen. Du musst überhaupt nichts umwandeln.
>an irgendeinem Port ausgegeben werden. Willst du die Byte´s Parallel ausgeben?? weil ein PORT PIN kann nur 0V oder 5V. Ausser der Beispiele im Netz nimm noch Datenblatt zu rate, erhlich gesagt der Atmega8 ist mist, da weder DebugWire noch JTAG um das ding mit JTAGICE oder DRAGON anzuhalten bzw. debuggen ;-)))
Ich empfehle auch dir AVR Studio 6.2 ohne vorgefertigtem scheiß zu nehmen und damit sich ruhig an dein Problem rantasten, und besorg dir ein JTAGICE3 und Atmega168 oder 328 für diese Problemstellung. ;-)))
jetzt übertreibt mal nicht. Wie habe es nur die Leute geschafft ohne Debuggen die alten µC zu programmieren? Für etwas ADC auslesen reicht das Datenblatt, spätestens nach den 3. Versucht läuft der Code. So mal man auch den Simulator hat.
machst du es mit der UML oder dem kleinen Programm? Gruß J.
hier mal die Variante im kleinen Programm
1 | class Application : public Controller |
2 | {
|
3 | // Bausteine und Attribute .........................................
|
4 | protected: AdcMultiChannel analog; |
5 | protected: Uart console; |
6 | // Funktionen ......................................................
|
7 | public: void onStart() |
8 | {
|
9 | // hier Initialisierungen durchführen
|
10 | |
11 | console.config(9600); |
12 | analog.config(); // Basiskonfiguration |
13 | analog.addChannel(0); // Chanel hinzufügen |
14 | analog.addChannel(1); |
15 | analog.configInt(enable); // Abholen und zwischenspeichern der Werte starten |
16 | }
|
17 | public: void onWork() |
18 | {
|
19 | uint8_t wert1,wert2; |
20 | wert1=analog.getValue8(0); |
21 | wert2=analog.getValue8(1); |
22 | console.sendByte(wert1); |
23 | console.sendByte(wert2); |
24 | waitMs(10); |
25 | |
26 | }
|
27 | } app; |
Peter II schrieb: > die kannst du 1:1 übernehmen. Du musst überhaupt nichts umwandeln. Oh, danke für den Hinweis! Mir war so, als wenn Ausdrücke wie z.B.
1 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); |
nicht funktionieren würden. Hab ich anscheinend aber noch nie ausprobiert.. ;-) Wie ist diese Beispielzeile überhaupt zu verstehen? Ich interpretiere es so: "Es wird eine '1' an die entsprechende Stelle im ADCSRA-Register 'geschoben'". Stimmt das? Was bezweckt das '|' (ODER) zwischen den Ausdrücken?
fortgeschrittener schrieb: > Willst du die Byte´s Parallel ausgeben?? weil ein PORT PIN kann nur 0V > oder 5V. Ich meine einen PORT, keinen PIN!
Das Codebeispiel hat mir erstmal sehr geholfen! Die Beschreibung in der Hilfe taugt einfach nichts.
Chris K. schrieb: > Wie ist diese Beispielzeile überhaupt zu verstehen? Ich interpretiere es > so: "Es wird eine '1' an die entsprechende Stelle im ADCSRA-Register > 'geschoben'". Stimmt das? Was bezweckt das '|' (ODER) zwischen den > Ausdrücken? Die Frage meinst du ernst? Das sind eigentlich Grundlagen C. OK, links neben dem Oder steht da "schiebe eine 1 um eine Stelle nach links" (ADPS1 hat den Wert 1, siehe auch avr/io.h), rechts vom Oder steht "schiebe eine 1 um null Stellen nach links" (ADPS0 hat den Wert 0). Man könnten also auch schreiben:
1 | ADCSRA = (1<<1) | (1<<0); |
Dröseln wir die Schiebeoperationen auf steht da:
1 | ADCSRA = 0b10 | 0b01; |
Und jetzt noch das Oder auflösen:
1 | ADCSRA = 0b11; |
Also eigentlich ganz einfach. Man schreibt halt nur
1 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); |
damit man auch nach 8 Monaten noch weiß warum man ADCSRA den Wert 3 zugewiesen hat falls man noch mal in den Quellcode rein schaut. ;)
Schiebeoperationen sind mir nicht unbekannt, allerdings nur so:
1 | test = test >> 3; |
Du meinst also, dass die Werte von ADPS0, ADPS1,... einen voreingestellten Wert haben, der in der h-Datei "hinterlegt" ist?! Ich arbeite bisher wie gesagt ohne die manuelle Einbindung von Dateien usw., verzeih mir also, dass ich mit den Ausdrücken nicht zurechtgekommen bin ;-) Die Sache mit dem ODER hätte ich eigentlich selbst erkennen müssen...
Chris K. schrieb: > Schiebeoperationen sind mir nicht unbekannt, allerdings nur so: >
1 | test = test >> 3; |
Wobei das, wenn es sich bei 'test' um etwas handelt, was logischweise eine Zahl darstellt, wie zb die Anzahl an Gummibärchen, besser als
1 | uint16_t AnzahlGummibärchen; |
2 | |
3 | AnzahlGummibärchen = AnzahlGummibärchen / 8; |
4 | // oder
|
5 | AnzahlGummibärchen /= 8; |
geschrieben wird. COmpiler sind nicht doof. Wenn eine derartige Division durch eine Schiebeoperation ersetzt werden kann, dann macht das der Compiler schon. > Du meinst also, dass die Werte von ADPS0, ADPS1,... einen > voreingestellten Wert haben, der in der h-Datei "hinterlegt" ist?! Was soll das heißen "Du meinst"? Das ist so! Genau das ist der Zweck von
1 | #include <avr/io.h> |
dass es für jeden im Datenblatt vorkommenden Registernamen, jeden im Datenblatt vorkommenden Bitnamen ein entsprechendes #define gibt, damit man sich eben nicht mit so Banalotäten wie Bitnummern rumschlagen muss. Das einzige was nicht abgedeckt ist, ist das man einen Bitnamen auf ein falsches Register anwenden kann. Nichts und niemand hindert einen
1 | ADCSR |= ( 1 << TOIE0 ); |
zu schreiben, obwohl das Overflow Interrupt Enable Bit nicht im Register ADCSR beheimatet ist. D.h. durch die Verwendung von Register bzw. Bitnamen wird einem zwar das mitdenken nicht abgenommen, aber es ist zumindest insofern einfacher, dass man nicht erst mal in
1 | ADCSRA |= 0x56; |
erst mal langatmig anhand der Bits aufdröseln muss, welche Bits da gesetzt werden und wie die heissen, damit man dann im Datenblatt die Beschreibung für diese Bits lesen kann.
Chris K. schrieb: > Du meinst also, dass die Werte von ADPS0, ADPS1,... einen > voreingestellten Wert haben, der in der h-Datei "hinterlegt" ist?! Ja, das sind Makros die in der avr/io.h definiert sind bzw. sein sollten.
Uwe S. schrieb: > Sorry Michael, > > ADPS0, ADPS1 sind keine Makros ! Ja OK, ich mach zwischen Makros und symbolischen Konstanten keinen Unterschied, ist irgendwie doch das Selbe. In beiden Fällen wird im Source-Code was ersetzt. Aber du hast recht, es sind keine Makros sondern symbolische Konstanten.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.