mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit ATMega16


Autor: daniel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
der AtMega16 gibt am Port C folgendes Bitmuster 00101100 aus. Versteh 
nicht warum. In meinem Program wird am PortC ueberhaupt nix gemacht.

Controller laeuft auf 8 MHz interner RC.
#include <avr/io.h>
#include <d:\projekt\lcdtest\T6963.h>

char string[10] = "Test";
unsigned char LCD_CMD;          // Command-Byte
unsigned char LCD_STATUS;       // Status-Byte
unsigned char LCD_DATA;         // Daten-Byte
char state;

int main()
{
  DDRD |= 0x08;
  state = 0;
  while (1)
  {
  PORTD = 0x08;
  LCD_CTRL_DDR |= 0x0F;
        DATA_DIR_IN();          // Port A als Eingang
        LCD_CD_H();             // Commando High
        LCD_RD_L();             // Read Low
        LCD_CE_L();             // Chip Enable Low
        LCD_STATUS = LCD_READ;  // Status lesen
        LCD_CE_H();             // Chip Enable High
        LCD_RD_H();             // Read High
        LCD_STATUS &= (0x03);   // Bits ausmaskieren

  }
  return 0;
}

t6963.h:

#define LCD_CTRL  PORTB              // Steuerport LCD
#define LCD_CTRL_DDR   DDRB          // Data Direction of Control Port

#define LCD_WR_H()     LCD_CTRL |=  _BV(LCD_WR)  // = 1
#define LCD_WR_L()      LCD_CTRL &= ~_BV(LCD_WR)  // = 0
#define LCD_RD_H()     LCD_CTRL |=  _BV(LCD_RD)
#define LCD_RD_L()      LCD_CTRL &= ~_BV(LCD_RD)
#define LCD_CE_H()     LCD_CTRL |=  _BV(LCD_CE)
#define LCD_CE_L()      LCD_CTRL &= ~_BV(LCD_CE)
#define LCD_CD_H()     LCD_CTRL |=  _BV(LCD_CD)
#define LCD_CD_L()      LCD_CTRL &= ~_BV(LCD_CD)
#define LCD_RST_H()     LCD_CTRL |=  _BV(LCD_RST)
#define LCD_RST_L()      LCD_CTRL &= ~_BV(LCD_RST)
an PD3 haengt eine LED die auch leuchtet. muesste heissen der macht 
schon was. nur was?

ausserdem habe ich eine externe Beschaltung der Pins um beim Tasterdruck 
einen positiven Pegel zu erzeugen. siehe Schematic.
Vielleicht kann mir jemand sagen wo das Problem liegen koennte, 
vielleicht hat auch der Controller ein Schuss weg.

Vielen Dank
Daniel

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JTAG abschalten!

Autor: mehrfacher STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guck mal nach der JTAG-Fuse!

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daran kanns wohl liegen :)
die war noch an, wusste aber auch nicht ob es noetig ist die 
auszuschalten. Vielen Dank fuer die schnellen Antworten.
steh nun bei der testung mit den eingaengen, funzt aber auch nicht so 
richtig. Moechte die als Tristate Hi-Z verwenden.
int main()
{
  DDRD |= 0x08; // LED PD3 output
  PORTD = 0x0B; // PD0..PD1 input tristate PD3, PD3 on - LED an
  state = 0;
  while (1)
       {
.
. selbe wie oben
.
        if ((PORTD & 0x01)== 0x01) PORTD = 0x08;
  if ((PORTD & 0x02)== 0x02) PORTD = 0x00;
  }
  return 0;
}
die Tasten generieren VCC über 100 Ohm zum Portpin vom Pin mit 10k gegen 
Masse. Entprellt muessen die nicht sein, geht ja nur um an oder aus.
LED will aber nicht ausgehen.
Weiss da jemand Rat?

Vielen Dank
Daniel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> die Tasten generieren VCC über 100 Ohm zum Portpin vom Pin mit 10k gegen
> Masse.

Hä?
Kannst du das mal aufmalen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
>> die Tasten generieren VCC über 100 Ohm zum Portpin vom Pin mit 10k gegen
>> Masse.
>
> Hä?
> Kannst du das mal aufmalen?

Seh gerade, dass du im Eröffnungsposting einen Schaltplan
hast.

Wenn du die Widerstände drinnen lässt, solltest du die
internen Pull Up Widerstände nicht einschalten. Der interne
Pullup bildet sonst mit dem externen 10k Widerstand einen
Spannungsteiler, so dass dein Pin niemals auf GND runterfallen
kann.

Einfacher wäre es aber, wenn du die externen Widerstände
einfach rausschmeist, du brauchst sie nicht.

