Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 Zeitprobleme


von Jakob (Gast)


Lesenswert?

Guten Morgen,

möchte mit einem Atiny2313 eine kleine Steuerung machen..
Nix besonderes, er fragt 3 Pin's ab ( wo ein später "Taster" ran kommen, 
im Moment nur simuliert ) und soll je 2 Pin's high oder low setzten.
Macht er auch, aber, die Zeiten sind willkürlich. Die 2 Sek. macht er 
bei Position 2 aber bei Position 1 hängt er sich lange auf, manchmal 
aber macht er auch nur 2 Sek. und schalten normal um. Programmiert wird 
er über ISP mit dem AVRISP mkII. Die Fuses sind auch eigentlich richtig 
gesetzt. Hier mal der Code, eventuell könnt ihr mir weiter helfen .
1
/*
2
 * AVRGCC2.c
3
 *
4
 * Created: 20.03.2014 12:41:52
5
 *  Author: Jakob
6
 */ 
7
8
#include <avr/io.h>
9
#define F_CPU 8000000UL
10
#include <util/delay.h>
11
#include <avr/interrupt.h>
12
13
int u=1;
14
int o=1;
15
int auf=0;
16
 
17
int main(void)
18
{
19
  
20
DDRB = 0x00;
21
DDRD = 0xFF;
22
23
24
    while(1)
25
    {
26
  
27
if (auf==1)
28
{
29
  PORTD = 0b00100001; // 
30
  }
31
32
if (auf==0)
33
{
34
  PORTD = 0b00010000; // 
35
}
36
    
37
 if ((PINB & (1<<PINB1)) && (PINB &(1<<PINB3)) && u==1)    //Position 1
38
{
39
  PORTD = 0x01;
40
  _delay_ms(2000);  
41
  PORTD = 0x00 ;
42
  u=0;
43
  o=1;
44
  auf=0;
45
}
46
47
if ((!(PINB & (1<<PINB1))) && (PIND & (1<<PINB4)) && o==1)  //Position 2
48
{
49
  PORTD = 0b00000010;
50
  _delay_ms(2000);
51
  PORTD = 0x00 ;  
52
  o=0;
53
  u=1;
54
  auf=1;
55
}
56
    }
57
}

von Karl H. (kbuchegg)


Lesenswert?

Was mir als erstes auffält:

Brauchst du keine Pullup Widerstände?

Es ist in Irrglaube, dass ein Eingang an dem nichts hängt, ein 
0-Potential hätte! So ein Eingang ist hochohmig genug, dass er sich 
jedes dahergelaufene elektromagnetische Feld einfängt. Und davon haben 
wir genügend in unserer Umgebung: Handies, Elektromotoren, du selbst 
fungierst als Antenne, die Stromleitungen in der Wand, dein PC, etc. 
etc.

von Karl H. (kbuchegg)


Lesenswert?

Mit solchen Rundumschlag Portzuweisungen wirst du auf Dauer nicht 
glücklich
1
  PORTD = 0x01;


du willst an einem Port immer nur die Pins auch tatsächlich verändern, 
die du verändern musst.

Pin auf 1 setzen
1
    Port |= ( 1 << pin );
Pin auf 0 löschen
1
    Port &= ~( 1 << pin );

von Jakob (Gast)


Lesenswert?

Ich werde mal Pull-Down Widerstände einbauen. Da ich, wenn nix anliegt, 
das Potenzial auf GND haben muss.

von Uwe S. (de0508)


Lesenswert?

Bitte erkläre uns warum Du ein "musst hast.

Jakob schrieb:
> Ich werde mal Pull-Down Widerstände einbauen. Da ich, wenn nix anliegt,
> das Potenzial auf GND haben muss.

von Jakob (Gast)


Lesenswert?

Wie meinen sie das mit "Bitte erkläre uns warum Du ein "musst hast".
Das Potenzial der Eingänge ziehe ich bei nicht anliegen Signal gegen 
GND. Damit auch 0 Anliegt.

von Karl H. (kbuchegg)


Lesenswert?

Jakob schrieb:
> Ich werde mal Pull-Down Widerstände einbauen. Da ich, wenn nix anliegt,
> das Potenzial auf GND haben muss.

