Hallo,
ich möchte gern Atmel-Controller (myAVR) in der Schule einsetzen und
hatte dazu einen Lehrgang besucht, in dem mit E-Lab AVRco (Pascal)
programmiert wurde.
Nun gefällt mir Pascal nicht sonderlich und ich würde gern in C/C++
programmieren, auch weil es da mehr Hilfe und mehr Beispiele gibt.
Soweit so gut, einige Testprogramme aus Pascal konnte ich bereits in C
nachvollziehen, aber an einer Sache beiße ich mir gerade die Zähne aus.
In AVRco kann man einfach einem Port eine Variable zuweisen und diese
Variable 1 oder 0 setzen:
var ledrt[@PortB,0]:bit; //Variable für rote LED an Port B0, Typ bit
var ledge[@PortB,1]:bit;
...
ledrt:=1;
ledge:=0;
mdelay(300);
ledrt:=0;
ledge:=1;
mdelay(300);
In Entwicklungsumgebungen, die auf avr-gcc beruhen, habe ich keine
solche Möglichkeit gefunden. Ich kann zwar der Portnummer eine Variable
zuordnen, die Zuweisung des Status an/aus ist aber dann wesentlich
kryptischer:
#define ledrt PORTB0
#define ledge PORTB1
...
PORTB |= (1<<ledrt);
PORTB &= ~(1<<ledge);
_delay_ms(300);
PORTB |= (1<<ledge);
PORTB &= ~(1<<ledrt);
_delay_ms(300);
Der Pascal-Code ist deutlich anschaulicher, auch wenn man an dem
C-Beispiel gleich die Boolesche Algebra erklären kann.
Gibt es eine Pascal-ähnliche Syntax in C/C++?
Vielen Dank schon mal!
Jürgen
Jürgen schrieb:> solche Möglichkeit gefunden. Ich kann zwar der Portnummer eine Variable> zuordnen, die Zuweisung des Status an/aus ist aber dann wesentlich> kryptischer:>> #define ledrt PORTB0> #define ledge PORTB1> ...> PORTB |= (1<<ledrt);> PORTB &= ~(1<<ledge);> _delay_ms(300);> PORTB |= (1<<ledge);> PORTB &= ~(1<<ledrt);> _delay_ms(300);
Gewöhn dich daran.
> Gibt es eine Pascal-ähnliche Syntax in C/C++?
Wie gut sind deine C-Kentnisse?
Klar kann man. Nur eben nicht 'out of the box'. Aber für einen C-Kenner
ist das kein Problem.
Nur um mal die einfchste Variante zu zeigen
1
#define SET_BIT(p,b) (p) |= (1<<(b))
2
#define CLR_BIT(p,b) (p) &= ~(1<<(b))
3
4
#define ERROR_LED_PORT PORTB
5
#define RED_LED PB0
6
#define YELLOW_LED PB1
7
...
8
9
10
intmain()
11
{
12
...
13
14
15
SET_BIT(ERROR_LED_PORT,RED_LED);
16
CLR_BIT(ERROR_LED_PORT,YELLOW_LED);
17
18
...
19
}
Oder, das ganze noch eine Klkeinigkeit weiter getrieben
oder man kann sich dafür Funktionen schreiben. Oder ....
Und man kann natürlich, wenn man es kann, sich auch etwas zurecht legen,
so dass man schreiben kann
1
intmain()
2
{
3
4
ErrorPort.RedLed=ON;
5
6
...
Hängt alles nur davon ab, wie gut dein C ist.
Aber: Da jeder eine andere Vorstellung davon hat, wie sowas aussehen
sollte, gibt es da kaum Standard-Verfahren, bzw. man landet auf
unterster Stufe immer wieder beim
PORTB |= ( 1 << PB0 );
das ist nun mal das universellste und alles weitere leitet sich davon
ab. PS: Was machst du, wenn du wirklich mehrere Portpins auf einmal auf
1 setzen willst? In C schreibst du
PORTB |= ( 1 << PB0 ) | ( 1 << PB1 );
bzw. mit entsprechendem Makro-Ersatz dann eben auch mit sprechenderen
Namen. Aber: es geht. Du kannst in einem Aufwasch mehrere Portpins auf
einmal schalten.
Jürgen schrieb:> Gibt es eine Pascal-ähnliche Syntax in C/C++?
Über Bitfelder (eher was für Fortgeschrittene)
Beitrag "Re: "Syntaxbefehl" erstellen" oder
Präprozessormakros
#define AN(p,v) (p|=(1<<v))
#define AUS(p,v) (p&=~(1<<v))
und das Spiel kann man dann weiter treiben
#define PORTLED PORTB
#define LED1 3
#define LED1_AN AN(PORTLED,LED1)
usw.
Und Ach ja.
Die Schwierigkeit bei Programmen aus der realen Welt besteht ja darin
die Logik hinzukriegen und nicht welche Syntax man jetzt benutzt um
einen Portpin auf 0 oder auf 1 zu schalten. In der Praxis sehen die
wenigsten Programme nun mal so aus
1
intmain()
2
{
3
DDRB|=(1<<PB0)|(1<<PB1);
4
5
while(1){
6
7
PORTB|=(1<<PB0);
8
PORTB&=~(1<<PB1);
9
_delay_ms(1000);
10
11
PORTB&=~(1<<PB0);
12
PORTB|=(1<<PB1);
13
_delay_ms(1000);
14
}
15
}
Sowas ist ja die Ausnahme. Reale Programme haben einen wesentlich
höheren Logikanteil, so dass die paar Portzuweisungen kaum ins Gewicht
fallen. Und wenns einen stört, dann versteckt man die eben hinter
Makros.
Also Bitfelder finde ich gar nicht sooo schwierig besonders wenn die
schon vordefiniert sind ;-) mit einem myAVR hast doch schon sowas schau
mal hier: http://www.avr-cpp.de das sieht dann in etwa so aus:
Jürgen schrieb:> die Zuweisung des Status an/aus ist aber dann wesentlich> kryptischer:
Nö, muß man nicht.
Es geht auch ähnlich einfach, wie unter Pascal:
Danke für den Tip mit sbit.h - das ist genau was ich will und dazu (so
hoffe ich) auch frei.
1
#include <avr\io.h>
2
#include <avr\sbit.h>
3
#define Taster PIN_D2
4
#define LED PORT_D5
5
6
int main(void)
7
{
8
PORT_D2 = 1; // Pull-Up-Widerstand
9
DDR_D5 = 1; // Ausgang setzen
10
11
while(1)
12
{
13
if(Taster)
14
LED = 1;
15
else
16
LED = 0;
17
}
18
}
SiSy (http://sisy.de) gefällt mir zwar noch besser (objektorientiert),
kostet aber als Schulversion 49 EUR je Arbeitsplatz und zeigte unter Win
7 Probleme bei normalen Benutzerrechten.
Jürgen
> #include <avr\io.h>
Besser:
#include <avr/io.h>
da portabler.
Noch besser:
#include <io.h>
und den Includepfad per Compileroption auf .../avr
setzen.
iab schrieb:> Noch besser:> #include <io.h>>> und den Includepfad per Compileroption auf .../avr> setzen.
Warum sollte das noch besser sein? Das einzige, was du damit erreichst,
ist, daß sich deinen Programme auf keiner anderen
avr-gcc-Standardinstallation ohne Anpassungen compilieren lassen.
1
#include<avr/io.h>
ist Standard, und dabei solte man auch bleiben.
Oliver
Hallo,
ich halte die GCC-Standard-Installation nicht unbedingt für den Stein
der Weisen und das oberste Ende der Entwicklung. Der GCC ist eher eine
Basis von der aus man ausgehen kann und etwas auf seine Bedürfnisse
zuschneiden oder weiterentwickeln kann. Das Sieht man deutlich bei den
kommerziellen oder herstellerspezifischen Umgebungen. Es taucht hier
immer wieder das Bedürfnis ich nenne es mal "moderneren"
Sprachkonstrukten als Shift-Opreationen zu benutzen. Solche Angebote
wie:
http://www.luna.dehttp://www.avr-cpp.dehttp://sourceforge.net/projects/veavrcclasslibr/http://www.mySTM32.de
usw. usw.
kann man nicht einfach wegbügeln mit "das ist kein GCC-Standard deswegen
mach das nicht" besser ist es darüber konstruktiv zu diskutieren. So das
musste mal raus ;-)
Also ich find es absolut OK wenn er sich seine IDE verbiegt :-D er
erkundet wie es besser gehen kann und lernt und wir lernen mit ihm
Gruß J.
Julius schrieb:> Es taucht hier> immer wieder das Bedürfnis ich nenne es mal "moderneren"> Sprachkonstrukten als Shift-Opreationen zu benutzen.
Klar kann man sich für Port-IO elegantere Lösungen denken, als das
Standard-C-Bitgeschubse, aber:
Ich sach mal so: In jeder ernsthaften Anwendung, die über das erste
Testprogramm "LED-Blinken" hinausgeht, machen die Port-IO-Operationen
weniger als 0,00x% des gesamten Codes aus. Wer da schon an den
Bitoperationen scheitert, kriegt den Rest eh nicht hin.
Und die, die den Rest hinkriegen, die störten die paar Zeilen nicht.
Das es mit Arduino, Luna, Bascom, et. al. alternative toolchains mit
Vor- und Nachteilen gegenüber einem avr-gcc mit avrlibc gibt, ist prima.
So hat jeder die freie Wahl.
Vorhandene libs der Struturen auf Sourccde-Ebene zu erweitern, ist eine
geute Sache. IDEs verbiegen ohne sinnvollen Grund zu verbiegen ist
dagegen keine gute Idee. Spätestens mit dem nächste Update läuft man
damit voll in die Schxxxe.
Oliver
Julius schrieb:> ich halte die GCC-Standard-Installation nicht unbedingt für den Stein> der Weisen und das oberste Ende der Entwicklung.
Das bedeutet aber nicht, dass man es deshalb zwanghaft anders machen
muss. Ich finde ein avr/io.h auch besser als nur io.h. Das ist ähnlich
wie in C++ mit Namespaces. Man verteilt die Header auf verschiedene
Verzeichnisse, abhängig davon, für welchen Bereich von Funktionalität
sie verwendet werden. Und man läuft nicht Gefahr, dass sich jemand ein
eigenes io.h definiert hat, das dann damit kollidiert.
Das ist etwas, das sehr viele Bibliotheken so machen. Was findest du
daran schlecht?
> kann man nicht einfach wegbügeln mit "das ist kein GCC-Standard deswegen> mach das nicht" besser ist es darüber konstruktiv zu diskutieren. So das> musste mal raus ;-)
Es geht nicht um GCC selbst, sondern eher um die avr-libc. Und ich kann
umgekehrt auch sagen, nur weil die von dir genannten Projekte es
irgendwie anders machen, heißt das nicht, dass das der Stein der Weisen
ist und man bei der Benutzung von avr-libc die avr-libc-Gepflogenheiten
verwerfen sollte.
> Also ich find es absolut OK wenn er sich seine IDE verbiegt :-D er> erkundet wie es besser gehen kann und lernt und wir lernen mit ihm
Wie schon gesagt wurde: Was du vorschlägst, ist nicht besser. Es hat
keinerlei Vorteil, außer dass man 4 Zeichen weniger tippen muss.
Und wenn man etwas "verbiegen" muss, weil man es anders machen will als
alle anderen, dann ist das zwar nicht immer, aber doch meistens ein
Zeichen dafür, dass man was falsch macht.