Einen Taster kann man ganz einfach so anschliessen:



    PD0 o-------------+
                      |
                    \
                     \
                      |
          ------------+-------o  GND

Den internen Pullup an diesem Pin aktivieren. Fertig.
Die Taster sind dann allerdings low-aktiv. Im nicht gedrückten
Zustand kriegst du eine 1, wird der Taster gedrückt kriegst
du eine 0

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Pullup duerfte aber nicht aktiv sein, wenn DDRD0:1 = 0 und PORTD0:1 
= 0. Somit waeren laut Datenblatt S. 52 die Pins im Tristate Hi - Z 
Mode.
Werds mal probieren. Muesste doch dann endlich die LED ausgehen bei PD2 
= 1 laut programm.

naja ich mache mir sorgen wegen den Stoereinkoplungen dachte mir 
vielleicht ist so eine Beschaltung besser. Ich weiss das man low aktive 
Taste über Pull-Up leichter verwenden kann. Aber ich habe so leitungen 
von 30 cm und weiss nicht wie das mit Störeinkopplungen sein wird.


vielen Dank
DAniel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daniel wrote:
> Der Pullup duerfte aber nicht aktiv sein, wenn DDRD0:1 = 0 und PORTD0:1
> = 0. Somit waeren laut Datenblatt S. 52 die Pins im Tristate Hi - Z
> Mode.

Moment.

Du setzt

  DDRD |= 0x08;

also  00001000
also PD0 und PD1 auf Eingang

  PORTD = 0x0B;

0x0B ist binär  00001011

Doch. Die Pullups an PD0 und PD1 sind aktiv

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
funktioniert aber trotzdem nicht, naja sicher mein Fehler :)

hier das funktioniert wunderschoen. Klassischer Polling Loop ohne Timer. 
:)
void Init()
{
  // Port definitions
  SFIOR |= 0x00;  // PullUps on
  PORTD = 0x03; // Tristate PD0..PD1
  DDRD = 0x08;  // Output PD3
  PORTD = 0x08;
  DDRA = 0xFF;

  // Timer Init
  

  // Variable Inits
  cntr = 65535;
}


int main()
{
  Init();
  while (1)
  {
  while (cntr) cntr--;
  cntr = 65535;
  PORTA ^= _BV(PA3);
  if (Taste1) {
  PORTD = 0x00; State = 0;}
  if (Taste2) 
  {
  State = 1; PORTD = 0x08;
  }
  }
  return 0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daniel wrote:

> naja ich mache mir sorgen wegen den Stoereinkoplungen

Brauchst du nicht.
Der Eingang ist ja niemals offen. Er ist entweder über den Taster
direkt mit GND verbunden oder über den internen Pullup mit Vcc.
Ergo: Du hast immer ein definiertes Potential, egal ob der Taster
geöffnet oder geschlossen ist.

Was anderes wäre es, wenn du den Pullup wegschaltest. Dann wäre
der Eingang bei nicht gedrücktem Taster tatsächlich offen und
du müsstest dir Sorgen um Störungen machen.

> vielleicht ist so eine Beschaltung besser. Ich weiss das man low aktive
> Taste über Pull-Up leichter verwenden kann. Aber ich habe so leitungen
> von 30 cm und weiss nicht wie das mit Störeinkopplungen sein wird.

30 cm sind kein Problem.
Einfach Taster drann, internen Pullup ein und loslegen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 1)   PORTD = 0x03; // Tristate PD0..PD1
> 2)   DDRD = 0x08;  // Output PD3
> 3)   PORTD = 0x08;

In Zeile 1) schaltest du die Pullups ein.
In 2) schaltest du den einen Portpin auf Ausgang
in Zeile 3) schaltest du die Pullups wieder aus.


Jede Zuweisung an PORTB muss berücksichtigen, dass die
Bits 0 und 1 auf 1 sein muessen.

Du kannst Probleme vermeiden, indem du das Setzen eines
Bits an einem Port so machst:

   PORTB |= 0x08;

und demenstprechend ein einzelnes Bit löschen:

   PORTB &= ~0x08;

