Forum: Mikrocontroller und Digitale Elektronik LCD an MyAVR Board


von Daniel S. (dave12)


Lesenswert?

Hallo Forum,

Habe ein Problem. ich will das  myAVR LCD-Zusatzgerät, mit dem myAVR 
Mikrocontroller und einem Programm (unten), hochzählen lassen.
Habe nicht viel Ahnung vom Programmieren mit dem AtmelStudio.
Es wird mir beim Überspielen einfach das hochzählen mit dem betätigen 
eines Tasters nicht angezeigt bzw. funktioniert einfach noch nicht 
richtig wie es soll. Kann mir da bitte einer helfen?

Bin echt richtig am verzweifeln..




//---------------------------------------------------------------------- 
----
// Titel    : LCD-Bibliothek
// Funktion    : Beinhaltet Funktionen für die LCD-Anzeige
// Schaltung  : Anschluss über die Leiste
// Prozessor  : ATmega8 mit 3,6864 MHz
// Sprache    : C
// Datum    : 26.01.2011
// Version    : 1.1
// Autor    : Peter Dischinger
//---------------------------------------------------------------------- 
----
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 3686400


//---------------------------------------------------------------------- 
---
//  lcd_enable() - setzt das Enable-Signal für eine Millisekunde auf HI
//  PE:  keine
//  PA:  keine
//---------------------------------------------------------------------- 
---
void lcd_enable()
{
  PORTD = PORTD | 0b00001000;
  _delay_ms(1);
  PORTD = PORTD & ~ 0b00001000;
}


//---------------------------------------------------------------------- 
---
//  lcd_init(..) - Initialisiert das myAVR LCD 16x2, 4 Bit Modus
//  PE:  keine
//  PA:  keine
//---------------------------------------------------------------------- 
---
void lcd_init()
{
  // Port D = Ausgang
  DDRD = 0b11111111;
  PORTD = 0b00000000;
  // muss 3mal hintereinander gesendet werden zur Initialisierung


  _delay_ms(50);
  PORTD = 0b00100000;
  lcd_enable();
  lcd_enable();
  lcd_enable();

  _delay_ms(5);

  lcd_cmd(0b00101000);
  lcd_off();
  lcd_clear();
  lcd_cmd(0b00000110);
  lcd_on();



}


//---------------------------------------------------------------------- 
---
//  lcd_send(..) - sendet ein Byte an LCD im 4-Bit-Modus
//  RS muss vorher richtig gesetzt sein
//  PE:  data=zu sendendes Byte
//---------------------------------------------------------------------- 
---
void lcd_send(char data)
{
  char tmp = data;
  // aktuelles RS ermitteln
  char rs = PORTD;
  rs =rs  & 0b00000100;
  // High-Teil senden
  tmp = tmp & 0b11110000;
  tmp = tmp | rs;
  PORTD = tmp;
  // Schreibsignal
  lcd_enable();
  // Low-Teil senden
  tmp = data;
  tmp = tmp & 0b00001111;
  tmp = tmp * 16;
  tmp = tmp | rs;
  PORTD = tmp;
  // Schreibsignal
  lcd_enable();
  // verarbeiten lassen
  _delay_ms(1);
}


//---------------------------------------------------------------------- 
---
//    lcd_cmd(..) - sendet ein Kommando an LCD
//  PE:  cmd=Kommando-Byte
//---------------------------------------------------------------------- 
---
void lcd_cmd(char cmd)
{
  PORTD = PORTD & ~0b00000100;
  lcd_send(cmd);
}


//---------------------------------------------------------------------- 
---
//    lcd_clear(..) - löscht die Anzeige im LCD
//---------------------------------------------------------------------- 
---
void lcd_clear()
{
  lcd_cmd(0b00000001);
  _delay_ms(2);      // warten
}
//---------------------------------------------------------------------- 
---
//    lcd_home(..) - Cursor auf Position 1,1
//---------------------------------------------------------------------- 
---
void lcd_home()
{
  lcd_cmd(0b00000010);
  _delay_ms(2);      // warten
}


