Hallo zusammen!
Erst mal vorweg, ich bin seit fast 10 Jahren nicht mehr mit C in
Berührung gekommen, dafür aber viel ABAP und C#.
Ich habe am Wochenende fleißig Datenblätter gewälzt und hier im Forum
gestöbert, und einen ersten Entwurf für mein Programm erstellt.
Und zwar will ich einen Lenkradfernbedienungs-Interface für mein Auto
bauen, fertig gibts sowas leider für mein Modell nicht.
Der Aufbau ist folgendermaßen:
An Pin PB3 kommt der Eingang von der LFB, eine Widerstandsleiter mit
Tastern. Den genauen Wert für R2 kann ich erst berechnen, wenn ich die
einzelnen Werte für die Tasten ausgemessen habe.
An Pin PB4 kommt der Anschluss für mein Radio.
Die genauen Informationen über das nötige Protokoll für mein
Alpine-Radio hab ich von hier:
http://www.mp3car.com/vbulletin/input-devices/131147-need-alpine-wired-remote-control-pinout.html#post1314327
Leider habe ich noch keinen µC um das ganze mal zu testen, muss erst
noch die Teile bestellen.
Könnt ihr mal bitte drüberschauen, ob mein Code so einigermaßen stimmt?
Vor allem die Initialisierung der Register und des ADC und die Benutzung
des Interrupts.
Das Programm habe ich mit WinAVR im Programmer's Notepad erstellt.
Beim kompilieren erhalte ich ein paar Warnings bei folgenden Stellen:
Hier kommt "warning: assignment from incompatible pointer type", aber
ich verstehe nicht ganz warum...
Kommentare, Kritik und Verbesserungsvorschläge sehr erwünscht ;)
MfG
> Hier kommt "warning: assignment from incompatible pointer type", aber> ich verstehe nicht ganz warum...
data ist ein Pointer auf eine Datenstruktur, alp_datagram_vol_up
beinhaltet die Daten. Das passt nicht zusammen.
Wenn, dann muss es heißen:
data = &alp_datagram_vol_up;
Gruß,
Frank
Du hast natürlich recht.
Aber die Compilerwarnung bleibt leider die selbe...
Also sowohl bei
data = &alp_datagram_vol_up; (eigentlich richtig)
als auch bei
data = alp_datagram_vol_up; (falsch)
Am Anfang hatte ich es auch richtig, so wie du geschrieben hast.
Nur beim Testen woher die dusslige Warning kommt hab ich halt mal alle
falschen Möglichkeiten durchprobiert, um zu sehen was für Meldungen dann
ausgeworfen werden.
Und am Ende dann vergessen es wieder richtig zu schreiben, war schon
spät gestern...
MfG
Ja, bei beiden Varianten die gleiche Meldung.
Ich hab auch mal einen Screenshot angehängt...
Irgendwelche Ideen woher das kommen könnte?
Vielleicht eine Einstellung im Compiler...
Ich habe alles ohne weitere Anpassungen so verwendet, wie es installiert
wurde.
Das Makefile ist aus dem sample-Verzeichnis kopiert, dort habe ich nur
die Zeile
Moment mal, als was ist denn alp_datagram_data_t deklariert? Der
Initializer sieht so aus, als wäre das ein Array... Ein Array
wird durch einen Zeiger auf das erste Element weitergereicht, ich
vermute, du hast ein array of pointers draus gemacht.
Jörg Wunsch schrieb:
> Ein Array> wird durch einen Zeiger auf das erste Element weitergereicht, ich> vermute, du hast ein array of pointers draus gemacht.
Aah, jetzt hats "Klick" gemacht... Danke!
So muss es sein, oder?
1
alp_datagram_data_tdata;
2
*data=*alp_datagram_vol_up;
Und wie stehts mit dem Rest vom Programm?
Macht der auch wirklich das, was ich in den Kommentaren geschrieben
habe?
(Ja ich schreibe meine Comments immer in Englisch... ;) )
Funktioniert auch nicht.
Wenn data const ist, kann ich ja keinen Wert zuweisen.
Und wenn ich das const weglasse, bekomme ich
"warning: assignment discards qualifiers from pointer target type"
Vielleicht nochmal eine Beschreibung was ich machen will:
- Ich definiere mir ein paar globale konstante Variablen vom Typ
"alp_datagram_data_t" (ein bool-Array mit Länge 17).
- In der Funktion "send_to_hu()" hole ich mir anhand des übergebenen
Parameters per switch...case eine Referenz auf die richtige der vorher
oben definierten Variablen in meine lokale Variable "data".
Dann kommt eine For-Schleife über die Elemente (="Bits") von "data", und
die Werte werden entsprechend am Ausgang ausgegeben.
Unter C kann man keine beliebigen Bitbreiten definieren, es gibt nur
uint8_t, uint16_t und uint32_t, also keine 17 Bit usw.
Womöglich macht der Compiler sogar Deine Typen alles int, dann ist aber
ruchzuch Dein SRAM explodiert. Ein int je Bit ist zu teuer.
Versuch mal alles in Bytefelder umzusetzen, der AVR-GCC versteht sogar
Binärschreibweise.
Die vielen Switch-Case würde ich als Pointerarray vereinfachen.
Peter
Jörg Wunsch schrieb:
> Dann liefere mal so viel Programmtext, dass man das selbst compilieren> kann.
Gleich im Anfangspost habe ich doch den kompletten Quelltext des
Programms angehängt...
Was fehlt denn genau?
Peter Dannegger schrieb:
> Womöglich macht der Compiler sogar Deine Typen alles int, dann ist aber> ruchzuch Dein SRAM explodiert. Ein int je Bit ist zu teuer.>>> Versuch mal alles in Bytefelder umzusetzen, der AVR-GCC versteht sogar> Binärschreibweise.
Ja, leider wird bool intern wohl auf byte umgesetzt, der Daten-Speicher
war fast voll. Und bit fields wollte ich eigentlich vermeiden, wegen dem
fehlenden Index-Zugriff.
Aber dein Tipp mit der Binärschreibweise hat mich auf was gebracht:
Die ganzen bool[] habe ich durch UINT32_t ersetzt.
Als Wert haben sie jeweils die Element-Werte in umgekehrter Reihenfolge
in Binärschreibweise erhalten:
1
constalp_datagram_data_talp_datagram_vol_up={1,1,0,1,1,0,1,1,1,1,0,1,0,1,1,0,1};// alt
2
constuint32_talp_datagram_vol_up=0b10110101111011011ul;// neu
um nun auf die einzelnen Bits zugreifen zu können, habe ich mir eine
kleine Hilfsfunktion gebastelt:
1
boolget_bit(uint32_tdata,uint8_tindex)
2
{
3
// index may not be higher than 31 for 32 bit value
4
if(index>31)
5
returnfalse;
6
7
// extract the n-th bit by and-ing data with just one binary "1" in n-th bit
8
// then the result is shifted right by n places to get the bit we want
9
return((data&(1<<index))>>index);
10
}
Im Anhang liegt die neue Version sowie das Makefile dazu.
MfG
Wo und wie ist denn bool und false definiert?
Ich versuche, nicht standard Typen möglichst zu vermeiden.
Bezüglich analoge Tastenabfrage, das kann man beqem alles den Compiler
ausrechnen lassen:
Beitrag "Tastenmatrix auslesen über nur 2 Leitungen"
Peter
Peter Dannegger schrieb:
> Wo und wie ist denn bool und false definiert?
Das ist über #include <stdbool.h> definiert.
Peter Dannegger schrieb:
> Bezüglich analoge Tastenabfrage, das kann man beqem alles den Compiler> ausrechnen lassen:>> Beitrag "Tastenmatrix auslesen über nur 2 Leitungen"
Danke für den Tip!
Die Rechnerei überlass ich dann dem Compiler...
Sind sonst noch irgendwelche groben Schnitzer bei mir drin?
Vor allem: Machen meine Initialisierungen auch das, was sie laut
Kommentar bewirken sollen?
MfG
Stefan B. schrieb:
> Das ist über #include <stdbool.h> definiert.
Die findet der AVR-GCC aber nicht.
Auch die 2 weiteren Compiler auf meinem PC kennen sie nicht.
Peter
Seltsam, in meinem WinAVR ist das standardmäßig vorhanden, und zwar im
Verzeichnis
[WinAVR-Ordner]\lib\gcc\avr\4.3.3\include\stdbool.h
Hier der Inhalt (ohne Copyright-Hinweis):
1
#ifndef _STDBOOL_H
2
#define _STDBOOL_H
3
4
#ifndef __cplusplus
5
6
#define bool _Bool
7
#define true 1
8
#define false 0
9
10
#else /* __cplusplus */
11
12
/* Supporting <stdbool.h> in C++ is a GCC extension. */
13
#define _Bool bool
14
#define bool bool
15
#define false false
16
#define true true
17
18
#endif /* __cplusplus */
19
20
/* Signal that all the definitions are present. */
Stefan B. schrieb:
> [WinAVR-Ordner]\lib\gcc\avr\4.3.3\include\stdbool.h
Hätt ich mal doch die Windows-Suche benutzen sollen.
Ich hab nur unter ...\avr\include nachgesehen.
> #define false 0
Dann stellst sich die Frage, wie sich in der Funktion get_bit() false
von einem 0-Bit unterscheidet.
Peter
Kein Problem, ich hab zuerst auch nur da nachgeschaut.
Da hätten die doch auch ne info.txt mit reinpacken können, damit man
weiß wo der Rest ist...
Peter Dannegger schrieb:
> Dann stellst sich die Frage, wie sich in der Funktion get_bit() false> von einem 0-Bit unterscheidet.
Wenn du damit das
1
if(index>31)
2
returnfalse;
meinst, dann gar nichts.
Ist nur eine Angewohnheit, normalerweise programmiere ich ja C#.
Ich ändere es mal auf "return 0", damit es überall gleich aussieht...
Stefan B. schrieb:
> Da hätten die doch auch ne info.txt mit reinpacken können, damit man> weiß wo der Rest ist...
Es gibt einfach zwei Verzeichnisse, in denen der Compiler nach
Headerdateien nachsieht. Das eine gehört zum Compiler selbst und
wird von ihm verwaltet, die Dateien dort gehören zum GCC-Paket.
Das ist das, wo u. a. auch <stdbool.h> gefunden wird.
Das zweite Verzeichnis gehört zur avr-libc, wird von dieser verwaltet
und entsprechend installiert, wenn man die Bibliothek baut und
installiert.
Wenn man den Compiler mit -v aufruft, zeigt er einem an, wo er beim
Compilieren überall nach den Dateien sucht.
Das mit der info.txt war auch nur Spaß. ;)
Jörg Wunsch schrieb:
> Wenn man den Compiler mit -v aufruft, zeigt er einem an, wo er beim> Compilieren überall nach den Dateien sucht.
Danke für den Hinweis!
MfG
So, ich hab mein Programm noch etwas erweitert und (hoffentlich)
verbessert.
Der ADC-Eingang hat noch eine kleine Entprell-Routine in der ADC-ISR
spendiert bekommen, und die ganzen delay_ms und delay_us wurden durch
einen Timer ersetzt.
Ist das jetzt zumindest einigermaßen brauchbar?
MfG Stefan