oder noch besser (da klarer wird, welches Bit ein oder
ausgeschaltet wird:

  PORTB |= ( 1 << PB3 );   // setze PB3
  PORTB &= ~( 1 << PB3 );  // lösche PB3

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
trickreich :) so geht aber :)
int main()
{
  PORTD = 0x03;   // Tristate aktiv
  DDRD  = 0x08;   // output
  PORTD = 0x08;   // output aktiv, tristate aktiv
  PORTA = 0xFF;   // tristate aktiv
  DDRA = 0x00;    // output
  PORTA = 0x00;   // tristate aktiv
  state = 0;
  while (1)
  {
      LCD_STATUS = 0;
      LCD_CTRL_DDR |= 0x0F;
        DATA_DIR_IN();          // Port A als Eingang
        LCD_CD_H();             // Commando High
        LCD_RD_L();             // Read Low
        LCD_CE_L();             // Chip Enable Low
        LCD_STATUS = LCD_READ;  // Status lesen
        LCD_CE_H();             // Chip Enable High
        LCD_RD_H();             // Read High
        LCD_STATUS &= (0x03);   // Bits ausmaskieren
      if ((PORTD & 0x01)== 0x01) PORTD = 0x08;
      if ((PORTD & 0x02)== 0x02) PORTD = 0x00;
      if (LCD_STATUS == 3) PORTD = 0x08;
  }
  return 0;
}

Vielen dank, kann nun endlich loslegen mit hoeherem wo die Grundlagen 
geklaert sind ;)
Daniel

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank fuer die Tips, hatte den Post noch nicht endeckt.
Du machst das echt super hier Karl Heinz Buchegger! Dickes Lob von mir. 
Hatte hier schon einige Threads und du hast mir immer gute Tips gegeben.
Danke :)

Daniel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
??Verwirrt??
Inzwischen weiss ich nicht mehr, welches Programm denn
nun gilt und welches Probleme macht.

