atmega32: Inputverhalten PORTB

Gast #1900746
Lesenswert?

Hi,

ich hab folgendes Problem:

Ich habe mir zwei Taster, wie unter 
http://www.mikrocontroller.net/articles/Entprellung beschrieben, mit dem 
74HC14 entprellt. Die Signale gebe ich auf PORTB an die Pins PB0 und 
PB1.

DDRB = 0x00;

Jetzt frage ich alle 100ms die Tasterzustände ab:

if(PINB & PB0) {
...
}

if(PINB & PB1) {
...
}

Wenn ich aber jetzt den Taster an Port PB1 betätige wird auch die obere 
Bedingung wahr.

Ich habe mir das Signal mit dem Oszi angeschaut. Wenn ich den Taster PB1 
drücke, liegt an PB1 HIGH-Pegel an. An PB0 bleibt der Pegel auf LOW. 
Also hab ich schon mal keine ungewollte Verbindung zwischen den beiden 
Pins.

Wenn ich nun die Signale nicht auf PORTB sondern auf PORTA lege, 
funktioniert alles einwandfrei.

Meine Frage: Wer weiß an was es liegen kann?

P.S.: Ich hab die alternativen Funktionen der PINS PB0 und PB1 nicht 
aktiviert ;)
#1900760
Lesenswert?

maggie schrieb:
> Korrektur: ich verwende:
>
> PORTB & (1<<PB0) und PORTB & (1<<PB1)

auch das ist falsch.

Hör auf, einfach immer nur Stückwerk zu posten.
Nimm dein *.c File und häng es als Attachment an. Auf die Art kannst du 
keine Fehler beim Tippen machen und wir haben alles was wir brauchen. 
Und zwar so, wie du es tatsächlich programmiert hast und nicht in der 
25ten fehlerbereinigten im Forum getippten Version, die dann immer noch 
nicht dem Programm entspricht, das tatsächlich am µC läuft.
Gast #1900765
Lesenswert?

Ach Du weisst doch: Das Problem liegt garantiert nicht in den nicht 
gezeigten Zeilen.
Und evtl. Fehler sind sowieso nur Tippfehler. Im "richtigen" Quelltext 
ist es so wie Du nachher als Korrektur vorschlägst.
Es wird dann eher an der Temperatur oder dem Wochentag gelegen haben.

Aber eine Frage ist da noch: Was ist der Unterschied zwischen PB0 und 1 
<< PB0 ?

Wer hierin Ironie findet, darf sie behalten.
Gast #1900769
Lesenswert?

Jo, alles klar:
1
void io_get_inputs(void) {
2
  if(PINB & (1<<PB0)) {
3
    if(!(DISPLAY_OUTPORT & (1<<DISPLAY_GREEN))) { // GREEN BL turned on
4
      display_green_backlight_off;
5
    } else {
6
      display_green_backlight_on;
7
    }
8
  }  
9
}

display_green... sind Makros.
Gast #1900778
Lesenswert?

Aber eine Frage ist da noch: Was ist der Unterschied zwischen PB0 und 1
<< PB0 ?

Du hast recht. Hier ist kein Unterschied. Bei PB5 und 1<<PB5 aber sehr 
wohl, da PB5 = 5 und 1 << PB5 = 0x20.

Abgesehen davon, dass ich hier halt zum ersten mal was poste und meine 
Post einbisschen verk*ckt habe, ist das noch lang kein Grund sich hier 
den arroganten Schnösel raushängen zu lassen.
Gast #1900785
Lesenswert?

NurEinGast schrieb:
> Wieso schaffst Du es nicht einfach das zu zun, was oben vorgeschlagen
> wurde ?
>
>>     Nimm dein *.c File und häng es als Attachment an.
>
> Willst Du Hilfe, oder lieber doch nicht ?


Wo ist dein Problem? Ich hab schick dir den Ausschnitt aus meinem 
C-File, um den es geht. Der Rest ist irrelevant.

Wie am Anfang geschrieben, hab ich das DDRB mit 0x00 initialisiert und 
das sollte doch dafür reichen, dass du dir deine Gedanken darüber machen 
kannst.

Das ganze ist Teil eines größeren Projekts und ich sehe keinen Anlass, 
das ganze Projekt hier reinzuposten.
Gast #1900787
Lesenswert?

> ist das noch lang kein Grund sich hier den arroganten Schnösel raushängen > zu 
lassen.

Das war nur Hellseherei. Kein Grund zur Aufregung. Nichts gegen Dich 
persönlich. Reine Statistik. Wenn Drei Milliarden Fische nur im Wasser 
atmen können, vermute ich vom 3.000.000.001ten das selbe.
#1900793
Lesenswert?

