Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage I/O über interne Pullups


von Bastler (Gast)


Lesenswert?

Hallo

Ich beschäftige mich erst seit neuestem mit uCs.
Ich bin noch bei dem simplen gebastel mit Dioden an einem ATMega.
Jetzt möchte ich mit einem stückchen Draht das an GND hängt einen 
Schlater simulieren.

Aber folgendes Programm funktioniert nicht und ich begreife nicht so 
ganz warum:

void main(void)
{
  DDRC=0xff;    //PORTC ist Ausgang
  DDRF=0x00;    //PORTF ist Eingang
  PORTF=0xff;   //pullups aktivieren für Eingang => 5V an den PINS, zum 
Schalten auf Masse ziehen!

  while(1)
  {
  loop_until_bit_is_set(PINF, PINF7); //warte bis Taste zum Senden 
gedrückt oder Interrupt eingelaufen
  setbit(PINC,PC5);
  loop_until_bit_is_clear(PINF, PINF7);
  clearbit(PINC,PC5);
  }
}



Dadurch das ich die internen Pullups aktiviert habe müsste ja die 
Abfrage von einem PINF "1" ergeben. Wenn ich jetzt einen Draht von Masse 
an den PIN lege müsste die Abfrage "0" ergeben.

Aber das funktioniert nicht. Die Abfrage ergibt immer "0".
Wo ist mein Denkfehler?
Der interne Pullup bringt doch den PIN auf 5V oder nicht?

von Falk B. (falk)


Lesenswert?

@ Bastler

Welche Proogrammiersprache und Compiler ist das? Sieht nach C aus, aber 
wohl kein GCC.

>Dadurch das ich die internen Pullups aktiviert habe müsste ja die
>Abfrage von einem PINF "1" ergeben. Wenn ich jetzt einen Draht von Masse
>an den PIN lege müsste die Abfrage "0" ergeben.

Ja.

>Der interne Pullup bringt doch den PIN auf 5V oder nicht?

Ja.

Das Problem ist möglicherweise Prellen. Mach mal einen Delay von 1 
Sekunde hinter die Anweisung, welche die LED anschaltet.

MFG
Falk


von Karl H. (kbuchegg)


Lesenswert?

Welchen Mega benutzt du?

>  setbit(PINC,PC5);

Du willst nicht am PIN Register eine 1 setzen,
sondern am PORT register

  setbit(PORTC, PC5);

PIN      von der Umwelt -> µC
PORT     vom µC -> Umwelt

Mach mal folgendes, noch einfachere Programm

[C]
int main()
{
  DDRC=0xff;    //PORTC ist Ausgang
  DDRF=0x00;    //PORTF ist Eingang
  PORTF=0xff;   //pullups aktivieren für Eingang => 5V an den PINS, zum 
Schalten auf Masse ziehen!

  while(1)
  {
    PORTC = PINF;
  }
}

von Bastler (Gast)


Lesenswert?

Hallo
Ist ein ATMega128.
Benutze AVRStudio mit istalliertem WinAVR.
An PORTC hängen über Vorwiderstände Dioden zu Masse.
An PORTF halte ich wiegesagt einen Draht der an Masse angeschlossen 
ist...

Das Programm von kbucj´hegg funktioniert leider auch nicht.
Hab irgendwie das Gefühl da ist ein ganz simpler fataler Denkfehler 
drin.
Komme aber im Moment nicht drauf.

von Bastler (Gast)


Lesenswert?

Hier nochmal der komplette Quelltext:


//Includes
#include <avr/io.h>         //Header mit I/O Registern aus WinAVR
#include <avr/interrupt.h>  //Interrupts
#include <inttypes.h>    //Inttypes der Atmels

//Defines
#define setbit(ADRESSE,BIT) (ADRESSE |= (1<<BIT))  //vereinfachter 
Zugrriff auf ein Bit
#define clearbit(ADRESSE,BIT) (ADRESSE &= ~(1<<BIT))//vereinfachter 
Zugrriff auf ein Bit
#define checkbit(ADRESSE,BIT) (ADRESSE & (1<<BIT))  //vereinfachter 
Zugrriff auf ein Bit



/*********************************************************************** 
*****************************

"delay1ms"
Die Funktion verzögert mit einem 8-Bit Timer um 1ms.
Es sind Verzögerungen bis 65sec möglich => delay(65535)

************************************************************************ 
****************************/

void delay1ms(uint16_t ms)
{
  TCCR0A = 0x00;    //Timer initialisieren (s.S. 110)
  setbit(TCCR0A, CS00);  //Vorteiler: keiner (1)
  ms *= 62;
  while (ms)
     {
          while(!(checkbit(TIFR0, TOV0))){}   //warte solange kein 
Überlauf (TOV0=0), wenn Überlauf (TOV0=1) wird while verlassen
          setbit (TIFR0, TOV0);        //Flag wird durch setbit wieder 
gesetzt (Datenblatt)
          ms--;
     }
}  //Ende der Funktion



void main(void)
{
  DDRC=0xff;    //PORTC ist Ausgang
  DDRF=0x00;    //PORTF ist Eingang
  PORTF=0xff;   //pullups aktivieren für Eingang => 5V an den PINS, zum 
Schalten auf Masse ziehen!

  while(1)
  {
  PORTC=PINF;
  }
}   //Ende main