Du brauchst es nur richtig rum programmieren und später die taster 
richtig rum anschliessen, dann kannst du die eingebauten Pullup 
Widerstände benutzen.

Ob du einen Pin mit
1
   if( PINB & ( 1 << PB0 ) )
abfrägst, oder mit
1
   if( !(PINB & ( 1 << PB0 ) )
ist doch Komplexitätsmässig völlig egal.

Im einfachsten Fall macht man sich dafür ein  Makro
1
#define IS_PRESSED(p,b)  (!(p & (1<<b)))
, schreibt im Code dann
1
   if( IS_PRESSED( PINB, PB0 ) )

und ist damit im Code die Details, ob die Taster nach GND oder nach Vcc 
schalten, los. Im eigentlichen Programm interessiert das dann überhaupt 
nicht mehr, denn da erhebt sich dann bei den Abfragen nur mehr die 
Frage: gedrückt oder nicht gedrückt. Das Detail, das gedrückt ein 0 Bit 
bedeutet braucht man im Code dann überhaupt nicht mehr berücksichtigen. 
Dieses Detail kommt durch die Makro-Ersetzung für den Compiler wieder 
ins Spiel, aber mich als menschlichen Programmierer kümmert es nicht 
mehr. Denn ich als Programmierer denke nicht in 0 oder 1 Bits, sondern 
in gedrückten oder nicht gedrückten Tasten. Und genau das steht dann 
auch so im Code.

Wenn etwas gemacht werden soll, wenn 2 Taster gleichzeitig gedrückt 
sind, dann eben:
1
   if( IS_PRESSED( PINB, PB0 ) &&
2
       IS_PRESSED( PINB, PB3 ) )
3
     ...

und da kann man doch (fast) nicht mehr meckern. Das liest sich im C Code 
dann schon ganz gut.
Wenn man die Pinnummern mittels #define auf einen sprechenden Namen 
rauszieht
1
#define MASTER_KEY  PB3
2
#define DOOR_UP     PB0
3
4
....
5
6
   if( IS_PRESSED( PINB, MASTER_KEY ) &&
7
       IS_PRESSED( PINB, DOOR_UP ) )
8
9
..

dann hat man plötzlich eine ganz andere Code Qualität, weil der Code 
selber schon fast ein englischer Satz ist, der mir erzählt, worum es an 
dieser Stelle im Code geht.


Fazit: Lerne dein C! Dann verliert vieles, von dem du dich jetzt 
fürchtest seinen Schrecken, weil du weißt, wie man das in C so 
formulieren kann, dass es überhaupt kein Problem mehr ist.
Was du jetzt auch lernen musst: wie kann ich die Möglichkeiten von C 
einsetzen um mir selbst das Leben leichter zu machen?
Es ist keineswegs Gott gegeben, dass in einem C Programm es nur so von 
unverständlichen Bit-Ausdrücken wimmelt, über die man erst mal 3 Minuten 
brüten muss, um sie zu verstehen oder die nur mit großem Aufwand zu 
ändern sind. Das alles liegt in deiner Hand, dir das so zu organisieren, 
dass es kein Problem darstellt. Die Sprache gibt dir die Mittel dazu. 
Aber benutzen musst schon du diese Mittel.

: Bearbeitet durch User
von Jakob (Gast)


Lesenswert?

Hab immer noch ein Problem.
Erstmal danke an Karl Heinz für den Tipp, werde ihn anwenden wenn ich 
das Problem gefunden habe.

Hab das Programm mal auf Pull-Up geschrieben...#

Das Programm sollte alle 1,5sek zwischen den beiden Positionen wechseln, 
hängt sich aber bei jetzt bei Position 2 auf. Ist hier im Programm ein 
sehr grober Fehler ? Weil in der Verdrahtung stimmt alles. Oder kann der 
2313 ein hau weg haben ? Oder braucht der einen externen Ozi ?
1
#include <avr/io.h>
2
#define F_CPU 8000000UL
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
6
int u=1;
7
int o=1;
8
int auf=0;
9
 
10
int main(void)
11
{
12
  
13
DDRB = 0x00;
14
PORTB =0xFF;
15
DDRD = 0xFF;
16
17
18
    while(1)
19
    {
20
  
21
if (auf==1)
22
{  
23
  PORTD = 0b11011110;  //Position 1
24
  
25
  }
26
27
if (auf==0)
28
{  
29
  PORTD = 0b11101111;  //Position 2 
30
  
31
}
32
    
33
 if ((!(PINB & (1<<PINB1))) && (!(PINB &(1<<PINB3))) && u==1)    //Position 1
34
{
35
  PORTD  |= (1<<PIND0);
36
  _delay_ms(1500);  
37
  PORTD &= ~(1<<PIND0);
38
  u=0;
39
  o=1;
40
  auf=0;
41
}
42
43
if ((PINB & (1<<PINB1)) && (!(PIND & (1<<PINB4))) && o==1)  //Position 2
44
{
45
  
46
  PORTD  |= (1<<PIND1);
47
  _delay_ms(1500);
48
  PORTD &= ~(1<<PIND1);
49
  o=0;
50
  u=1;
51
  auf=1;
52
}
53
    }
54
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jakob schrieb:
> Das Programm sollte alle 1,5sek zwischen den beiden Positionen wechseln
Warum sollte es das tun?

> (!(PIND & (1<<PINB4)))
Es sind zwar nur #defines, aber es sieht seltsam aus...

von Karl H. (kbuchegg)


Lesenswert?

Jakob schrieb:
> Hab immer noch ein Problem.
> Erstmal danke an Karl Heinz für den Tipp, werde ihn anwenden wenn ich
> das Problem gefunden habe.

Tja. Hättest du das mal gleich gemacht
1
if ((PINB & (1<<PINB1)) && (!(PIND & (1<<PINB4))) && o==1)  //Position 2
2
                              ****


Die Sichtweise "Ich will jetzt erst mal haben das es funktioniert und 
dann kümmere ich mich darum, dass es 'schön' ist" ist die falsche 
Sichtweise. Denn sie übersieht, dass man sich viele blödsinnige Fehler 
spart, wenn man gleich ein 'schönes', übersichtliches Programm schreibt.
Du darfst dir selbst als Programmierer möglichst wenig Tüchen offen 
lassen, in denen du Fehler machen kannst. Und das interessante daran: in 
den meisten Fällen führt genau dieses 'Schliessen von Türchen' zu den 
bereits genannten Techniken, mit denen ein Programm 'schöner' wird und 
auch qualitativ einen Schritt nach vorne macht.

Dazu gehören im Übrigen auch vernünftige Einrückungen im Code, so dass 
man die generelle Struktur, erkennt. Dazu gehören auch vernünftige 
Variablennamen. Dazu gehört auch, dass man zb so was
1
if (auf==1)
2
{  
3
  PORTD = 0b11011110;  //Position 1
4
  
5
  }
6
7
if (auf==0)
8
{  
9
  PORTD = 0b11101111;  //Position 2 
10
  
11
}
nicht schreibt, denn das 'else' als Ausdruck für 'wenn - dann - 
andernfalls' ist schon erfunden, so dass man nicht 2 Abfragen mit 
gegensätzlichen Bedingungen schreiben muss, in denen man Gefahr läuft 
die beiden Abfragen zu verbocken.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Was soll das eigentlich für eine Steuerung werden?

Dein Code und vor allen Dingen die vielen Variablen, kommen mir ein 
wenig viel und recht unübersichtlich vor.
Das sieht fast aus wie eine Türsteuerung oder so ähnlich. Ein Taster ist 
den Bedientaste, die anderen beiden sind Endschalter und am Port D hängt 
u.A. eine H-Brücke, mit der ein Motor vorwärts/rückwärts gefahren werden 
kann.

Aber so recht ist das Ziel des ganzen nicht erkennbar. Ich sag 
absichtlich 'fast', denn so richtig stimmt das Ganze dann auch wieder 
nicht. Ich bin mir nur noch nicht im klaren, ob das daran liegt, dass 
ich die Aufgabenstellung nicht kenne, oder daran, dass da grundsätzlich 
schon mal der Wurm drinnen ist.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.