maggie schrieb:
> NurEinGast schrieb:
>> Wieso schaffst Du es nicht einfach das zu zun, was oben vorgeschlagen
>> wurde ?
>>
>>>     Nimm dein *.c File und häng es als Attachment an.
>>
>> Willst Du Hilfe, oder lieber doch nicht ?
>
>
> Wo ist dein Problem? Ich hab schick dir den Ausschnitt aus meinem
> C-File, um den es geht. Der Rest ist irrelevant.

Sagt wer?

Du scheinst nicht gar so unerfahren zu sein.
Wenn der Fehler tatsächlich in dem Code stecken würde, den du gepostet 
hast, hättest du ihn wahrscheinlich selber gesehen.
Da du ihn aber nicht gesehen hast ....  steckt der Fehler ganz woanders.

qed

Poste deinen Code!
Und das mein ich ernst


> Das ganze ist Teil eines größeren Projekts und ich sehe keinen Anlass,
> das ganze Projekt hier reinzuposten.

Du kannst ja auch ein Testprojekt machen, indem du nur den relevanten 
Teil herausziehst, compilierst, auf die Hardware brennst und nachsiehst 
ob der Fehler dort auch noch vorhanden ist. Wenn ja, dann postest du das 
kleinere Testprojekt.

Ansonsten: Such deine Fehler alleine. Irgendwann haben die meisten hier 
keine Lust mehr, dem Fragesteller ständig die Würmer aus der Nase ziehen 
zu müssen.
Gast #1900802
Lesenswert?

Ok,

jetzt für alle:
1
#define BIT_IS_SET(var, bit)   ((var) & (1 << (bit)))
2
#define BIT_IS_CLEAR(var, bit)   !BIT_IS_SET(var, bit)
3

4
...
5

6
#define IO_UP       PB0
7
#define IO_ENTER    PB1
8
#define IO_DOWN     PB4
9

10
...
11

12
void io_init(void) {
13
  io_tast_status = 0x00;
14
  io_tast_status_old = 0x00;
15
  io_tast_changed = 0x00;
16
}
17

18
void io_get_inputs(void) {
19
  io_tast_status_old = io_tast_status;
20
  io_tast_status = BIT_IS_SET(PINB, IO_UP) | BIT_IS_SET(PINB, IO_ENTER) | BIT_IS_SET(PINB, IO_DOWN);  
21
  io_tast_changed = io_tast_status_old ^ io_tast_status;  
22

23
  // Ist die Taste gedrückt und hat sich ihr Zustand geändert?
24

25
  if(BIT_IS_SET(io_tast_changed, IO_UP) && BIT_IS_SET(io_tast_status, IO_UP)) {
26
    if(BIT_IS_CLEAR(DISPLAY_OUTPORT, DISPLAY_GREEN)) { // GREEN turned on
27
      display_green_backlight_off;
28
    } else {
29
      display_green_backlight_on;
30
    }
31
  }    
32

33
  // Ist die Taste gedrückt und hat sich ihr Zustand geändert?
34

35
  if(BIT_IS_SET(io_tast_changed, IO_DOWN) && BIT_IS_SET(io_tast_status, IO_DOWN)) {
36
    if(BIT_IS_CLEAR(DISPLAY_OUTPORT, DISPLAY_RED)) { // RED turned on
37
      display_red_backlight_off;
38
    } else {
39
      display_red_backlight_on;
40
    }
41
  }
42
}
Gast #1900827
Lesenswert?

So, ich habe jetzt ein Testprojekt zusammengestellt.

Somit hoffe ich allen Forderungen der Gemeinschaft nachzukommen und zu 
einer Lösung des Problems meinen Teil in angemessener Weise beizutragen.

Sorry, wenn ich das Ganze etwas umständlich gemacht habe.
Angehängte Dateien:
Gast #1900846
Lesenswert?

Karl heinz Buchegger schrieb:
> Ich versteh zwar nicht, wozu in einem Testprogramm dass sich um Taster
> und LED dreht, ein Timer und ein Watchdog enthalten sein muss
>
> aber da dein LED am PC5 hängt und du einen Mega32 verwendest: JTAGEN ist
> abgeschaltet?

JTAGEN ist aus:

Fusebits:  -U lfuse:w:0x2f:m -U hfuse:w:0xc9:

Wie gesagt, das ganze ist Teil eines größeren Projekts und da sind 
getimete Tasks und der Watchdog von Nöten. Hier im Testprojekt 
vielleicht nicht. Da hast du recht. Aber es sollen ja etwa gleiche 
Bedingungen wie bei dem großen Projekt bestehen.
Angehängte Dateien:
#1900850
Lesenswert?

maggie schrieb:

