Forum: Mikrocontroller und Digitale Elektronik Warum geht das nicht ?


von Michael H. (h_m)


Angehängte Dateien:

Lesenswert?

Guten Abend,

ich habe ein Projekt aus einem Buch mit einem Atmega32a. Es scheint auch 
soweit zu funktionieren, aber kann die Ausgabe am display nicht sehen.

ich bin der Meinung das ich alles richtig angeschlossen habe. Und den 
Kontrast habe ich auch schon verstellt.

das einzige das ich mir vorstellen kann ist das bei der 
"LCD_display_on_Port_C.h" oder in der main.c irgendetwas falsch ist.

kann mir bitte jemand weiterhelfen warum mir mein display keinen Wert 
bzw. anzeigt?


"LCD_display_on_Port_C.h"
1
// LCD Output for HD44780 compatible displays
2
// target: ATmega32
3
// for LCD control commands see LCD data sheet
4
5
#define LCD_CLEAR    0x01  // clear display     0b 0000 0001
6
#define LCD_HOME    0x02  // cursor home      0b 0000 0010
7
#define LCD_ON      0x0C  // cursor invisible    0b 0000 1100
8
#define LCD_OFF      0x08  // display off      0b 0000 1000
9
#define POS_01      0x80  // line 1 - column 0  0b 1000 0000
10
#define POS_02      0xC0  // line 2 - column 0  0b 1100 0000
11
12
#define  LCDPORT      PORTC  // define port with LCD attached
13
#define  LCDDDR      DDRC  // and its data direction
14
15
// define pins of LCD port
16
#define LCD_PIN_RS    2    
17
#define LCD_PIN_E    3
18
#define LCD_PIN_D4    4
19
#define LCD_PIN_D5    5
20
#define LCD_PIN_D6    6
21
#define LCD_PIN_D7    7
22
23
// DEFINITIONS
24
#define sbi(PORT, bit)     (PORT|=(1<<bit))  // set bit        
25
#define cbi(PORT, bit)     (PORT&=~(1<<bit))  // claear bit
26
#define tbi(PORT, bit)     (PORT^=(1<<bit))  // toggle bit
27
28
#define  COMMAND      0
29
#define DATA      1
30
31
// Function: Toggle enable pin 
32
void toggle_enable_pin(void)
33
{
34
  sbi(LCDPORT, LCD_PIN_E);
35
  cbi(LCDPORT, LCD_PIN_E);  
36
}
37
38
// Send Byte to LCD Controller
39
void lcd_send(unsigned char type, unsigned char c)
40
{
41
  unsigned char sic_c;          // Backup for c
42
  // send high nibble
43
  sic_c = c;                // save original c
44
  sic_c &= ~0x0f;              // set bit 0-3 == 0
45
  if (type==DATA)
46
    sic_c |= (1<<LCD_PIN_RS);      // Data: RS = 1
47
  LCDPORT = sic_c;            // send high nibble
48
  toggle_enable_pin();
49
  // send low nibble
50
  sic_c = c;                // save original c
51
  sic_c = sic_c<<4;            // exchange nibbles
52
  sic_c &= ~0x0f;              // set bit 0-3 == 0
53
  if (type==DATA)
54
    sic_c |= (1<<LCD_PIN_RS);      // Data: RS = 1
55
  LCDPORT = sic_c;            // send low nibble
56
  toggle_enable_pin();
57
  _delay_ms(5);              // Wait for LCD controller
58
}
59
60
// set cursor to line x and column y
61
void lcd_set_cursor(uint8_t x, uint8_t y)
62
{
63
  uint8_t i;
64
 
65
  switch (x) 
66
  {
67
    case 1: i=0x80+0x00+y; break;    // 1. line
68
    case 2: i=0x80+0x40+y; break;    // 2. line
69
    default: return;                   // invalid line
70
  }
71
  lcd_send(COMMAND, i);
72
}
73
74
// Display String on LCD
75
void lcd_write(char *t)
76
{
77
  unsigned char i;
78
  for (i=0;i<255;i++)
79
  {
80
    if (t[i]==0) // End of String -> EXIT
81
      return;
82
    else 
83
      lcd_send(DATA, t[i]);
84
  }
85
}
86
87
88
// initializing LCD Controller see data sheet for details
89
void lcd_init()
90
{
91
  // Set LCD port to Output
92
  LCDPORT = 0x00;
93
  LCDDDR  = 0xFF;
94
95
  _delay_ms(50); // wait for LCD
96
97
  // 4-bit Modus config
98
  sbi(LCDPORT, LCD_PIN_D5);
99
  cbi(LCDPORT, LCD_PIN_D4);
100
101
  // 4-Bit mode start 
102
  sbi(LCDPORT, LCD_PIN_E);
103
  cbi(LCDPORT, LCD_PIN_E);
104
  _delay_ms(5); 
105
106
  // 2 Lines, 4-Bit Mode
107
  lcd_send(COMMAND, 0x28);
108
109
  lcd_send(COMMAND, LCD_OFF);
110
  lcd_send(COMMAND, LCD_CLEAR);
111
112
  lcd_send(COMMAND, 0x06);
113
  lcd_send(COMMAND, LCD_ON);
114
}