Hab gerade schon überlegt was es an dem C auszusetzten gibt ;-)
Klar, wenn man die Defines nicht mit postet.

von Karl H. (kbuchegg)


Lesenswert?

Bastler wrote:
> Hier nochmal der komplette Quelltext:
>
>
> //Includes
> #include <avr/io.h>         //Header mit I/O Registern aus WinAVR
> #include <avr/interrupt.h>  //Interrupts
> #include <inttypes.h>    //Inttypes der Atmels
>
> //Defines
> #define setbit(ADRESSE,BIT) (ADRESSE |= (1<<BIT))  //vereinfachter
> Zugrriff auf ein Bit
> #define clearbit(ADRESSE,BIT) (ADRESSE &= ~(1<<BIT))//vereinfachter
> Zugrriff auf ein Bit
> #define checkbit(ADRESSE,BIT) (ADRESSE & (1<<BIT))  //vereinfachter
> Zugrriff auf ein Bit
>
>
>
> /*********************************************************************** 
*****************************
>
> "delay1ms"
> Die Funktion verzögert mit einem 8-Bit Timer um 1ms.
> Es sind Verzögerungen bis 65sec möglich => delay(65535)
>
> ************************************************************************ 
****************************/
>
> void delay1ms(uint16_t ms)
> {
>   TCCR0A = 0x00;    //Timer initialisieren (s.S. 110)
>   setbit(TCCR0A, CS00);  //Vorteiler: keiner (1)
>   ms *= 62;
>   while (ms)
>      {
>           while(!(checkbit(TIFR0, TOV0))){}   //warte solange kein
> Überlauf (TOV0=0), wenn Überlauf (TOV0=1) wird while verlassen
>           setbit (TIFR0, TOV0);        //Flag wird durch setbit wieder
> gesetzt (Datenblatt)
>           ms--;
>      }
> }  //Ende der Funktion
>
>
>
> void main(void)
> {
>   DDRC=0xff;    //PORTC ist Ausgang
>   DDRF=0x00;    //PORTF ist Eingang
>   PORTF=0xff;   //pullups aktivieren für Eingang => 5V an den PINS, zum
> Schalten auf Masse ziehen!
>
>   while(1)
>   {
>   PORTC=PINF;
>   }
> }   //Ende main
>
>
>
>
>
> Hab gerade schon überlegt was es an dem C auszusetzten gibt ;-)
> Klar, wenn man die Defines nicht mit postet.

Ja. Aber daran liegt es nicht mehr. Das einfachst Programm
verwendet das gar nicht mehr

Hmm.

  while(1)
  {
    PORTC = PINF;
  }

Das ist so einfach wie nur was. Das muesste eigentlich
gehen.  Wenn du einen Pin am F Port auf Masse ziehst
muesste sich am C Port was tun.

Hmm
Was ist mit

void main(void)
{
   DDRC=0xff;    //PORTC ist Ausgang
   DDRF=0x00;    //PORTF ist Eingang
   PORTF=0xff;   //pullups aktivieren für Eingang => 5V an den PINS, zum

   while(1)
   {
     PORTC = 0xAA;
   }
}

Jetzt müsste am C Port abwechselnd 1 Led brennen und 1 aus sein.

(mal schauen, ob dein Prozessor überhaupt arbeitet).
Wenn das geht: Probier mal anstelle des F Ports den B Port

void main(void)
{
   DDRC = 0xff;    //PORTC ist Ausgang
   DDRB = 0x00;    //PORTB ist Eingang
   PORTB = 0xff;
   while(1)
   {
     PORTC = PINB;
   }
}


von Walter (Gast)


Lesenswert?

wenn das Einfachprogramm nicht funktioniert, dann ist wohl an der 
Hardware oder am Programmer was faul,
oder du misst Mist?
Kannst du das Programm wieder auslesen bzw. geht verifiy,
hast du an den Fuses geändert?

von Karl H. (kbuchegg)


Lesenswert?

Mega128
Blöde Frage: Die 103-Kompatibilitätsfuse hast du ausgeschaltet?

von Bastler (Gast)


Lesenswert?

Das Programm von Dir läuft.

Das Problem ist schlichtweg, dass die PINF Abfrage immer 0 ergibt...
Wenn man mit einem Multimeter nachmist kommen aber 4,81V raus, was ist 
da los?

Da muß also irgendwas an der Abfrage falsch sein.

von Bastler (Gast)


Lesenswert?

Habs jetzt mal mit PORTE als Eingang versucht.
Da funktioniert alles wie ich mir das vorgstellt habe.

Alle Ports haben ja auch Sonderfunktionen.
Kann es sein das ich PORTF irgendwie nicht mehr als IO Port sondern als 
Sonderfunktionsport eingestellt habe (wie auch immer das gehen mag)?

von Karl H. (kbuchegg)


Lesenswert?

Da bin ich überfragt.
Ich kenn den Mega128 nicht.

Hol dir von Atmel das Dtaenblatt und sieh nach
was am PORTF sonst noch so rumliegt. Wo liegt beim 128
eigentlich das JTAG Interface. So er eines hat,
muss man auch das abschalten.

von Karl H. (kbuchegg)


Lesenswert?

Ja, der hat ein JTAG Interface und rate mal: das liegt am
Port F.

Also: per Fuse abschalten.

von Bastler (Gast)


Lesenswert?

Also:

Wieder was gelernt!

Danke

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.