Hallo,
ich habe folgendes Problem:
Im Dateianhang findet ihr einen Teil des Schaltplans, ich habe nur den
Teil beigefügt der mir Probleme bereitet. Folgendes, der Controller
läuft mit dem Programm (Code unten)auf dem STK500 sehr gut und schaltet
mir über je 2 Taster je einen Ausgang, mit dem ich je ein Relai
ansteuern möchte um den rechts-links-lauf für einen Motor zu
realisieren. Leider leuchten auf dem STK500 alle LEDs so wie sie sollen
aber das Relai schaltet nicht so wie es soll und der Ausgang am
Controller ist nie wirklich auf 0V. Es liegt immer eine Spannung an,
4,87V oder geschaltet 1,76V und ich wüsste gerne warum ???
Zweites Problem, wie kann ich das schalten des Ausgangs im Programm am
besten umkehren/negieren ???
Für Tips und Hilhen wäre ich euch sehr dankbar - ich habe langsam keine
Gedult mehr, ist schon die dritte Platine......
Gruss Boris
____________________________________________________________________
#include <avr/io.h>
int main (void)
{
DDRB &= ~( 1 << PB0 ); //PB0 Eingang
DDRB &= ~( 1 << PB1 ); //PB1 Eingang
PORTB |= ( 1 << PB0 ); //Pull up an
PORTB |= ( 1 << PB1 ); //Pull up an
DDRC &= ~( 1 << PC2 ); //PC2 Eingang
DDRC &= ~( 1 << PC3 ); //PC3 Eingang
PORTC |= ( 1 << PC2 ); //Pull up an
PORTC |= ( 1 << PC3 ); //Pull up an
DDRC |= ( 1 << PC0 ); //PC0 Ausgang
DDRC |= ( 1 << PC1 ); //PC1 Ausgang
while(1)
{
if (PINB & (1 << PB0))//wenn PB0 High ist...
{
PORTC |= (1 << PC0); //PC0 High
}
if (PINB & (1 << PB1))//wenn PB1 High ist...
{
PORTC |= (1 << PC1); //PC1 High
}
if (PINC & (1 << PC2))//wenn PC2 High ist...
{
PORTC |= (1 << PC0); //PC0 High
}
if (PINC & (1 << PC3))//wenn PC3 High ist...
{
PORTC |= (1 << PC1); //PC1 High
}
// Eine Schleife
if (!(PINB & (1 << PB0))) //wenn PB0 Low ist...
{
PORTC &= ~(1 << PC0); //PC0 Low
}
if (!(PINB & (1 << PB1))) //wenn PB1 Low ist...
{
PORTC &= ~(1 << PC1); //PC1 Low
}
if (!(PINC & (1 << PC2))) //wenn PC2 Low ist...
{
PORTC &= ~(1 << PC0); //PC0 Low
}
if (!(PINC & (1 << PC3))) //wenn PC3 Low ist...
{
PORTC &= ~(1 << PC1); //PC1 Low
}
}
return 0;
}
____________________________________________________________________
sorry für den vielen Platz durch den Code !!!! ;-)
Hast Du wirklich AVCC, AGND und AREF richtig beschaltet?
Das "Andersherum" Schalten des Ausgangs kann man z.B.in BASCOM mit dem
NOT - Befehl erreichen. Ob es den in C gibt, weiß ich nicht, davon
verstehe ich nichts.
MfG Paul
Sorry,
habe ich in der Skizze leider vergessen - Pin 20 liegt an 5V VCC.
Ich habe jetzt mal LEDs an die Stelle der Relais gelötet und
festgestellt, das sie ständig leuchten und nur dann heller werden, wenn
ich einen Taster für links oder rechts drücke.
Stimmt etwas mit der Transistoransteuerung nicht oder das Programm ? auf
dem STK500 geht es doch ???
Gruss Boris
Hallo,
nein - eine H-Brücke ist nicht nötig, das ist ein Getriebemotor der
sofort steht sobald der Taster losgelassen wird. Ich habe am Ausgang des
Mic immer 4,8V stehen und sobald ich den Taster drücke, fällt der Pegel
nur auf 1,2V ab. Abgesehen davon, das der Ausgang 0V liefern sollte und
erst dann ca. 5V wenn der Taster gedrückt wird..... scheint das Programm
zu laufen. Das mit dem umgekehrten Pegel liegt eben am STK500, das dreht
den Pegel an den Ausgängen um.
Also es wäre nett, wenn mir jemand helfen könnte.
Danke !
Boris
Ich hab jetzt dein Programm nicht in allen Einzelheiten
analysiert. Da sind mir einfach zuviele if then-else
die jeweils den Port-Pin verstellen.
Ich könnte mir aber vorstellen, dass in Wirklichkeit dein
PC0 bzw. PC1 Ausgang ständig den Pegel wechselt.
Warum machst du nicht einfach mal ein simples Testprogram
1
intmain()
2
{
3
DDRC=(1<<PC0)|(1<<PC1);
4
5
while(1){
6
PORTC=0x03;
7
}
8
}
Jetzt müssen die beiden Relais sauber anziehen.
Tun sie das, dann kommt der Gegentest
1
intmain()
2
{
3
DDRC=(1<<PC0)|(1<<PC1);
4
5
while(1){
6
PORTC=0x00;
7
}
8
}
Und die Relais sollten ruhig sein.
Wenn das hier klappt (ruhig auch mal die Spannungen am µC
Pin nachmessen), dann sieh dir nochmal dein Programm an.
Zieh es umgekehrt auf:
Geh nicht von den Eingängen aus und leite davon ab, was am
Ausgang passieren soll, sondern geh von den Ausgängen aus
und überleg dir, welche Bedingung an den Eingängen vorliegen
muss, damit der Ausgang 1 bzw. 0 sein soll. Formulier das
als eine einzige Bedingung. Dadurch läufst du dann nicht
Gefahr, dass ein Programmteil den Portausgang auf 1 setzt
und gleich darauf ein anderer Programmteil den Ausgang wieder
auf 0 runterzieht.
Hallo,
vielen Dank - es ist genau wie Du geschrieben hast, die Ausgänge werden
sauber geschaltet. Das ist mein erstes Projekt mit einem AVR - wie
bekomme ich das hin, das ich die Ausgänge mit einem Taster sauber
schalte - ohne ein flimmern ?
Gibt es da einen Trick, wie man die Ausgänge am sichersten schaltet ?
Vielen Dank !
Gruss
Buris
Boris wrote:
> Gibt es da einen Trick, wie man die Ausgänge am sichersten schaltet ?
Der Trick ist, die Ausgänge nur an einer einzigen STelle im Code
schalten. Entweder ein oder aus. Aber nicht an 5 verschiedenen
Stellen verstreut über den ganzen Code.
Ich geh mal davon aus, dass dein Eingänge 2 von 2 Tastern
und 2 Endschaltern kommen.
Das heist, der Motor darf nur dann in eine Richtung fahren,
wenn der entsprechende Taster gedrückt und der entsprechende
Endschalter nicht erreicht ist.
Um das ganze übersichtlicher zu gestalten, schlage ich die
Einführung von ein paar Funktionen vor
1
uint8_tTasterRauf()
2
{
3
PINB&(1<<PB0);
4
}
5
6
uint8_tEndschalterOben()
7
{
8
PINC&(1<<PC2);
9
}
10
11
voidMotorAuf()
12
{
13
PORTC&=~(1<<PC1);
14
PORTC|=(1<<PC0);
15
}
16
17
voidMotorZu()
18
{
19
PORTC&=~(1<<PC0);
20
PORTC|=(1<<PC1);
21
}
22
23
voidMotorStop()
24
{
25
PORTC&=~(1<<PC0);
26
PORTC&=~(1<<PC1);
27
}
Der Zweck dieser Hilfsfunktionen besteht darin, den eigentlichen
Code einfacher bzw. lesbarer zu gestaltet. Die Ganzen << und & und |
lenken sonst extrem vom eigentlichen Geschehen ab. Du willst dich
nicht ständig mit & und | herumschlagen, du willst dich mit deiner
Logik beschäftigen.
1
intmain()
2
{
3
...
4
5
while(1){
6
7
// Wenn die Taste für 'Rauf' gedrückt ist, dann fährt der
8
// Motor nach oben. Aber nur, wenn der Endschalter dafür
9
// nicht schon erreicht ist
10
11
if(TasterRauf()){
12
if(!EndschalterOben())
13
MotorAuf();
14
}
15
16
// Wenn die Taste für 'Runter' gedrückt ist, dann fährt der
17
// Motor nach unten. Aber nur dann, wenn der entsprechende
18
// Endschalter nicht betätigt ist UND wenn die Kinder nicht
19
// wieder mal ihre Patschehändchen auf beiden Tasten gleich-
20
// zeitig haben. In dem Fall 'gewinnt' dann die Taste für
21
// auf
22
23
elseif(TasterRunter()){
24
if(!EndschalterUnten())
25
MotorZu();
26
}
27
28
// nichts ist gedrückt. Dann soll auch nichts passieren
29
else
30
MotorStop();
31
}
32
}
Man beachte, wie der Code hier schon fast selbsterklärend wird.
Durch die Funktionen ist der Code schon fast sowas wie eine
Zusammenfassung des jeweils darüberstehenden Kommentars.
PS: Ich habe jetzt nicht darauf geachtet, ob die Schatlerfunktionen
korrekt auf PIN 0 oder 1 geschrieben sind. Da musst du
ev. nachbessern. Dazu würde ich mir gleich wieder mal ein Testprogramm
schreiben
1
intmain()
2
{
3
...
4
5
while(1){
6
7
if(!EndschalterOben())
8
MotorAuf();
9
}
10
}
Die Erwartung dieses Testprogramms: Der Motor fährt auf, bis
der Endschalter anspricht.
Jetzt vergleichst du die Realität mit der Erwartung. Tut die
Schaltung das erwartete? Wenn nein, dann untersuchst du
warum nicht. Es gibt nur eine Möglichkeit: Die Auswertung
des Endschalters ist genau verkehrt rum. Also korrigierst
du sie in der Endschalter Funktion.
Wenn das dann klappt, dann gehts ans überprüfen in die andere
Richtung.
Erst nachdem die Einzelteile geprüft sind, baust du dann wie
oben angedeutet, das komplette Programm zusammen.
Du musst anfangen modular zu arbeiten. Kleine Änderungen, die
jede für sich einzeln testbar sind.
Super - vielen Dank !!!
ich werde mich gleich mal dran machen...so hört es sich schon viel
besser an und ich glaube das könnte etwas werden.
Mit den Endschaltern ist eine gute Idee, nur die zwei weiteren Schalter
wollte ich mir für später reservieren um das Projekt noch ausbauen zu
können. Der Motor hat intern schon Endschalter und die Abschaltung
wollte ich per Zeit machen - sicher ist sicher.
Aber das ist dann das nächste Problem, erst müssen die Ausgänge auf die
Taster reagieren, danach möchte ich das jeder Ausgang nur ca.2 Minuten
aktiv ist und dann automatisch wieder auf low geht.
Aber wie gesagt.... dieses Wochenende hoffe ich den Anfang zu finden und
die Arbeitsweise zu begreifen.
Nochmals vielen Dank, Du solltest Lehrgänge anbieten - sehr gut erklärt
!
Gruss
Boris
Hallo Karl Heinz,
also mit dem Programm habe ich doch einige Probleme,
was bedeuten die "unit8_t..." kann ich jetzt direkt unit8_t TasterAuf
aufrufen und es als Variable nutzen oder wofür steht es ?
Und die Definition für void MotorAuf() kann ich die auch als Variable
aufrufen ?
Also irgendwie bringt mich das jetzt doch durcheinander....
Muss ich die Ein-/Ausgänge nicht auch noch definieren ?
Danke !
mfg.
Boris
uint8_t TasterAuf()
{
PINB & ( 1 << PB0 );
}
uint8_t ExtAuf()
{
PINC & ( 1 << PC2 );
}
uint8_t TasterZu()
{
PINB & ( 1 << PB1 );
}
uint8_t ExtZu()
{
PINC & ( 1 << PC3 );
}
void MotorAuf()
{
PORTC &= ~( 1 << PC1 );
PORTC |= ( 1 << PC0 );
}
void MotorZu()
{
PORTC &= ~( 1 << PC0 );
PORTC |= ( 1 << PC1 );
}
void MotorStop()
{
PORTC &= ~( 1 << PC0 );
PORTC &= ~( 1 << PC1 );
int main(void)
{
...
while( 1 )
{
// Wenn die Taster für 'Rauf' oder Taster "Extauf" gedrückt ist,
dann fährt der
// Motor ca. 2 Minuten nach oben.
// Wird ein Taster für "auf" gedrückt, stehen alle Ausgänge wieder auf
"0".
if( TasterRauf(PB0==0) )
{
if( Extauf(PC2==0) )
MotorAuf(PC0==1);
}
// Wenn die Taste für 'Runter' oder Taster "Extzu" gedrückt ist,
dann fährt der
// Motor ca. 2 Minuten nach unten.
// Wird ein Taster für "auf" gedrückt, stehen alle Ausgänge wieder auf
"0".
else if( TasterRunter(PB1==0) )
{
if( Extzu(PC3==0) )
MotorZu(PC1==1);
}
// nichts ist gedrückt. Dann soll auch nichts passieren
//else
//MotorStop();
//}
//}
//int main()
//{
//while( 1 )
//{
//if( !EndschalterOben() )
//MotorAuf();
//}
//}
Boris wrote:
> Hallo Karl Heinz,> also mit dem Programm habe ich doch einige Probleme,> was bedeuten die "unit8_t..."
uint8_t ist ein Datentyp. So wie int oder double oder long.
Nur ist dieser Datentyp so spezifiziert, dass er exakt einem
Byte entspricht.
> kann ich jetzt direkt unit8_t TasterAuf> aufrufen
TasterAuf ist eine Funktion.
Die kann man einfach aufrufen und diese Funktion liefert einen
Wert. So wie sin(0.2) einen Wert liefert (nämlich den Sinus
des angegebwnwn Winkels), so liefert TasterAuf einen Wert.
Dieser Wert repräsentiert den Zustand der Taste 'auf'
> Und die Definition für void MotorAuf() kann ich die auch als Variable> aufrufen ?
Das ist keine Variable. Das ist wieder eine Funktion. Wird die
aufgerufen, so sorgt sie dafür, dass der Motor in die 'Auf-Stellung'
läuft.
> Also irgendwie bringt mich das jetzt doch durcheinander....
C-Literatur besorgen. Eine Programmiersprache lernt man nicht
dadurch, dass man sich durchwurschtelt.
Modulares Programmieren (Programmieren indem man sich Funktionen
für bestimmte Aufgaben schreibt und diese dann verwendet) ist
das A und O einer vernünftigen Softwareentwicklung.
> Muss ich die Ein-/Ausgänge nicht auch noch definieren ?
Sicher musst du das. Da ich aber nicht 100% weiss, wo deine
Taster und Motoren am µC hängen, habe ich das in main() mit
den 3 Punkten ... angedeutet.
> if( TasterRauf(PB0==0) )
TasterRauf liefert schon einen Wert (oder soll es zumindest), der
eine Aussage darüber trifft, ob der Taster gedrückt ist oder
nicht.
if( TasterRauf() )
Hallo Karl Heinz,
nochmals Danke für Deine Hilfe - momentan bin ich auf der Arbeit sehr
eingespannt - also sorry das ich mich erst jetzt wieder melde. In der
Schule habe ich C und Pascal gehabt.... ist nur schon sehr lange her und
ich komme da nur schwer wieder rein.
Also fange ich mal von ganz vorne an, Schritt für Schritt.
Ich benötige 4 Eingänge und 2 Ausgänge
PB0 oder PC2 schalten Ausgang PC0 auf "1"
PB1 oder PC3 schalten Ausgang PC1 auf "1"
(Die Eingänge liegen immer auf "1" und werden bei Betätigung auf "0"
gezogen, die Ausgänge sollen "1" liefern wenn sie aktiv sind)
Was benötige ich dafür und was muss ich wie definieren damit das schon
mal funktioniert ?
Danke !
Gruss
Boris