main.c
1
// velocity measurement - target ATmega32
2
3
#define XTAL      8e6
4
#define F_CPU      XTAL
5
6
#define DIST      0.06    // sensor distance in m
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <stdlib.h>
11
#include <util/delay.h>
12
13
#include "BitUtilities.h"
14
#include "LCD_display_on_Port_C.h"
15
16
volatile double     sec  = 0;
17
volatile unsigned char   run  = 0;  // 0 = stop, 1 = run
18
volatile unsigned int   ctr  = 0;  // counter latch
19
char t[8];              // text for LCD display
20
21
ISR (TIMER1_COMPA_vect)    // Compare Match
22
{  if (run) {run = 0; ctr =1; sec = 100;}
23
}
24
25
ISR (TIMER1_CAPT_vect)     // Capture Event
26
{  if (run) {ctr = ICR1; sec = ctr/(F_CPU/256.0); run = 0;}
27
else {sbi(PORTB, 0); TCNT1 = 0; run = 1;}
28
}
29
30
int main()
31
{  lcd_init();  lcd_write ("km/h  01"); _delay_ms(999);
32
  lcd_send(COMMAND, LCD_CLEAR); lcd_set_cursor(1, 7); lcd_write ("0");
33
  lcd_set_cursor(2, 0); lcd_write (" km/h");
34
  DDRB = 0b00000001;    // port for run indicator LED
35
36
  TIMSK |= (1<<TICIE1) | (1<<OCIE1A);  // input capture & compare match
37
  OCR1A = F_CPU/128;          // compare for 2 sec
38
  TCCR1B |= (1<<WGM12) | (1 << CS12);  // CTC mode & Prescaler = 1/256
39
  sei();
40
41
  while (1)
42
  {  if (ctr)
43
    {  cbi(PORTB, 0);
44
      lcd_set_cursor(1, 0); dtostrf ((3.6*DIST/sec), 8, 2, t); lcd_write (t);
45
      ctr = 0;
46
    }
47
  }
48
}


  

von ??? (Gast)


Lesenswert?

Schon mal Inder errata nachgeschaut?

von ??? (Gast)


Lesenswert?

Beschreibe doch mal in Prosa wie die Schaltung funktionieren soll.

von ??? (Gast)


Lesenswert?

Also nicht das Programm ist gemeint.

von No Y. (noy)


Lesenswert?

Also auf dem obersten Bild ist der Kontrast schonmal falsch..
Der muss so sein das du gerade keine schwarzen Kästchen mehr siehst.

von mitlesa (Gast)


Lesenswert?

Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.
Ich muss bei jedem IC ein Abblock-C von VCC nach GND anschliessen.

von H. H. (Gast)


Lesenswert?

No Y. schrieb:
> Also auf dem obersten Bild ist der Kontrast schonmal falsch..
> Der muss so sein das du gerade keine schwarzen Kästchen mehr siehst.

Ach wo, der Kontrast stimmt, aber das Display wird nicht initialisiert.

von Michael H. (h_m)


Lesenswert?

No Y. schrieb:
> Also auf dem obersten Bild ist der Kontrast schonmal falsch..
> Der muss so sein das du gerade keine schwarzen Kästchen mehr siehst.

Ja. Ich hab schon verstellt. Das zeigt nicht an.

Ich weiß nicht genau was mit errata gemeint ist. Kann das sein das ich 
die falschen fuse bit für den externen quarz eingestellt habe?

von mitlesa (Gast)


Lesenswert?

- AVcc gehört auch an Vcc angeschlossen. Inklusive extra Abblock-C.

- Quarz-Lastkapazitäten gehören an den Masse-Pin des Controllers
angeschlossen, nicht irgendwo an Masse.

- Reset gehört auch definiert beschaltet.

Wer solch eine Anleitung schreibt gehört schon ausgepeitscht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Michael H. schrieb:
1
void lcd_init()
2
{
3
  // Set LCD port to Output
4
  LCDPORT = 0x00;
5
  LCDDDR  = 0xFF;
6
  _delay_ms(50); // wait for LCD
7
  // 4-bit Modus config
8
  sbi(LCDPORT, LCD_PIN_D5);
9
  cbi(LCDPORT, LCD_PIN_D4);
10
  // 4-Bit mode start
11
  sbi(LCDPORT, LCD_PIN_E);
12
  cbi(LCDPORT, LCD_PIN_E);
13
  _delay_ms(5);
14
  // 2 Lines, 4-Bit Mode
15
  lcd_send(COMMAND, 0x28);
16
  lcd_send(COMMAND, LCD_OFF);
17
  lcd_send(COMMAND, LCD_CLEAR);
18
  lcd_send(COMMAND, 0x06);
19
  lcd_send(COMMAND, LCD_ON);
20
}

Hmm. Bei mir sieht die HD44780-Initialisierung so aus:
1
/*
2
 * Function set.  if8bit selects an 8-bit data path, twoline arranges
3
 * for a two-line display, font5x10 selects the 5x10 dot font (5x8
4
 * dots if clear).
5
 */
6
#define HD44780_FNSET(if8bit, twoline, font5x10) \
7
  (0x20 | ((if8bit)? 0x10: 0) | ((twoline)? 0x08: 0) | \
8
    ((font5x10)? 0x04: 0))
9
/*
10
 * Selects disp[lay] on/off, cursor on/off, cursor blink[ing]
11
 * on/off.
12
 */
13
#define HD44780_DISPCTL(disp, cursor, blink) \
14
  (0x08 | ((disp)? 0x04: 0) | ((cursor)? 0x02: 0) | ((blink)? 1: 0))