//---------------------------------------------------------------------- 
---
//    lcd_on(..) - Schaltet das LCD an
//---------------------------------------------------------------------- 
---
void lcd_on()
{
  lcd_cmd(0b00001110);
}

//---------------------------------------------------------------------- 
---
//    lcd_off(..) - Schaltet das LCD aus
//---------------------------------------------------------------------- 
---
void lcd_off()
{
  lcd_cmd(0b00001000);
}

//---------------------------------------------------------------------- 
---
//  lcd_goto(..) - setzt die Cursorposition
//  PE:  row = Zeile 1/2
//    col = Spalte 1..16
//---------------------------------------------------------------------- 
---
void lcd_goto(int row, int col)
{
  char tmp;
  row--;        // Null-basierend
  row = row & 0b00000001;      // sicherheitshalber
  row = row * 64;        // Zeile nach Bit 6 bringen
  col--;        // Null-basierend
  col = col & 0b00001111;    // sicherheitshalber
  tmp = row | col;      // Adresse bilden
  tmp = tmp | 0b10000000 ;      // Cursor setzen
  lcd_cmd(tmp);      // setzen
}

//---------------------------------------------------------------------- 
---
//  lcd_light(..) - schaltet die LCD Hintergrundbeleuchtung ein oder aus
//  PE:  on_off=0..1 = Beleuchtung ein- bzw. ausschalten
//---------------------------------------------------------------------- 
---
int lcd_dimmer_is_init=0;
void lcd_light(int on_off)
{
  // wenn dimmer an -> PWM deinit
  if (lcd_dimmer_is_init == 1)
  {
    TCCR1A = 0;
    lcd_dimmer_is_init = 0;
  }
  DDRB |= (1<<1);    // PORTB1 als Ausgang
  if (on_off == 1)
  {
    PORTB |= (1<<1);  // an
    } else {
    PORTB &= ~(1<<1);  // aus
  }
}

//---------------------------------------------------------------------- 
---
//    lcd_dimmer(..) - legt die Helligkeit der Hintergrundbeleuchtung 
fest
//  PE:  light=0..255 Helligkeit der Anzeige
//---------------------------------------------------------------------- 
---
void lcd_dimmer(char light)
{
  // init
  if (lcd_dimmer_is_init == 0)
  {
    DDRB |= (1<<1);    // PORTB1 als Ausgang
    TCCR1A = 0b10000001;      // PWM Mode 1, Channel A
    TCCR1B = (1<<1);      // PWM Frequenz CLK/8
    lcd_dimmer_is_init = 1;
  }
  OCR1A = light;          // PWM Vergleichswert
}

//---------------------------------------------------------------------- 
---
//    lcd_write(..) - sendet ein Zeichen (Daten) an LCD
//  PE:  text=Zeichen
//---------------------------------------------------------------------- 
---
void lcd_write(char text)
{
  PORTD = PORTD | 0b00000100 ;      // RS setzen = Daten
  lcd_send(text);      // senden
}


//---------------------------------------------------------------------- 
---
//    lcd_writeText(..) - sendet einen String (Daten) an LCD
//  PE:  text=Zeichenkette, laenge=Anzahl von Zeichen
//---------------------------------------------------------------------- 
---
void lcd_writeText(char * text, int laenge)
{
  int zaehler;
  for (zaehler = 0; zaehler < laenge; zaehler++)
  {
    lcd_write (text[zaehler]);
  }
}


int main(void)
{
  DDRC &= ~(1 << PB0);
  PORTC &= ~(1 << PB0);

  char Zaehler[16];

  lcd_init();

  lcd_goto(1,1);

    lcd_writeText("Hochzaehlen",11);

  lcd_goto(2,1);
  lcd_writeText("LF1",3);

    _delay_ms(2500);
    lcd_clear();




  while (1)
  {
    int zaehler;
    {

      if (PINC & (1 << PB0))

      {
        Zaehler = Zaehler +1;
      }

      if (Zaehler > 10)
      {
        Zaehler = 0;
      }
      lcd_clear();
      lcd_writeText(Zaehler,1);

    }
  }
}

