Programm für Fahrtsteller anpassen

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 29 11 2024  04:05:03      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte

Gehe zu Seite ( Vorherige Seite 1 | 2 )      


Autor
Programm für Fahrtsteller anpassen

    







BID = 841490

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus
 

  


Hatte gerade mal wieder etwas Zeit zum Programmieren und natürlich lässt das Erste Problem nicht lange auf sich warten.

Und zwar will ich nichts weiter, als eine einfache Variablenzuweisung für die Ausgangspins des µC. Für die Eingangspins funktioniert es schon mal

Seltsamerweise gibt es bei Google eine Vielzahl von Treffern, wenn man danach sucht, aber funktioniert hat nichts so recht.


Jetzt hoffe ich, dass ihr mir weiter helfen könnt. Hier der Quellcode.



Code :

#include <avr/io.h>

#include <avr/delay.h>

int main (void)
{

DDRB = 0xF0; //Bit7...4 Ausgänge, Bit3...0 Eingänge
PORTB = 0x00; //Alle PullUp-Widerstände aus

//Ein Taster steuert eine LED mit Variablenzuweisung an

do{

#define S1 (PINB&(1<<PINB3))
#define S2 (PINB&(1<<PINB2))
#define S3 (PINB&(1<<PINB1))
#define S4 (PINB&(1<<PINB0))
/* So (Zuweisung als Pseudocode) soll es mal aussehen
LED1 --> PB7
LED2 --> PB6
LED3 --> PB5
LED4 --> PB4

if(S1) LED1=1;
else LED1=0;
if(S2) LED2=1;
else LED2=0;
if(S3) LED3=1;
else LED3=0;
if(S4) LED4=1;
else LED4=0;
}
*/
//So sieht es bis jetzt aus, und funktioniert dafür wenigstens

if(S1) PORTB|=(1<<PB7);
else PORTB&=~(1<<PB7);
if(S2) PORTB|=(1<<PB6);
else PORTB&=~(1<<PB6);
if(S3) PORTB|=(1<<PB5);
else PORTB&=~(1<<PB5);
if(S4) PORTB|=(1<<PB4);
else PORTB&=~(1<<PB4);

}while(1);

return 1;
}



_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 841493

perl

Ehrenmitglied



Beiträge: 11110,1
Wohnort: Rheinbach

 

  


Zitat :
Alle PullUp-Widerstände aus
Warum?
Die sind doch recht praktisch und erlauben es die Schalter ohne weitere Bauteile nach Masse zu legen.


Zitat :
aber funktioniert hat nichts so recht.
Dann schau dir doch mal mit dem Simulator bzw. Disassembler den erzeugten Maschinencode an.
Du kannst ihn sogar im Einzelschritt untersuchen.
Auf diese Weise verstehst du die Arbeitsweise des Compilers und deine Fehler noch am besten.


BID = 841496

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus


Zitat :
erlauben es die Schalter ohne weitere Bauteile nach Masse zu legen.
Klar, ich wollte aber gegen VCC schalten. Daher wurden die internen Pullup-Widerstände deaktiviert und ein R-Netzwerk als Pulldown eingesetzt.


Zitat :
Auf diese Weise verstehst du die Arbeitsweise des Compilers und deine Fehler noch am besten.
Hilft mir leider nicht weiter.




_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 841498

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika


Zitat :

[...]
als eine einfache Variablenzuweisung für die Ausgangspins des µC.