15
16
hd44780_init(void)
17
{
18
  SET(DDR, HD44780_RS);
19
  SET(DDR, HD44780_RW);
20
  SET(DDR, HD44780_E);
21
  ASSIGN(DDR, HD44780_D4, 0x0F);
22
23
  _delay_ms(15);    /* 40 ms needed for Vcc = 2.7 V */
24
  hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
25
  _delay_ms(4.1);
26
  hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
27
  _delay_ms(0.1);
28
  hd44780_outnibble(HD44780_FNSET(1, 0, 0) >> 4, 0);
29
  _delay_us(37);
30
31
  hd44780_outnibble(HD44780_FNSET(0, 1, 0) >> 4, 0);
32
  hd44780_wait_ready(false);
33
  hd44780_outcmd(HD44780_FNSET(0, 1, 0));
34
  hd44780_wait_ready(false);
35
  hd44780_outcmd(HD44780_DISPCTL(0, 0, 0));
36
  hd44780_wait_ready(false);
37
}

Ich bilde mir ein, dass diese Folge so im Datenblatt gefordert wird – 
beachte die Delays. Auch das hier:
1
void toggle_enable_pin(void)
2
{
3
  sbi(LCDPORT, LCD_PIN_E);
4
  cbi(LCDPORT, LCD_PIN_E);  
5
}

kann eventuell nicht mehr Datenblatt-konform sein, bei mir steht da ein 
_delay_us(0.5) dazwischen. Falls dein Controller mit 1 MHz getaktet 
wird, wäre es wohl OK so. Hast du nicht geschrieben. Falls du 
tatsächlich mit den 8 MHz vom Quarz fährst, ist das aber so auf jeden 
Fall zu schnell.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Jörg W. schrieb:
> Ich bilde mir ein, dass diese Folge so im Datenblatt gefordert wird –
> beachte die Delays.

Hier die Datenblattseite.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Michael H. schrieb:

> ich bin der Meinung das ich alles richtig angeschlossen habe. Und den
> Kontrast habe ich auch schon verstellt.

JTAGEN Fuse deaktiviert?

Grüßle
Volker

: Bearbeitet durch User
von Pete K. (pete77)


Lesenswert?

Quarz-Thema: F_CPU gesetzt?
Lass mal eine LED für 1 Sekunde leuchten, dann weisst Du, ob der Quarz 
richtig schwingt.

von Ingolf G. (Gast)


Lesenswert?

Habe genau das Gleiche mal vor Jahren aufgebaut, gleiches Buch.
Hat funktioniert.
Aber erst nachdem ich durch eine Kontroll-LED, die im Sekundentakt 
blinken sollte, sah das ich den internen Takt falsch eingestellt hatte. 
:-/

Ups, etwas zu spät   :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Volker B. schrieb:
> JTAGEN Fuse deaktiviert?

Innerhalb der zeitlichen Randbedingung JTD setzen sollte genauso 
funktionieren.

Aber natürlich ein sehr guter Einwand!

Ist auch nicht völlig klar, warum man sich an einem Controller mit 
vielen ungenutzten Pins für das LCD ausgerechnet die aussuchen muss, die 
ohne Fuse-Umkonfiguration nicht benutzbar sind.

von mitlesa (Gast)


Lesenswert?

Volker B. schrieb:
> JTAGEN Fuse dekativiert?

Frage mich schon die ganze Zeit wie er seinen Controller
programmiert, aber da ist ja SPI angeschlossen. Nur reicht
das vermutlich nicht da für ISP auch der Reset betätigt
werden muss.

von mitlesa (Gast)


Lesenswert?

Ingolf G. schrieb:
> Habe genau das Gleiche mal vor Jahren aufgebaut, gleiches Buch.

In diesem Buch steht sicher noch mehr Schrott drin.

von mitlesa (Gast)


Lesenswert?

??? schrieb:
> Beschreibe doch mal in Prosa wie die Schaltung funktionieren soll.

Ich kenne den Namen des TO aus ein paar früheren Threads (gut
ein paar Monate oder sogar mehr als ein Jahr her) in denen schon
mal mit dem Kopf geschüttelt werden durfte.

Typische Vorgehensweise:

- Problem in den Raum gestellt. "Warum"-Frage.
- kaum oder keine Reaktion auf Bemerkungen seitens der Leser.
- kein oder wenig Verständnis für die Problempunkte die
von den Lesern erwähnt werden.
- Reaktionszeit lang bis unendlich.

Schliesslich bleibt das Gefühl der TO dreht sich im Kreis und
ist mit dem "Projekt" und den Problem-Lösungsvorschlägen überfordert.

von Rudi D. (rulixa)


Lesenswert?

Jörg W. schrieb:
> Jörg W. schrieb:
>> Ich bilde mir ein, dass diese Folge so im Datenblatt gefordert wird –
>> beachte die Delays.
>
> Hier die Datenblattseite.

Ist zwar in Assembler, funktioniert ausgezeichnet. Wichtig sind die 
delays als auch die Umschaltung auf 4 bit Ansteuerung. Pinning und clock 
als o.k. angenommen.
1
;Init the LCD an PortB entsprechend TC1602A_Manual.pdf
2
;als auch *******AD9850 DDRB, PB6 = FR_UD und PB7 = W_CLK********
3
lcd_init:
4
    ldi    C,$FF        ;PortB alle auf Output Seite50
5
    out    DDRB,C
6
    out    PortB,C        ;definierter Status fürs Display
7
    ldi    B,100        ;n x 2ms delay
8
wait_display:            ;t2313 ist fertg, display auch
9
    rcall delay2ms        ;lass alles zur Ruhe kommen
10
    dec   B
11
    brne  wait_display
12
13
; Display DB [7:4] liegt auf PortB [3:0]
14
; sonst könnte man nicht RS = PB5,  Enable = PB4 
15
; im 4 bit mode vom PortB aus bedienen
16
    ldi   C,0b00000011  ;8bit mode, 
17
    out   LCD_PORTB, C  ;
18
    rcall lcd_enable  ;1,  
19
    rcall delay2ms