von Adam P. (adamap)


Lesenswert?

David S. schrieb:
> lcd_writeText(Zaehler,1);

Du übergibst eine Zahl und keinen String!
Du solltest die Zahl erst konvertieren und dann an deine Funktion 
übergeben und die Länge ist dann nicht immer 1.

Die Konvertierung kannst du mit itoa() erledigen.

von Adam P. (adamap)


Lesenswert?

David S. schrieb:
> char Zaehler[16];

David S. schrieb:
> int zaehler;

und das ist so auch kontraproduktiv.

...Da fehlt es an C Grunglagen!

: Bearbeitet durch User
von Daniel S. (dave12)


Lesenswert?

Wäre es so korrekt:

  while (1)
  {
    int zaehler;
    {

      if (PINC & (1 << PC0))
      {
        Zaehler = Zaehler +1;
      }

      if (Zaehler > 10)
      {
        Zaehler = 0;
      }

      for(int i=0; i<=9; i++)
      {
        lcd_clear();
        itoa(i, Zaehler, 10);
       }

    }
  }
}

von Daniel S. (dave12)


Lesenswert?

Adam P. schrieb:
> ...Da fehlt es an C Grunglagen!

Habe bereits erwähnt das ich nicht viel Ahnung habe.

von Adam P. (adamap)


Lesenswert?

Ersetz mal deine main() durch folgendes:
1
int main(void)
2
{
3
  char buf[16];
4
  uint8_t buf_length;
5
  uint32_t counter = 0;
6
  
7
  DDRB &= ~(1 << PB0);
8
  PORTB &= ~(1 << PB0);
9
10
  lcd_init();
11
12
  lcd_goto(1,1);
13
  lcd_writeText("Hochzaehlen",11);
14
15
  lcd_goto(2,1);
16
  lcd_writeText("LF1",3);
17
18
  _delay_ms(2500);
19
  lcd_clear();
20
21
  while (1)
22
  {
23
    if (PINB & (1 << PB0))
24
    {
25
      counter++;
26
      
27
      /* Das ist nicht schön! */
28
      _delay_ms(100);
29
    }
30
31
    if (counter > 10)
32
    {
33
      counter = 0;
34
    }
35
    
36
    itoa(counter, buf, 10);
37
    buf_length = strlen(buf);
38
    
39
    lcd_clear();
40
    lcd_writeText(buf, buf_length);
41
  }
42
}

Du hast bei dir Port C abgefragt, dabei willst du doch PB0, ODER?
Denn dein Init. ist ebenfalls verwirrend:
1
  DDRC &= ~(1 << PB0);
2
  PORTC &= ~(1 << PB0);
Wenn du PB0 willst, dann solltest du auch die define's für Port B 
verwenden: DDRB und PORTB.

Aber eigentlich sollte man es anders lösen,
ein Taster sollte "entprellt" werden, hier sorgt das _delay_ms(100); für 
eine Pseudoentprellung, dazu gibt es hier im Forum mehr als genug zu 
lesen.
Weiterhin würde es ohne delay hier so ablaufen, dass solange du die 
Taste gedrückt hälst, er hochzählen würde...einen Tastendruck müsstest 
du anhand einer Flankenerkennung programmieren.
Aber ich würde dir raten, dich dazu mal selbst einzulesen, dabei lernst 
du am meisten...

P.S.
Bitte füge langen Code als Anhang an und bei kurzen Code Ausschnitten 
die Tags für C-Code Formatierung verwenden:

https://www.mikrocontroller.net/articles/Formatierung_im_Forum

: Bearbeitet durch User
von Daniel S. (dave12)


Lesenswert?

Danke dir das du mir hilfst :)

Sorry will Port C verwenden:

DDRC &= ~(1 << PC0);
PORTC &= ~(1 << PC0);

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.