> Wie gesagt, das ganze ist Teil eines größeren Projekts und da sind
> getimete Tasks und der Watchdog von Nöten. Hier im Testprojekt
> vielleicht nicht. Da hast du recht. Aber es sollen ja etwa gleiche
> Bedingungen wie bei dem großen Projekt bestehen.

Ist ok.

Deine Vorstellung wie extern funktioniert ist zwar fehlerhaft. Aber auf 
die Schnelle ist mir da jetzt nichts aufgefallen.

Um festzustellen, ob es ein Hardwareproblem ist, würde ich noch weiter 
abspecken
1
#include <avr/io.h>
2

3
int main()
4
{
5
  DDRB = 0x00;
6
  DDRC = 0xFF;
7

8
  while( 1 ) {
9
    if( PINB & ( 1 << PB0 ) )
10
      PORTC |= ( 1 << PC5 );
11
 
12
    if( PINB & ( 1 << PB1 ) )
13
      PORTC &= ~( 1 << PC5 );
14
  }
15
}

das wär mein Hardware-Testprogramm.
Die LED muss mit PB0 ein und mit PB1 ausschaltbar sein.

Geht das, dann hat es IMHO nichts mit der Hardware zu tun.
(Auch wenn ich mir die Arbeit mit den FF gar nicht gemacht hätte)
Gast #1900854
Lesenswert?

Vielleicht noch als Ergänzung:

Im Anhang befindet sich das Oszibild, wenn ich auf den Taster auf PB1 
drücke. Man kann sehen, dass keine Rückwirkungen bestehen.

Und auch nochmal: An PORTA funktioniert das Ganze. Deshalb kann es wohl 
auch nicht am PORTC liegen (z.B. JTAG).
Angehängte Dateien:
#1900860
Lesenswert?

maggie schrieb:
> Karl heinz Buchegger schrieb:
>>
>> Deine Vorstellung wie extern funktioniert ist zwar fehlerhaft. Aber auf
>> die Schnelle ist mir da jetzt nichts aufgefallen.
>>
>
> Was ist denn an meiner Vorstellung so falsch?


Bei Funktionsprototypen brauchst du kein extern.
Dafür aber bei globalen Variablen, die in einem Header File sind. Sind 
Variablen nicht global, haben sie auch in Header Files nichts verloren.


header_zu_source.h
********
1
#ifndef HEADER_H
2
#define HEADER_H
3

4

5
extern uint8_t  globVar;
6

7
void foo( void );
8

9
#endif

source.c
********
1
// Implementierung für header_zu_source.h
2
#include "header.h"
3

4
uint8_t globVar;
5

6
static uint8_t  meine_Filelokale_Variable;
7

8
void foo()
9
{
10
  globVar = 8;
11
  meine_Filelokale_Variable = 0;
12
}

main.c
******
1
// Verwendet header_zu_source.h
2
#include "header.h"
3

4
int main()
5
{
6
  globVar = 5;
7
}
Gast #1900863
Lesenswert?

Das

Karl heinz Buchegger schrieb:
>
> Bei Funktionsprototypen brauchst du kein extern.
> Dafür aber bei globalen Variablen, die in einem Header File sind. Sind
> VAriablen nicht global, haben sie auch in Header Files nichts verloren.
>
>
> header_zu_source.h
> ********
> #ifndef HEADER_H
> #define HEADER_H
>
>
> extern uint8_t  globVar;
>
> #endif
>
> source.c
> ********// Implementierung für header_zu_source.h
> #include "header.h"
>
> uint8_t globVar;
>
> main.c
> ******// Verwendet header_zu_source.h
> #include "header.h"
>
> int main()
> {
>   globVar = 5;
> }

Das mit den Funktionsprototypen gilt aber nur, wenn ich immer jede 
Headerdatei eines Moduls einbinden will.

Und da ich in meinen Moduldateien nur die Header der Module drinhabe, 
referenziere ich Funktionen aus anderen Modulen mit extern.
#1900870
Lesenswert?

maggie schrieb:

> Das mit den Funktionsprototypen gilt aber nur, wenn ich immer jede
> Headerdatei eines Moduls einbinden will.

Nein.
Generell.
Ein Funktionsprototyp braucht kein extern. Er schadet allerdings auch 
nicht.

> Und da ich in meinen Moduldateien nur die Header der Module drinhabe,
> referenziere ich Funktionen aus anderen Modulen mit extern.

Du hast aber zb im timer.h deine globalen Varablen nicht mit extern 
markiert. Nochmal: In Header Files haben Variablen ohne extern nichts 
verloren!

Es geht hier um die Unterscheidung zwischen Definition und Deklaration!
http://www.mikrocontroller.net/articles/FAQ#Globale_Variablen_.C3.BCber_mehrere_Dateien
Gast #1900900
Lesenswert?