20
    rcall delay2ms
21
    rcall lcd_enable  ;2
22
    rcall delay2ms
23
    rcall lcd_enable  ;3
24
    rcall delay2ms    ;Display ist jetzt eindeutig im 8bit mode
25
26
;LCD: function set 
27
    ldi   C,0b00000010;4bit-Mode, noch im 8 bit mode gesendet
28
    out   LCD_PORTB, C
29
    rcall lcd_enable    
30
    rcall delay2ms    ;Display ist jetzt im 4bit mode  
31
        
32
; ab nun kann das Byte jeden Wert haben, da es in 2 nibbles aufgeteilt
33
; wird, die via PB[3:0] kommend, an das Display DB[7:4] gelangen.

von mitlesa (Gast)


Lesenswert?

Rudi D. schrieb:
> Ist zwar in Assembler, funktioniert ausgezeichnet.

Sehr gut! Und sehr hilfreich für jemanden der kaum selbst
einen Dreizeiler in C zustande bringt sondern sich mit
Copy&Paste Vorlagen behelfen muss.

von Rudi D. (rulixa)


Lesenswert?

mitlesa schrieb:
> Rudi D. schrieb:
>> Ist zwar in Assembler, funktioniert ausgezeichnet.
>
> Sehr gut! Und sehr hilfreich für jemanden der kaum selbst
> einen Dreizeiler in C zustande bringt sondern sich mit
> Copy&Paste Vorlagen behelfen muss.

ldc_enable fehlt noch:
1
;create  enable pulse 5 cycles auf 1 macht 0,75 us ändert kein Register
2
;mit fallender Flanke werden Daten übernommen
3
lcd_enable:
4
       sbi LCD_PORTB, PIN_E         ;2; Enable high
5
       nop
6
       nop
7
       nop
8
       cbi LCD_PORTB, PIN_E         ;2; Enable low
9
     rcall  delay50us    ;ab H>L Enable braucht das Display 38 us
10
     ret        ;bis es wieder bereit ist

von mitlesa (Gast)


Lesenswert?

Rudi D. schrieb:
> ldc_enable fehlt noch:

Didaktisch überaus überzeugend.

von Michael H. (h_m)


Lesenswert?

Pete K. schrieb:
> Quarz-Thema: F_CPU gesetzt?
> Lass mal eine LED für 1 Sekunde leuchten, dann weisst Du, ob der Quarz
> richtig schwingt.

Also, der Takt Stimmt wohl mit 8 Mhz mit externen Quarz, wie im Code 
oben eingestellt. Habe eine LED im Sekunden Takt blinken lassen und sie 
Blint im Sekundentakt.

Das mit der Zeit Einstellung für das display muss ich noch schauen.

von Michael H. (h_m)


Lesenswert?

mitlesa schrieb:
> Volker B. schrieb:
>> JTAGEN Fuse dekativiert?
>
> Frage mich schon die ganze Zeit wie er seinen Controller
> programmiert, aber da ist ja SPI angeschlossen. Nur reicht
> das vermutlich nicht da für ISP auch der Reset betätigt
> werden muss.

Ich habe einen originalen MK2 ISP Programmer

von mitlesa (Gast)


Lesenswert?

mitlesa schrieb:
> Nur reicht
> das vermutlich nicht da für ISP auch der Reset betätigt
> werden muss.

Wenn man genau hinschaut dann darf man sogar annehmen dass der
Reset auch angeschlossen ist.

Michael H. schrieb:
> Ich habe einen originalen MK2 ISP Programmer

Jetzt kontrolliere ob das JTAG Enable Bit gelöscht ist, denn
dein LCD benutzt zufällig zwei Leitungen des JTAG Ports. Das
(JTAG Enable und Port I/O) geht leider nicht zusammen.

von Michael H. (h_m)


Lesenswert?

mitlesa schrieb:
> mitlesa schrieb:
>> Nur reicht
>> das vermutlich nicht da für ISP auch der Reset betätigt
>> werden muss.
>
> Wenn man genau hinschaut dann darf man sogar annehmen dass der
> Reset auch angeschlossen ist.
>
> Michael H. schrieb:
>> Ich habe einen originalen MK2 ISP Programmer
>
> Jetzt kontrolliere ob das JTAG Enable Bit gelöscht ist, denn
> dein LCD benutzt zufällig zwei Leitungen des JTAG Ports. Das
> (JTAG Enable und Port I/O) geht leider nicht zusammen.


Danke das war das Problem, das hatte oben auch schon jemand geschrieben, 
aber so schnell bin ich nicht, Danke.

von mitlesa (Gast)


Lesenswert?

Michael H. schrieb:
> Danke das war das Problem

Danke, endlich mal eine vernünftige zeitnahe Reaktion.

von Micha W. (blackxiiv)


Lesenswert?

hiho,

ich musste feststellen, dass das der LCD-Controller Dicht macht, wenn 
man die Timings missachtet und genau dann eben nur schwarze Rechtecke 
anzeigt.

Hoffe Dir hilft mein Code, da ich ebenfalls den 4-Bit-Mode nutze.
1
#define F_CPU 4000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
7
void write_lcd_sign(uint8_t value){
8
  PORTD = (0x10|(value >> 4));
9
  PORTD = (0x50|(value >> 4));
10
  PORTD = (0x10|(value >> 4));
11
  PORTD = (0x10|(value & 0x0F));
12
  PORTD = (0x50|(value & 0x0F));
13
  PORTD = (0x10|(value & 0x0F));
14
  PORTD = 0x00;
15
  _delay_ms(2);}