Das kann ja nicht gehen, schließlich werden im Regelfall acht Bits an einer Adresse gemappt und können nur über die Adresse angesprochen werden (die Adresse ist bis auf wenige Ausnahmen im RAM gemappt und daher funktioniert sowas wie PORTD = 0xf5 auch erst. PORTB ist vom Typ (volatile uint8_t*).

Statt LED1 = 1 geht es aber so:

#define LED1 PORTB, PORTB5
#define LED2 PORTA, PORTA3

#define	setbit(IO) __setbit(IO)
#define	__setbit(PORT, BIT) PORT |= (1<<BIT)

#define	clearbit(IO) __clearbit(IO)
#define	__clearbit(PORT, BIT) PORT |= &= ~(1<<BIT)



Du kannst dann irgendwo im Programm schreiben:

if(Bedingung) setbit(LED1);
else clearbit(LED1);



Habe da noch andere Dinge geschrieben, die IO-Geschichten auf AVRs deutlich vereinfachen. Z.B. kann man auch sagen isoutput(LED1), dann wird im Prinzip das passende Bit im passenden DD-Register gesetzt.
Das ganze sind nur Makros, der Code wird zu sbi <PORT>, <BIT> assembliert, also optimal.

_________________


[ Diese Nachricht wurde geändert von: DonComi am  4 Aug 2012  0:16 ]

[ Diese Nachricht wurde geändert von: DonComi am  5 Aug 2012  0:11 ]

BID = 841583

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus

Danke Don, so etwas habe ich gesucht.

Leider funktioniert es aber nicht.
Die LEDs gehen sofort nach dem Programmieren an.
Ein Betätigen der Schalter bringt keine Veränderung.

Fehlt da evtl. ein "#include <hastenichgesehen>", um diese Funktionen zu verwenden?

So sieht der Quellcode bis jetzt aus:


Code :

#include <avr/io.h>

#include <avr/delay.h>

int main (void)
{

DDRB = 0xF0; //Bit7...4 Ausgänge, Bit3...0 Eingänge
PORTB = 0x00; //Alle PullUp-Widerstände aus

//Ein Taster steuert eine LED mit Variablenzuweisung an

do{

#define S1 (PINB&(1<<PINB3))
#define S2 (PINB&(1<<PINB2))
#define S3 (PINB&(1<<PINB1))
#define S4 (PINB&(1<<PINB0))

#define LED1 PORTB, PORTB7
#define LED2 PORTB, PORTB6
#define LED3 PORTB, PORTB5
#define LED4 PORTB, PORTB4

#define setbit(IO) __setbit(IO)
#define __setbit(PORT, BIT) PORT |= (1<<BIT)

#define clearbit(IO) __clearbit(IO)
#define __clearbit(PORT, BIT) PORT |= (1<<BIT)


if(S1) setbit(LED1);
else clearbit(LED1);
if(S2) setbit(LED2);
else clearbit(LED2);
if(S3) setbit(LED3);
else clearbit(LED3);
if(S4) setbit(LED4);
else clearbit(LED4);

}while(1);

return 1;
}




_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 841603

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Nein,

ich habe einen Fehler in clearbit().

Statt
#define	__clearbit(PORT, BIT) PORT |= (1<<BIT)

muss es natürlich
#define	__clearbit(PORT, BIT) PORT &= ~(1<<BIT)

sein.

Defines innerhalb von C-Code sind nicht schön,
packe am besten diese IO-Makros in einen separaten Header oder aber zumindest an den Anfang deines Programmes, macht einiges übersichtlicher.

Edit:
Zusätzliche Header sind für diese Makros nicht nötig.
Sie funktionieren prinzipiell auch mit Variablen, man könnte mit

register uint8_t val = 0x00;
setbit(val, 5);

Auch das fünfte Bit in einem Register (wie hier) oder in einer Variablen (uint8_t val) setzen.
Für IO-Ports funktioniert das deshalb zusätzlich, da diese im unteren Speicherbereich gemappt sind und der Zugriff transparent geschieht.
Der Compiler merkt, dass der Adressbereich zu IO-Registern gehört und nutzt dafür dann die entsprechenden Instruktionen sbi und cbi. Damit umgeht man ein read-modify-write, also sowohl Platz als auch Geschwindigkeit.
sbi/cbi funktionieren nur bis zu einer gewissen Adressgrenze, darüber muss man dann tatsächlich mit Read-Modify-Write arbeiten, wie ja auch die Anweisung PORT |= 1<<4 <==> PORT = PORT | 0x10; schon vermuten lässt.

_________________


[ Diese Nachricht wurde geändert von: DonComi am  5 Aug 2012  0:09 ]

BID = 841612

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus

Noch mal einen RIESEN Dank an dich, jetzt funktioniert es, wie es soll


Zitat :
muss es natürlich

#define __clearbit(PORT, BIT) PORT &= ~(1<<BIT)

sein.
Jetzt wo du´s sagst, fällt es mir auch auf...

Und so sieht es aus - Für alle, die ein ähnliches/das gleiche Problem haben.



Code :

#include <avr/io.h>

#include <avr/delay.h> //Wird für einen anderen Programmteil verwendet, dieses hier ist die gekürzte Variante

#define S1 (PINB&(1<<PINB3))
#define S2 (PINB&(1<<PINB2))
#define S3 (PINB&(1<<PINB1))
#define S4 (PINB&(1<<PINB0))

#define LED1 PORTB, PORTB7
#define LED2 PORTB, PORTB6
#define LED3 PORTB, PORTB5
#define LED4 PORTB, PORTB4

#define setbit(IO) __setbit(IO)
#define __setbit(PORT, BIT) PORT |= (1<<BIT)

#define clearbit(IO) __clearbit(IO)
#define __clearbit(PORT, BIT) PORT &=~ (1<<BIT)

int main (void)
{

DDRB = 0xF0; //Bit7...4 Ausgänge, Bit3...0 Eingänge
PORTB = 0x00; //Alle PullUp-Widerstände aus

//Ein Taster steuert eine LED mit Variablenzuweisung an

do {
//Direkte Zuweisung
if(S1) setbit(LED1);
else clearbit(LED1);
if(S2) setbit(LED2);
else clearbit(LED2);
if(S3) setbit(LED3);
else clearbit(LED3);
if(S4) setbit(LED4);
else clearbit(LED4);
/*
//Zuweisung über logische Verknüpfungen
if(S1&&S2) setbit(LED1); // AND
else clearbit(LED1);
if(!(S2&&S3)) setbit(LED2); // NAND
else clearbit(LED2);
if(S3||S4) setbit(LED3); // OR
else clearbit(LED3);
if(!(S4||S1)) setbit(LED4); // NOR
else clearbit(LED4);
*/
}while(1);

return 1;
}



_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 846665

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus

...ich mal einfach mal hier mit einem weiteren kleinen Problemchen weiter.

Diesmal geht es ums Entprellen ....jaja ich weiß, dieses Thema wurde schon in tausend Foren durchgekaut, würde aber dennoch gerne wissen, wo der Fehler liegt.

Verwendet habe ich diesen Code (von hier)

Allerdings bringt mein Compiler (AVR Studio 4.19) die Fehlermeldung
expected identifier or '(' before '{' token
in

Zitat :

#define debounce( port, pin )
Dieser Zeile ({
static uint8_t flag = 0;

Daher die Frage an die Experten: Was ist da los?



_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 846716

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Kannst du den Quellcode mal als C-Datei posten?
So kann ich damit nichts anfangen.

Wenn Defines über mehr Zeilen gehen sollen, dann __muss__ jede Zeile mit einem Backslash abgeschlossen werden.

Ansonsten noch mal gucken, ob das Makro auch richtig aufgerufen wird.

_________________

BID = 846729

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus


Zitat :
Kannst du den Quellcode mal als C-Datei posten?
Den hatte ich doch verlinkt.


Zitat :
Ansonsten noch mal gucken, ob das Makro auch richtig aufgerufen wird.
Wenn du mir noch verrätst wie, gerne.




_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.

BID = 846736

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Also ich kann den Source direkt und fehlerfrei übersetzen.

Im Allgemeinen ist von solchen Konstruktionen (mit Makros) abzuraten. Das ist nicht schön.

Mein Compileraufruf:
avr-gcc -mmcu=attiny2313 -Os -o debounce debounce.c


_________________

BID = 846788

Offroad GTI

Urgestein



Beiträge: 12742
Wohnort: Cottbus


Zitat :
Also ich kann den Source direkt und fehlerfrei übersetzen.
Nachdem ich ein neues Projekt angelegt hatte, klappt es bei mir jetzt auch.

Nur die 98µs Verzögerungszeit waren viel zu lang (für ein Senoiren-Telefon wahrscheinlich gerade richtig )
Habe sie jetzt soweit runter gesetzt, dass auch relativ schnell (~4Hz) getastet werden kann.



_________________
Theoretisch gibt es zwischen Theorie und Praxis keinen Unterschied. Praktisch gibt es ihn aber.


Vorherige Seite      
Gehe zu Seite ( Vorherige Seite 1 | 2 )
Zurück zur Seite 1 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 19 Beiträge im Durchschnitt pro Tag       heute wurden bisher 1 Beiträge verfasst
© x sparkkelsputz        Besucher : 182421362   Heute : 401    Gestern : 5459    Online : 372        29.11.2024    4:05
1 Besucher in den letzten 60 Sekunden        alle 60.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.111438035965