Also:
Gehen wir mal von der Situation aus:
Taster sind ohne irgendwelche Widerstände direkt an
den Prozessorpins am Port D angeschlossen.
Taster D0
Taster D0
Led    D3   (Led ist über Widerstand nach Vcc geschaltet.

Dann folgendes Proramm:

#include <avr/io.h>

int main()
{
  DDRD  = 0x08;    // PD3 auf Ausgang, alles andere auf Eingang
  PORTD = 0x0B;    // PD3 auf 1, Pullup an PD0 und PD1 ein

  while( 1 ) {

    if( ( PIND & 0x01 ) == 0x01 ) {    // PD0 gedrückt?
      PORTD &= ~( 1 << PD3 );          // Led ein (PD3 auf 0)
    }

    if( ( PIND & 0x02 ) == 0x02 ) {    // PD1 gedrückt?
      PORTD |= ( 1 << PD3 );           // Led aus (PD3 auf 1)
    }
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die externen Widerstände noch drann?

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und noch ein Fehler entdeckt, natuerlich werden die Tasten ja nie 
eingelesen kann man druecken wie man will. die Info steht am im PIND 
nicht im PORTD?!
nur so zur Info, fuer die die verstehen wollen was man alles fuer 
Fehlerchen machen kann.
Daniel

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja die sind noch dran, hab hier keine Loetkolben. aber geht ja auch mit 
wenn ich das mit dem Pull Up beachte.

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja das sind alles die Vorbetrachtungen zur Ansteuerung eines 
Grafikdisplay (T6963), aber da muss das mit den In/Outs erstmal 
knallhart sitzen. Deswegen die fielen verschiedenen Programme.
Es sind zwei Programmchen, bei dem einem wirken nur beide Taste und die 
LED.
Bei dem anderen wird das Statuswort am PINA des Displays abgefragt,die 
Comands werden am PORTB0..3 gesendet. Die LED leuchtet dauerhaft, ist 
das Statuswort korrekt soll die LED ausgehen.Taster wirken nur zur 
kontroller und  steuerung der LED auf AN/AUS. Leiderns geht die LED nie 
aus, das Statuswort (0x03)kommt nie an. Aber das hat sicher andere 
Ursachen, wichtiger erst mal das mit den Input Outputs verstehen.
Prog1
void Init()
{
  // Port definitions
  SFIOR |= 0x00;  // PullUps on
  PORTD = 0x03; // Tristate PD0..PD1
  DDRD = 0x08;  // Output PD3
  PORTD = 0x08;
  DDRA = 0xFF;

  // Timer Init
  

  // Variable Inits
  cntr = 65535;
}


int main()
{
  Init();
  while (1)
  {
  while (cntr) cntr--;
  cntr = 65535;
  // PORTA ^= _BV(PA3);
  if (Taste1) 
    {
      PORTD = 0x00; State = 0;
    }
  if (Taste2) 
    {
      State = 1; PORTD = 0x08;
    }
  }
  return 0;
}

Prog2
//PORTA ist der Datenport
#define DATA_DIR_IN()  DDRA =0x00;
#define DATA_DIR_OUT() DDRA =0xFF;
#define LCD_READ   PINA              // read PINC, ! NOT ! PORTC
#define LCD_WRITE  PORTA            //PORTB=(a); // write to data port

#define LCD_WR    1                // LCD_WRITE
#define LCD_RD    2                // LCD_READ
#define LCD_CE    3                // LCD_CS
#define LCD_CD    0                // LCD_COMMAND/DATA
#define LCD_RST  4                // LCD_RESET

#define LCD_CTRL  PORTB              // Steuerport LCD
#define LCD_CTRL_DDR   DDRB          // Data Direction of Control Port

#define LCD_WR_H()     LCD_CTRL |=  _BV(LCD_WR)  // = 1
#define LCD_WR_L()      LCD_CTRL &= ~_BV(LCD_WR)  // = 0
#define LCD_RD_H()     LCD_CTRL |=  _BV(LCD_RD)
#define LCD_RD_L()      LCD_CTRL &= ~_BV(LCD_RD)
#define LCD_CE_H()     LCD_CTRL |=  _BV(LCD_CE)
#define LCD_CE_L()      LCD_CTRL &= ~_BV(LCD_CE)
#define LCD_CD_H()     LCD_CTRL |=  _BV(LCD_CD)
#define LCD_CD_L()      LCD_CTRL &= ~_BV(LCD_CD)
#define LCD_RST_H()     LCD_CTRL |=  _BV(LCD_RST)
#define LCD_RST_L()      LCD_CTRL &= ~_BV(LCD_RST)
int main()
{
  PORTD = 0x03;   // Tristate aktiv
  DDRD  = 0x08;   // output
  PORTD = 0x08;   // output aktiv, tristate aktiv
  PORTA = 0xFF;   // tristate aktiv
  DDRA = 0x00;    // output
  PORTA = 0x00;   // tristate aktiv
  LCD_CTRL |= (1 << PB0 && 1<< PB1 && 1<< PB2 && 1<<PB3); 
  cntr = 10000;
  while (1)
  {
      while (cntr) cntr--;
      cntr = 10000;
      LCD_STATUS = 0;
      LCD_CTRL_DDR |= 0x0F;
        DATA_DIR_IN();          // Port A als Eingang
        LCD_CD_H();             // Commando High
        LCD_RD_L();             // Read Low
        LCD_CE_L();             // Chip Enable Low
        LCD_STATUS = LCD_READ;  // Status lesen
        LCD_CE_H();             // Chip Enable High
        LCD_RD_H();             // Read High
        LCD_STATUS &= (0x03);   // Bits ausmaskieren
      if ((PIND & 0x01)== 0x01) PORTD = 0x08;
      if ((PIND & 0x02)== 0x02) PORTD = 0x00;
      if (LCD_STATUS == 3) PORTD = 0x08;
  }
  return 0;
}

der Code wird langsam unuebersichtlich.  :)
daniel

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
daniel wrote:
> ja die sind noch dran, hab hier keine Loetkolben. aber geht ja auch mit
> wenn ich das mit dem Pull Up beachte.

Ja, klar.

:-)
Wenn du keine externen Widerstände hättest, wäre das hier

if ((PORTD & 0x01)== 0x01) PORTD = 0x08;

ein Problem, weil du dadurch ja die Pullups abschalten würdest.
Da du aber externe Pulldown Widerstände benutzt, ist das ok.

Du solltest dir aber trotzdem angewöhnen, immer nur das Bit an
einem Port zu beeinflussen, das du haben möchtest.
Irgendwann hast du nämlich an einem Port mehrere Ausgänge in
Benutzung, (zb. 2 LEDs) und dann wird so eine einfache
Zuweisung fatal.

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fehlerkorrektur
Prog1 Zusatz
#define Taste1    (PIND & 0x01)
#define  Taste2    (PIND & 0x02)

Prog2 Korrektur
if (LCD_STATUS == 3) PORTD = 0x08; --> if (LCD_STATUS == 3) PORTD = 0x00; // LED aus

daniel

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sas mit den bitgerechten Zuweisung hab ich mir jetzt angewoehnt, bei 
groesseren Programmen hat man dann wirklich grosse Probleme wenn man es 
nicht so macht.
So die In/Outs funktionieren :) jetzt muss ich das nur noch mit dem 
Timing der LCD loesen. aber dafuer vielleicht ein neuer Thread.
Ich weiss es gibt schon fertige Funktionen, aber die benutzen alle den 
Resetpin noch zusaetzlich, leiderns hab ich fuer diesen keine freien Pin 
mehr und das LCD und der uC teilen sich einen gemeinsamen reset.

daniel

Autor: Lötlackl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

geht, wie weiter oben schon erwähnt, noch, hmmm, eleganter.
#define Taste1    (PIND & 1<<PD0)
#define  Taste2    (PIND & 1<<PD1)
Naja, gibt's noch mehrere Varianten (statt 1<<PD0 _BV(PD0) usw.) ist 
aber Geschmackssache.

mfg Lötlackl

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.