16
17
void set_cursor_row1(void){
18
    PORTD = 0X08;
19
    PORTD = 0x48;
20
    PORTD = 0x08;
21
    PORTD = 0x00;
22
    PORTD = 0x40;
23
    PORTD = 0x00;
24
  _delay_ms(2);}
25
26
void set_cursor_row2(void){
27
    PORTD = 0x0C;
28
    PORTD = 0x4C;
29
    PORTD = 0x0C;
30
    PORTD = 0x00;
31
    PORTD = 0x40;
32
    PORTD = 0x00;
33
  _delay_ms(2);}
34
  
35
void lcd_init(void){
36
  _delay_ms(20);  //Time for LCD to Power on
37
  
38
  PORTD = 0x02;  // 4-bit mode, 2 Reihen
39
  PORTD = 0x42;
40
  PORTD = 0x02;  
41
  PORTD = 0x08;
42
  PORTD = 0x48;
43
  PORTD = 0x08;
44
  PORTD = 0x00;
45
  _delay_ms(1.6);
46
47
  PORTD = 0x00;  //Display on, Cursor on, Cursor-blink off
48
  PORTD = 0x40;
49
  PORTD = 0x00;  
50
  PORTD = 0x0E;
51
  PORTD = 0x4E;
52
  PORTD = 0x0E;
53
  PORTD = 0x00;
54
  _delay_ms(1.6);
55
  
56
  PORTD = 0x00;  //Display clear
57
  PORTD = 0x40;
58
  PORTD = 0x00;
59
  PORTD = 0x01;
60
  PORTD = 0x41;
61
  PORTD = 0x01;
62
  PORTD = 0x00;
63
  _delay_ms(3);
64
    //init done!
65
  }
66
67
68
int main(void)
69
{
70
  PORTB = (0<<PB7)|(0<<PB6)|(0<<PB5)|(0<<PB4)|(0<<PB3)|(0<<PB2)|(0<<PB1)|(0<<PB0);
71
  DDRB = (1<<DDB7)|(1<<DDB6)|(1<<DDB5)|(1<<DDB4)|(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0);
72
  PORTD = (0<<PD7)|(0<<PD6)|(0<<PD5)|(0<<PD4)|(0<<PD3)|(0<<PD2)|(0<<PD1)|(0<<PD0);
73
  DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD5)|(1<<DDD4)|(1<<DDD3)|(1<<DDD2)|(1<<DDD1)|(1<<DDD0);
74
  
75
    // lcd init
76
  lcd_init();
77
  
78
  write_lcd_sign(' ');
79
  write_lcd_sign(' ');
80
  write_lcd_sign('H');
81
  write_lcd_sign('e');
82
  write_lcd_sign('l');
83
  write_lcd_sign('l');
84
  write_lcd_sign('o');
85
  write_lcd_sign(' ');
86
  write_lcd_sign('W');
87
  write_lcd_sign('o');
88
  write_lcd_sign('r');
89
  write_lcd_sign('l');
90
  write_lcd_sign('d');
91
  write_lcd_sign('!');
92
  write_lcd_sign(' ');
93
  write_lcd_sign(' ');
94
  //Row 1 full
95
  set_cursor_row2();
96
  write_lcd_sign(' ');
97
  write_lcd_sign(' ');
98
  write_lcd_sign(' ');
99
  write_lcd_sign(' ');
100
  write_lcd_sign(' ');
101
  write_lcd_sign(' ');
102
  write_lcd_sign(' ');
103
  write_lcd_sign(' ');
104
  write_lcd_sign(' ');
105
  write_lcd_sign(' ');
106
  write_lcd_sign(' ');
107
  write_lcd_sign(' ');
108
  write_lcd_sign(' ');
109
  write_lcd_sign(' ');
110
  write_lcd_sign(' ');
111
  write_lcd_sign(' ');
112
  set_cursor_row1();
113
  
114
  while (1)
115
  {
116
    PORTB = 0x01;
117
    _delay_ms(50);
118
    PORTB = 0x00;
119
    _delay_ms(950);
120
  
121
122
  }
123
124
}
Musst Dir das dann halt auf deinen Code umschreiben, da wo Main-Funktion 
beginnt für deine Ports.
Auf PortB ist eine Heartbeat-LED angeschlossen, die kurz aufblinkt 
nachdem ins LCD geschrieben wurde.

Gruß,
michi (:

Edit: Ohhhh - zu spät :/

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

H. H. schrieb:
> das Display wird nicht initialisiert.

Richtig.

> Ach wo, der Kontrast stimmt

Na ja, sieht man dann ja.

von Micha W. (blackxiiv)


Lesenswert?

MaWin schrieb:
>> Ach wo, der Kontrast stimmt
>
> Na ja, sieht man dann ja.

Wenn man mit 5V arbeitet kann man den Kontrast-Pin einfach auf Masse 
ziehen ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Micha W. schrieb:
> Wenn man mit 5V arbeitet kann man den Kontrast-Pin einfach auf Masse
> ziehen ;)

Hängt vom konkreten Display ab. Es gibt welche, bei denen das dann schon 
arg schwarz wird.

Vernünftige Software macht das über PWM und Menü justierbar. ;-)

von Spess53 (Gast)


Lesenswert?

Hi

>  //Row 1 full
>  set_cursor_row2();

Der TO hat aber ein 8+8 Zweizeiliges Display d.h. nach 8 Zeichen muss in 
die 2.Zeile geschaltet werden

>Wenn man mit 5V arbeitet kann man den Kontrast-Pin einfach auf Masse
>ziehen ;)

Soll ;) ein breites Grinsen bedeuten?

MfG Spess

von Micha W. (blackxiiv)


Lesenswert?