Karl heinz Buchegger schrieb:
>
> Du hast aber zb im timer.h deine globalen Varablen nicht mit extern
> markiert. Nochmal: In Header Files haben Variablen ohne extern nichts
> verloren!
>
> Es geht hier um die Unterscheidung zwischen Definition und Deklaration!
> http://www.mikrocontroller.net/articles/FAQ#Global...

Ok alles klar. Ist halt einfacher, wenn ich Module aus nem anderen Modul 
einbinden will, weil ich dann nur noch das header-File des Moduls 
einbinden muss und nicht die einzelnen Variablen rauspflücken (und 
pfelgen) muss.

Funktional ist es aber kein Problem.
#1900945
Lesenswert?

maggie schrieb:
> Karl heinz Buchegger schrieb:
>>
>> Du hast aber zb im timer.h deine globalen Varablen nicht mit extern
>> markiert. Nochmal: In Header Files haben Variablen ohne extern nichts
>> verloren!
>>
>> Es geht hier um die Unterscheidung zwischen Definition und Deklaration!
>> http://www.mikrocontroller.net/articles/FAQ#Global...
>
> Ok alles klar. Ist halt einfacher, wenn ich Module aus nem anderen Modul
> einbinden will, weil ich dann nur noch das header-File des Moduls
> einbinden muss und nicht die einzelnen Variablen rauspflücken (und
> pfelgen) muss.

Genau darum geht es ja!

Wenn du es richtig machst, ist es nämlich überhaupt kein Problem.
Wenn du deine timer.h in 2 andere *.C Files inkludierst, läufst du 
bereits in Probleme.
Gast #1900949
Lesenswert?

Na dann kann ich ja jetzt mein Testboard wieder anders verwenden.
Ich fand Dein Problem interessant und hatte eben Deine Software in mein 
Testboard gebrannt und mit Debugger schauen wollen, was da passiert :-) 
Hatte aber kein Problem gefunden und wollte Dich gerade fragen ob es 
nicht vielleicht doch irgendwie an der HW liegen könnte.

Mir ist zwar nicht wirklich klar, warum dieses Fehlerbild auftritt, wenn 
PB1 nicht sauber verlötet ist - aber egal. Wenn alles läuft - auch gut.

Viel Erfolg weiterhin bei Deinem Projekt

NurEinGast
Gast #1900957
Lesenswert?

NurEinGast schrieb:
> Na dann kann ich ja jetzt mein Testboard wieder anders verwenden.
> Ich fand Dein Problem interessant und hatte eben Deine Software in mein
> Testboard gebrannt und mit Debugger schauen wollen, was da passiert :-)
> Hatte aber kein Problem gefunden und wollte Dich gerade fragen ob es
> nicht vielleicht doch irgendwie an der HW liegen könnte.
>
> Mir ist zwar nicht wirklich klar, warum dieses Fehlerbild auftritt, wenn
> PB1 nicht sauber verlötet ist - aber egal. Wenn alles läuft - auch gut.

Mir ist zwar auch nicht klar, was die defekte Lötstelle hier verursacht 
hat. Das Oszibild gibt ja keinerlei Aufschlüsse darüber. Irgendwie schon 
strange.

> Viel Erfolg weiterhin bei Deinem Projekt
>
> NurEinGast

Danke für deine Bemühungen ;)
Gast #1900961
Lesenswert?

Karl heinz Buchegger schrieb:
>
> Genau darum geht es ja!
>
> Wenn du es richtig machst, ist es nämlich überhaupt kein Problem.
> Wenn du deine timer.h in 2 andere *.C Files inkludierst, läufst du
> bereits in Probleme.

Und noch wegen der Prototypen. Mit extern sage ich dem Compiler ja nur, 
dass sich die Funktion in einem anderen Modul befindet. Sollte ja 
prinzipiell richtig sein. Ist aber nicht mehr nötig wenn ich deine 
Ratschläge befolge ;)

Danke
#1900999
Lesenswert?

maggie schrieb:
> Karl heinz Buchegger schrieb:
>>
>> Genau darum geht es ja!
>>
>> Wenn du es richtig machst, ist es nämlich überhaupt kein Problem.
>> Wenn du deine timer.h in 2 andere *.C Files inkludierst, läufst du
>> bereits in Probleme.
>
> Und noch wegen der Prototypen. Mit extern sage ich dem Compiler ja nur,
> dass sich die Funktion in einem anderen Modul befindet.


Das weiß er auch so.

void foo( void );

kann nur ein Prototyp und nicht die Implementierung einer Funktion sein. 
Daher ist das extern hier nicht notwendig, wenn es auch nicht schadet.

Mittels "extern" erhebt man etwas zu einer Deklaration um es von einer 
Definition zu unterscheiden. Bei Funktionen ist die Sache auch so klar, 
nur bei Variablen muss man selber Hand anlegen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren