Uidanke, das sind ne Menge Informationen mit denen ich was anfangen kann \
/
Gibts bei der ganzen Zusammenstellung etwas, was da unbedingt noch mit reingehört? Irgend eine Funktion / Methode?
- 4x Spannung messen -> Winkelbestimmung der Gelenke
initADC()
getADC()
setChannel()
- 1x Zustand messen -> Bodenkontakt
if (PINx &(1<<Pxn)) {}
- Routine Datenerfassung und Vergleich -> bestimmte Winkel und Zustand Bodenkontakt / Ist & soll
switch case oder verschachtelte if's
- Datenauswertung und Anzeige -> Anzeige über LCD
initLCD();
printLCD(char* text, unsigned char zeile);
clearLCD([unsigned char Zeile]); //Zeile nur optional
- Richtungsbestimmung bzw. Ausführung von Anweisungen -> Bewegungsabläufe
kommt drauf an wie du dich bewegst, aber bei servolenkung UND doppelantrieb brauchste wohl PWM also
initTimer() //altervnativ initSERVO()
initMotor()
setMotorDir() // wie im asuro ^^
setMotorSpeed()
- Verarbeitung von Ereignissen -> Kollision / nichterreichte Zustände
interruptservice-routinen
ISR oder SIGNAL
- allgemeine Spannungsüberwachung -> Betriebsspannung
das geht mit dem ADC
so als anregung für die zusammenstellung deiner methoden ^^
Uidanke, das sind ne Menge Informationen mit denen ich was anfangen kann \
/
Gibts bei der ganzen Zusammenstellung etwas, was da unbedingt noch mit reingehört? Irgend eine Funktion / Methode?
Noch ein Tipp:
Mit ein paar Makros kann man sich das schreiben des Programms sehr erleichtern und erhöht die Lesbarkeit des Codes ungemein.
Ich habe da vor allem diese vier:
So wird zum Beispiel aus der recht kryptischen Abfrage eines Eingangs auf PB4Code:#define SetBit(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT))) //!< Setzt ein bestimmtes Bit eines Registers #define ClrBit(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT))) //!< Löscht ein bestimmtes Bit eines Registers #define ToogleBit(ADDRESS,BIT) ((ADDRESS) ^= (1<<(BIT))) //!< Toogelt ein bestimmtes Bit eines Registers #define IsBitSet(ADDRESS,BIT) (((ADDRESS) & (1<<BIT))?1:0) //!< Fragt ein bestimmtes Bit eines Registers ab
if (PINB &(1<<PB4)) {}
ein recht einfaches
if (IsBitSet(PINB,4)) {}
und das ohne dass der Compiler einen anderen Code draus macht.
Gruß,
askazo
Hallo askazo
Das mit den defines hats mir schon länger angetan, find ich ne tolle Sache, hab bei meinen bisherigen Versuchen / Programmtests schon gern genau solch Tasterabfragen vordefiniert \/.
Was sollte man besser nicht definieren?
Ich benutze defines meistens zur Umdefinition von Zahlenwerten, z.B. für die Baudrate der UART (#define UART_BAUD_RATE 57600) oder für Berechnungen oder zur Zusammenfassung von Rechenoperationen (z.B #define UART_BAUD_SELECT (F_CPU/(USS_BAUD_RATE*16l)-1) )
Bei diesem Beispiel bräuchte ich z.B. zur Anpassung der Baudrate nur in der uart.h den Wert zu ändern und bin fertig.
Gelegentlich sind auch if-Abfragen auf Präprozessor-Ebene ganz nützlich. Beim ATMega128 habe ich z.B. zwei COM-Schnittstellen. Um meine uart.c für beide Schnittstellen benutzen zu können, habe ich mir folgenden Konstrukt gebastelt:
Um den Code auf die andere Schnittstellen anzupassen, brauche ich nur noch das Makro COM_PORT zu ändern.Code:#define COM_PORT 0 #if COM_PORT #define UDRX UDR1 #define UCSRXA UCSR1A #define UCSRXB UCSR1B #define UCSRXC UCSR1C #define UBRRXL UBRR1L #define UBRRXH UBRR1H #define SIG_UARTX_DATA SIG_UART1_DATA #define SIG_UARTX_RECV SIG_UART1_RECV #else #define UDRX UDR0 #define UCSRXA UCSR0A #define UCSRXB UCSR0B #define UCSRXC UCSR0C #define UBRRXL UBRR0L #define UBRRXH UBRR0H #define SIG_UARTX_DATA SIG_UART0_DATA #define SIG_UARTX_RECV SIG_UART0_RECV #endif
Man darf natürlich mit Makros nicht übertreiben. Komplexere Sachen gehören in eine Funktion. Und ganz tabu sind Sachen wie
Damit fängt man dann an, eine neue Programmiersprache zu basteln.Code:#define wenn if #define dann else
Generell würde ich keine Makros basteln, die Schlüsselwörter von C enthalten. Da kann man sich besser eine inline-Funktion basteln, wenn man einen kurzen Code hat, den man mehrmals aufrufen möchte.
Gruß,
askazo
Ok, das kann ich nachvollziehen \/
Bisher hab ich Pullups und PIN in define geschrieben, damit ich nur noch Wörter wie "Taster 1" oder "LED1" ecta. in Bedingungen / Schleifen schreiben brauche. Hatte den Vorteil, wenn ich den Port / Pin ändere, das dann in define anpasse. Das ist doch ok, oder?
Möglich, dass sich meine Frage mit einem größeren Programm beantwortet![]()
copious,
was mir bei deiner aufstellung noch fehlt, ist der programmfluß; wie spielen die dinge zusammen? das ist gerade bei uC-programmierung IMHO ganz wesentlich. wenn du von bewegungsabläufen sprichst, wirst du genaue zeitabläufe brauchen, damit kannst du entweder mit delays arbeiten:
damit kann dann aber während der delays nix mehr passieren, wenn zb ein hindernis auftritt, kann das erst nachher erkannt werden.Code:while(1) { start_bewegung(); _delay_ms(10.0); stop_bewegung(); read_sensors(); ... }
besser, aber auch komplizierter, ist sowas:
damit läuft dann alles andere weiter, während auf das ende der bewegung gewartet wird, und reaktionen auf zb hindernisse können schnell erfolgen. dafür ist die dauer nicht ganz so exakt wie beim ersten fall, weil das ablaufen des timers erst erkannt wird, wenn die endlosschleife wieder bei "timer_elapsed" vorbeikommt...Code:while(1) { if(ausloeser) { start_bewegung(); set_timer(1, 10); } if(timer_elapsed(1)) stop_bewegung(); read_sensors(); ... }
Ja, das kannst Du so machen. (Bis auf das Leerzeichen zwischen Taster und 1 - das geht nicht)
Die Namen von Makros sollte übrigens komplett in Großbuchstaben geschrieben werden, damit man sie direkt als Makros erkennen kann.
(Ausnahmen bestätigen die Regel, wie man bei meinen 4 defines weiter oben sieht - da würde sonst die Lesbarkeit ziemlich leiden. Ansonsten halte ich mich aber strikt dran.)
Die 2. Version find ich klasse, man meinte mal zu mir, dass if-Abfragen nur in bestimmten Fällen angewendet werden sollten, ließe sich gleiche Aufgabe mit Switch verwirklichen?
@askazo , das Leerzeichen ist bei mir immer ein Unterstrich, hab ich vergessen ^^
Bisher hab ich nur den ersten Buchstaben groß geschrieben, bringt das Probleme mit sich?
Lesezeichen