Jörg W. schrieb:
> Hängt vom konkreten Display ab. Es gibt welche, bei denen das dann schon
> arg schwarz wird.

Hatte ich glücklicherweise noch nicht (:

Spess53 schrieb:
> Der TO hat aber ein 8+8 Zweizeiliges Display d.h. nach 8 Zeichen muss in
> die 2.Zeile geschaltet werden

Da habe ich nicht aufgepasst ;)

Spess53 schrieb:
> Soll ;) ein breites Grinsen bedeuten?

Nur ein freches, spontanes, unwissendes Zwinkern, weil bisher alles 
Glatt lief.

gruß,
michi ;)

: Bearbeitet durch User
von Michael H. (h_m)


Lesenswert?

mitlesa schrieb:
> Ingolf G. schrieb:
>> Habe genau das Gleiche mal vor Jahren aufgebaut, gleiches Buch.
>
> In diesem Buch steht sicher noch mehr Schrott drin.

Was wäre denn ein gutes Buch ?

von Thomas (kosmos)


Lesenswert?

jtag disable lässt sich aus der Software raus aktivieren, da gibt es das 
JTAG disable Bit in einem Register, das man setzen muss. Man braucht 
also keine Fuses ändern.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Schrieb ich schon, aber er hat ja wohl nun die Fuses geändert. Wenn man 
eh keinen JTAG-Debugger hat, ist das sicher OK. Wenn man den hat, ist 
JTD die günstigere Option: im "Normalbetrieb" rennt die Software durch 
die Sequenz durch und schaltet es ab. Mit dem Debugger hält man davor an 
und macht dann zwei single-steps; damit ist die zeitliche Bedingung für 
das Abschalten des JTAG-Interfaces nicht erfüllt, und man kann weiter 
debuggen.

Im vorliegenden Beispiel ist aber eh völlig unklar, warum ausgerechnet 
die JTAG-Pins als GPIOs zur Ansteuerung des LCD genutzt werden sollen. 
Es sind ja noch so viele andere Pins frei …

von Stefan F. (Gast)


Lesenswert?

No Y. schrieb:
> Also auf dem obersten Bild ist der Kontrast schonmal falsch..
> Der muss so sein das du gerade keine schwarzen Kästchen mehr siehst.

Nein, dieses Bild ist für den Zustand normal, bevor das Display 
initialisiert wurde. Was ein guter Hinweis auf den Fehler ist.

Diese direkt aufeinander folgenden sbi/cbi Befehle machen mich stutzig. 
Ist das nicht zu schnell? Und zwischen dem Anlegen der Daten und dem 
Enable-Impuls muss man auch ein bisschen warten, soweit ich mich 
erinnere.

Du hast vielleicht Glück dass dein Display schneller ist als der 
originale HD44780 Chip.

Michael H. schrieb:
> Was wäre denn ein gutes Buch ?

Meins http://stefanfrings.de/mikrocontroller_buch/index.html

Nein, das war Spaß. Ich kann mein eigenes Buch ja schlecht selbst 
bewerten. Allerdings ist da in den vergangenen Jahren eine Menge 
Feedback eingeflossen, so dass die Qualität immer besser geworden ist. 
Vielleicht gefällt es dir, schau mal rein. Kostet ja nichts.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

http://sprut.de/electronic/lcd/index.htm
eine sehr ausführliche Beschreibung des HD44780 Controllers.

Die Wartezeiten sind für heutige Mikrocontroller elend lang, auch die 
nötigen Impulsbreiten für kurze Ansteuerimpulse sind oft länger als es 
ein AVR könnte.
Die Benutzung des Busy-Signals ist daher zu empfehlen, um die Zeiten 
nicht sicherheitshalber noch länger machen zu müssen. Das bedeutet 
allerdings etwas mehr Programmieraufwand, da R/W umgeschaltet werden 
muss.

von Stefan F. (Gast)


Lesenswert?

Christoph db1uq K. schrieb:
> eine sehr ausführliche Beschreibung des HD44780 Controllers.

Das finde ich auch.

> Die Benutzung des Busy-Signals ist daher zu empfehlen

Das Busy Signal sagt aber nicht, wie lange die Daten vor dem Enable 
Impuls anliegen müssen und wie lang der Enable Impuls sein soll.

Da ist es einfacher, bei der Initialisierung simple Delays zu benutzen 
und danach die Kommandos und Zeichen einzeln per 2ms Timer-Interrupt 
auszugeben. Das ist dann immer noch schneller, als man lesen kann.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan ⛄ F. schrieb:
> Das Busy Signal sagt aber nicht, wie lange die Daten vor dem Enable
> Impuls anliegen müssen und wie lang der Enable Impuls sein soll.

Das nicht, aber es sagt einem insbesondere, wann das Display mit lange 
dauernden Operationen fertig ist. Da wartet man sonst u. U. sehr viel 
länger als nötig.

Ich verstehe diesen Busy-Bit-Geiz auch nicht so richtig, weder von der 
Hardware noch vom Code ist das viel Aufwand. Und dass kein GPIO mehr 
frei ist, scheint ja hier nun nicht gerade der Fall zu sein …

von Stefan F. (Gast)


Lesenswert?

Jörg W. schrieb:
> Ich verstehe diesen Busy-Bit-Geiz auch nicht so richtig

Ich versuche es mal zu erklären.

Das Busy Flag ist hilfreich, wenn meine Anwendung single-threaded ist, 
also die Ausgabe (wie bei Arduino) blockierend stattfindet. Diese 
Methode ist aber eh nicht optimal.

Wenn mein Programm das Busy Bit auswertet, muss es warten. Das Display 
kann mein ganzes System anhalten, es sei denn, ich nutze Multithreading 
irgendeiner Variante.

Ich könnte z.B. einen Timer-Interrupt nutzen, um zyklisch das Busy Flag 
abzufragen und gepufferte Daten nach und nach auszugeben. Nur kann ich 
dann auch einfach direkt auf ein 2ms Intervall setzen. Denn dann brauche 
ich kein busy Flag mehr, das Display ist sowieso garantiert schneller.

Mit 2ms Delay zwischen jeden Befehl/Zeichen ist die Ausgabe immer noch 
schneller als ich gucken kann. Der Aufwand, die Ausgabe mittels Busy 
Flag zu beschleunigen bringt mir daher keinerlei praktischen Nutzen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich habe 37 ms für ein komplettes Löschen in Erinnerung.

Beim TE sehe ich kein Multitasking. ;-)

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Rudi D. schrieb:
> ;LCD: function set
>     ldi   C,0b00000010;4bit-Mode, noch im 8 bit mode gesendet
>     out   LCD_PORTB, C
>     rcall lcd_enable
>     rcall delay2ms    ;Display ist jetzt im 4bit mode
>
> ; ab nun kann das Byte jeden Wert haben, da es in 2 nibbles aufgeteilt

Nö,
da fehlt aber noch was. die 28hex zum Beispiel und nicht nur das...

Jörg W. schrieb:
> Ich verstehe diesen Busy-Bit-Geiz auch nicht so richtig, weder von der
> Hardware noch vom Code ist das viel Aufwand. Und dass kein GPIO mehr
> frei ist, scheint ja hier nun nicht gerade der Fall zu sein

Hi,
meine, in einen Dabla den Hinweis gelesen zu haben, dass der 
Adresscounter noch aktiv sein kann, und schon Zugriff erfolgt. Dadurch 
könnten sich je nach Situation weitere ungeahnte "Timing-Probleme" 
ergeben.
Brauche nur für Busyabfrage evtl. doch noch ein Delay. Alles rutscht 
sonst eine Zeile zu weit. Die Steuerbefehlsabfolge ist so wie so nicht 
mehr beliebig.
Habe das Timing Diagramm für den HD44780-er mal angehängt.

ciao
gustav

: Bearbeitet durch User
von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Jörg W. schrieb:
> Ich habe 37 ms für ein komplettes Löschen in Erinnerung.

Sprut sagt "Display löschen... 1,64 ms".

Im Datenblatt fehlt die Angabe seltsamerweise.

In meinem eigenen Code warte ich nach CLEAR_DISPLAY sogar nur 60µs so 
wie auch nach allen anderen Zeichen/Kommandos nach der Initialisierung. 
kit einer Ausnahme: RETURN_HOME braucht 1.6ms

von Spess53 (Gast)


Lesenswert?

Hi

>Im Datenblatt fehlt die Angabe seltsamerweise.

Bei den KS0070/KS0074 ist die Zeit für Clear Display und Return Home 
identisch.

MfG Spess

von Stefan F. (Gast)


Lesenswert?

Da sollte ich wohl meine Ausnahme auf CLEAR_DISPLAY ausweiten. Nur um 
sicher zu gehen.

von Karl B. (gustav)


Lesenswert?

Hi,
da offenbar die Aussage "Mein Display zeigt nur schwarze Balken" das 
Hauptproblem hier zu sein scheint,
ist zunächst einmal zu überprüfen, ob und wie überhaupt eine 
Initialisierung erfolgt. (Wurde oben ja schon von H.H. gesagt.)
Welche Fehler können sich da einschleichen:

a)Portzuweisung: welche Ports werden tatsählich
  von Steuerbits und Daten an IC-Anschlüssen verwendet und im Programm
  zugewiesen
b) Reihenfolge der Befehle laut Dabla mit Pausen
c) Enableimpulsgenerierung, Einfügen von Enableimpulsen an der richtigen
   Stelle
d) bei Vierbitmodus: Swappen (Display erwartet, "liest" die oberen 4-Bit
   zuerst)
e) Pushen und Poppen von
   von Zeitschleifen verwendeten Temporärregistern
   vergessen.

War wohl das Wichtigste

ciao
gustav

von Jens G. (jensig)


Lesenswert?

Karl B. schrieb:
> Hi,
> da offenbar die Aussage "Mein Display zeigt nur schwarze Balken" das
> Hauptproblem hier zu sein scheint,

Schien ... Lese doch einfach mal komplett, dann merkste auch, daß das 
Problem schon längst vorbei ist.

von Karl B. (gustav)


Lesenswert?

mitlesa schrieb:
> In diesem Buch steht sicher noch mehr Schrott drin.

Kann man höflicherweise etwas mehr Licht ins Dunkel bringen, indem man 
vielleicht die ISBN-Nummer dieses "Pamphlets" dem werten mitlesenden 
Publikum preisgibt?
Oder habe ich da was überlesen?

ciao
gustav

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von Stefan F. (Gast)


Lesenswert?

Jörg W. schrieb:
> link zum Buch

Wow, Abblock-Kondensatoren hat der Autor offenbar konsequent verweigert.

von Karl B. (gustav)


Lesenswert?

Hi,
in dem Buch unten sind auch C-Programme drin:
Seite 471, Programmname: zum Beispiel k5p4 allerdings ATMega8-er
ISBN:
9783486587906


Titel:   Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie 
- Programmierung in Assembler und C - Schaltungen und Anwendungen
Autor:   Schmitt, Günter

ciao
gustav

Beitrag #6699422 wurde von einem Moderator gelöscht.
von Karl B. (gustav)


Lesenswert?

Jens G. schrieb:
> Schien ... Lese doch einfach mal komplett, dann merkste auch, daß das
> Problem schon längst vorbei ist.

Hi,
soweit ich das jetzt überblicke, hapert es schon bei der Initialisierung 
des LCDs.
Das ist eben zunächst zu klären. Dann step by step...
Oder habe ich da etwas übersehen.
Der Reihe nach [Wiederkaumodus ein]:
Michael H. schrieb:
> Kann das sein, dass ich
> die falschen fuse bits für den externen quarz eingestellt habe?

Jörg W. schrieb:
> Hmm. Bei mir sieht die HD44780-Initialisierung so aus:

Jörg W. schrieb:
> Falls dein Controller mit 1 MHz getaktet
> wird, wäre es wohl OK so. Hast du nicht geschrieben. Falls du
> tatsächlich mit den 8 MHz vom Quarz fährst, ist das aber so auf jeden
> Fall zu schnell.

Michael H. schrieb:
> Habe eine LED im Sekunden Takt blinken lassen und sie
> Blinkt im Sekundentakt.

Jörg W. schrieb:
> Im vorliegenden Beispiel ist aber eh völlig unklar, warum ausgerechnet
> die JTAG-Pins als GPIOs zur Ansteuerung des LCD genutzt werden sollen.
> Es sind ja noch so viele andere Pins frei …

[Wiederkaumodus aus]
So und jetzt Feedback vom TO.....

Offtopic:
Jens G. schrieb:
> Schien ... Lese doch einfach mal komplett, dann merkste auch, daß das
> Problem schon längst vorbei ist.

Hi, bei einigen Progs nehme ich für die LCD-Ausgabe einen "Coprozessor".
Schiebe per UART mit Interrupt die Daten rüber und speicher zwischen und 
lasse LCD sekündlich was anzeigen.
/Offtopic.


ciao
gustav

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Komm Entar schrieb im Beitrag #6699422:
> Verlag des Buches: Franzis

Das reicht schon als Erklärung. Ich habe schon lange nichts gutes mehr 
von diesem Verlag gesehen.

Ich habe für meinen Sohnemann zwei Bausätze und ein "Baubuch" von 
Franzis gekauft. Die Experimente waren spannend und Kindgerecht 
aufbereitet. Aber die Erklärungen, wie/warum es funktioniert waren 
äußerst lückenhaft und in dem Baubuch waren gleich zwei ungeeignete 
Bauteile drin, die blöderweise auch noch in fast jeder Schaltung 
gebraucht wurden. Dazu waren 2 von 10 Fritzing Pläne fehlherhaft.

Ohne meine Hilfe hätte mein Sohn das Ding schon bei der zweiten 
Schaltung frustriert in den Müll geworfen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl B. schrieb:
> So und jetzt Feedback vom TO

Wenn du den Thread wirklich mal gelesen hättest:

Beitrag "Re: Warum geht das nicht ?"

von Karl B. (gustav)


Lesenswert?

Ähh,
da was falsch zitiert. Ins Offtopic sollte der Beitrag von @stefanus 
rein:

Stefan ⛄ F. schrieb:
> Ich könnte z.B. einen Timer-Interrupt nutzen,

etc...

ciao
gustav

von Karl B. (gustav)


Lesenswert?

Michael H. schrieb:
> Danke das war das Problem, das hatte oben auch schon jemand geschrieben,
> aber so schnell bin ich nicht, Danke.

Michael H. schrieb:
> Jetzt kontrolliere ob das JTAG Enable Bit gelöscht ist, denn
>> dein LCD benutzt zufällig zwei Leitungen des JTAG Ports. Das
>> (JTAG Enable und Port I/O) geht leider nicht zusammen.

Und wie sieht jetzt das korrigierte Programm im Zusammenhang aus?
Kurze Kopie als Dateianhang wäre echte Erleuchtung.
Was wurde evtl. noch am Pinout geändert.

Danke.

ciao
gustav

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl B. schrieb:
> Und wie sieht jetzt das korrigierte Programm im Zusammenhang aus?

Er hat wohl nichts geändert als die JTAGEN-Fuse abzuschalten.

Klar, der Rest ist immer noch ziemlicher Pfusch, aber wenn er damit 
glücklich wird, dann isses eben so.

von Karl B. (gustav)


Lesenswert?

OK.
Hoffentlich braucht er keinen HV Modus hernach noch ;-)

Jörg W. schrieb:
> Klar, der Rest ist immer noch ziemlicher Pfusch, aber wenn er damit
> glücklich wird, dann isses eben so.

Wie bereits mehrfach bemerkt wurde: Die LCD-Initialisierung z. B.

OT:
Das mit den Büchern ist mir auch schon übel aufgestoßen.
Da waren LED-Anzeigeeinheiten mit gemeinsamer Katode verlangt aber mit 
gemeinsamer Katode gezeichnet. Das Uhren-IC konnte damals noch nicht so 
leicht wie heute umgestrickt werden. Und ging kaputt. Ca. 30 Deutschmark 
im Teich.
/OT

ciao
gustav

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl B. schrieb:
> Da waren LED-Anzeigeeinheiten mit gemeinsamer Katode verlangt aber mit
> gemeinsamer Katode gezeichnet.

kann ja mal vorkommen :-))

von Karl B. (gustav)


Lesenswert?

Jörg W. schrieb:
> Karl B. schrieb:
>> Da waren LED-Anzeigeeinheiten mit gemeinsamer Katode verlangt aber mit
>> gemeinsamer Katode gezeichnet.
>
> kann ja mal vorkommen :-))

Anode...uuups.

ggg

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.