Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Characters not displaying correctly

alx1234

Newbie
Joined
Jan 24, 2024
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
47
I have three problems that I need to fix, please advise me what to do:

  1. when i try to output the characters, some characters are display correctly and others are not
  2. when i send characters to the display, it iterates in chip 1 and after that in chip 2. In this Case it shows only on chip 1
  3. the down half of the display is offmy code

Code:
#include "modul-Display-hardware.h"
#include "font5x8.h" // Include font5x8.h
#include <avr/io.h>
#include <avr/pgmspace.h> // Für den Zugriff auf PROGMEM
#include <util/delay.h>
#define GLCD_RESET_PIN PD0
#define GLCD_RESET_PORT PORTD
#define GLCD_RESET_DDR DDRD
void glcd_reset_pin_init(void) {
    // Set the reset pin as an output
    GLCD_RESET_DDR |= (1 << GLCD_RESET_PIN);
    // Start with the display not in reset
    GLCD_RESET_PORT |= (1 << GLCD_RESET_PIN);
}
void glcd_reset(void) {
    // Set the reset pin low to reset the GLCD
    GLCD_RESET_PORT &= ~(1 << GLCD_RESET_PIN);
    // Wait for at least 1ms
    _delay_ms(1);
    // Set the reset pin high to end the reset
    GLCD_RESET_PORT |= (1 << GLCD_RESET_PIN);
    // Wait for GLCD to be ready (specify time as per datasheet)
    _delay_ms(10);
}
uint8_t modul_display_init(void){
    // Initialisierungscode...
    DDRA = 0xFF; // Alle Ports von Port A als Ausgang
    DDRC |= (1 << DDC2);
    DDRC |= (1 << DDC3);
    DDRC |= (1 << DDC4);
    DDRC |= (1 << DDC5);
    DDRC |= (1 << DDC6);// Konfiguriere bestimmte Pins von Port C als Ausgang
    DDRC |= (1 << DDC7);
    PORTC = (1 << PORTC7);
   

    modul_display_sendInstruction(63); // Display on
    modul_display_sendInstruction(192); // Display Start Line
    modul_display_sendInstruction(184); // Set Page (x 0-7)
    modul_display_sendInstruction(64); // Set Address(y 0-63)
    return 0;
}
void modul_display_sendInstruction(uint8_t data){
    //uint8_t ready = modul_display_busyCheck(void);
    //if(ready==0){
    PORTA = data; // Daten an Port A senden
    PORTC &= ~((1 << PC2) | (1 << PC3)); // D/I und R/W auf Low setzen
    PORTC |= (1 << PC4); // Enable High
    PORTC &= ~(1 << PC4); // Enable Low
    //}
    }
void modul_display_selectChip(bool chip){
    if(chip){
        PORTC = (PORTC & ~(1 << PC5)) | (1 << PC6); // CS2 high, CS1 low
    } else {
        PORTC = (PORTC & ~(1 << PC6)) | (1 << PC5); // CS1 high, CS2 low
    }
}
void modul_display_writeDisplay(bool chip, uint8_t data){
    modul_display_selectChip(chip);
     modul_display_sendInstruction(184);
    PORTA = data; // Daten an Port A senden
    PORTC |= (1 << PC2); // D/I high
    PORTC &= ~(1 << PC3); // R/W low
    PORTC |= (1 << PC4); // Enable High
    PORTC &= ~(1 << PC4); // Enable Low
}
//reset auf 1 und für enable auf start auf 1 und dann auf flanke
void modul_display_clearDisplay(){
 for (uint8_t page = 0; page < 8; ++page) { // For each page
        modul_display_sendInstruction(0xB0 | page); // Set page address (might be different for your display)
        for (uint8_t chip = 0; chip < 2; ++chip) { // For each chip
            modul_display_selectChip(chip);
            for (uint8_t col = 0; col < 64; ++col) { // Assuming 64 columns per chip
                // Write zero to clear the display
                modul_display_writeDisplay(chip, 0x00);
            }
        }
    }
}
void modul_display_showText(unsigned char *arr, uint16_t length, uint8_t page, uint8_t column) {
    modul_display_sendInstruction(0xB0 | page); // Set page address
    modul_display_sendInstruction(0x00 | (column & 0x0F)); // Set lower column address
    modul_display_sendInstruction(0x10 | ((column >> 4) & 0x0F)); // Set higher column address
    for (uint16_t i = 0; i < length; ++i) {
        uint8_t ascii_index = arr;
        uint8_t font_index = (ascii_index - 32) * 5; // Annahme: ASCII-Wert 32 ist der Start
        for (uint8_t j = 0; j < 5; j++) {
            modul_display_writeDisplay(true, pgm_read_byte(&font5x8[font_index + j]));
        }
        // Optional: Senden Sie hier ein zusätzliches leeres Byte für den Abstand zwischen den Zeichen
        modul_display_writeDisplay(true, 0);
    }
}
void modul_display_showCharArray(unsigned char *arr, uint16_t length){
    for (uint16_t i = 0; i < length; ++i) {
        uint8_t ascii_index = arr;
        uint8_t font_index = (ascii_index - 32) * 5; // Annahme: ASCII-Wert 32 ist der Start
        for(uint8_t j = 0; j < 5; j++) {
            modul_display_writeDisplay(true, pgm_read_byte(&font5x8[font_index + j]));
        }
        // Optional: Senden Sie hier ein zusätzliches leeres Byte für den Abstand zwischen den Zeichen
        modul_display_writeDisplay(true, 0);
    }
}
uint8_t modul_display_run(void){
    glcd_reset_pin_init();
    glcd_reset();
    // Definieren Sie ein Array von Zeichen, die angezeigt werden sollen
    // ASCII-Werte für 'D', 'E', 'U'
    unsigned char charactersToShow[] = {65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,}; 
    // Initialisieren Sie das Display
    modul_display_init();
    _delay_ms(500);
    //unsigned char textToShow[] = "Hello";
    
    // Löschen Sie das Display, bevor Sie etwas Neues anzeigen
    modul_display_clearDisplay();
    //_delay_ms(500);
    // Zeigen Sie die Zeichen auf dem Display an
    modul_display_showCharArray(charactersToShow, 26);
      //modul_display_showText(textToShow, 5, 0, 0);

    return 0; 
}
[code tags added by moderator]

characters1.PNG
 
Last edited by a moderator:
it iterates in chip 1 and after that in chip 2. In this Case it shows only on chip 1
I don´t see chip 1 nor chip 2. Can´t understand wht this means.

****
Circuit:
You don´t say whether the problems are with the simulation or the problems are with the real circuit.
My saying: A circuit without a capacitor is not reliably working circuit.
--> Add proper bypassing capacitors.

I see a lot of unconnected inputs - The display nor the microcontrolelr can work this way.

I understand that simulators are bnot realistic and can work without: XTALs, power supplies, decoupling capacitors and so on .... but still I recommend to draw the schematics like the real circuit.

Also PCB layout may play a role .. or signal voltage levels, or timing....

Klaus
 
Hello!

There are parts of your code in which I don't know what you are trying to do.
As your code works a little bit (at least it shows something), I didn't check
it all, but Klaus is right, this couldn't work in the real world (no power, no ground,
no caps), only in a simulation environment. As for the code itself,
I checked only what you feed into the display function. I suppose it must
be the one, the name of which contains "show text" : modul_display_showText.

Let's suppose the 3 first lines are fine, then you will try to display the contents of arr.
In the loop, you define ascii_index to the beginning of arr, which is fine. Useful,
I don't know, but apparently not an error.

Then you define font-index as (ascii_index - 32) * 5.

Let's take an example: your processor has 32k of RAM starting at 0x00800000.
Then the address of your data is therefore somewhere between 0x00800000 and
0x00807FFF. Let's suppose it is 80BF04.
uint8_t ascii_index = arr; will take an uint8 value from this mess. It will
likely be the lsb, 04. Now if you subtract 32 from 04, you will get E4 (in 8 bit).
And if you multiply E4 by 5, then you will get something probably beautiful, but
for sure random and useless, exactly what you get at the third line.

The alphabet display is right because you use the values inside of the array
(showCharArray works). The Hello string doesn't display because ShowText is wrong,
see above.

Some comments:
1. The LCD you are using is a character display. Why do you make a difference
between a "char array" and text (I mean, why modul_display_showText AND
modul_display_showCharArray?). A text is an array of characters.

2. You define charactersToShow as {65, 66, 67, etc... }.
Why not const char charactersToShow[] = "ABC .... ... XYZ";?
It will be more readable.

3. You should write a separate write_char function.

4. You write: modul_display_clearDisplay, but the LCDs usually have a clear function.

5. You shoud use #define statements.
For example:
#define LCD_RW PC3
In which case the line:
PORTC &= ~(1 << PC3); // R/W low
would become:
PORTC &= ~(1 << LCD_RW); // And here you don't need comment

Or even better:
#define LCD_RW (1 << PC3)
In which case the line
PORTC &= ~(1 << PC3); // R/W low
would become:
PORTC &= ~LCD_RW;

Beside this, in the #defines, you could have:
#define LCD_RS (1 << PC2)
#define LCD_RW (1 << PC3)
#define LCD_EN (1 << PC4)
#define LCD_CS1 (1 << PC5)
#define LCD_CS2 (1 << PC6)
#define LCD_RST (1 << PC7)

Then, you can also add
#define LCD_CTRL (LCD_RS | LCD_RW | LCD_EN | LCD_CS1 | LCD_CS2 | LCD_RST;

This would simplify your setup:
PORTC = LCD_CTRL;

6. You could also make a move_to(line, col) function, in which case
your code would be simplfiied and more understandable.

Dora.
 
i have updated my code as mentioned, but it's still showing the same problem:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <avr/io.h>
#include <util/delay.h>
#include "font5x8.h" // Stellen Sie sicher, dass diese Datei im Projektverzeichnis vorhanden ist
 
// Definition der Pin-Konfiguration für PORTB
#define DI 0  // D/I (Data/Instruction) auf PB0
#define RW 1  // R/W (Read/Write) auf PB1
#define CS1 2 // Chip Select 1 auf PB2
#define CS2 3 // Chip Select 2 auf PB3
#define EN 4  // Enable auf PB4
#define RST 6 // Reset auf PB6
 
void modul_display_init(void) {
    DDRA = 0xFF; // Setzt PORTA als Ausgang für Daten
    DDRB = 0b01111111; // Setzt PORTB Pins für Steuerung
 
    // Display Reset
    PORTB &= ~(1 << RST); // Reset auf Low setzen
    _delay_ms(1); // Kurze Verzögerung
    PORTB |= (1 << RST); // Reset auf High setzen
    _delay_ms(10); // Warte auf Display-Reset
}
 
void modul_display_sendCommand(uint8_t command) {
    PORTA = command; // Sendet Befehl auf Datenleitungen
    PORTB &= ~((1 << DI) | (1 << RW)); // Setzt DI und RW auf Low für Befehlsmodus
    PORTB |= (1 << EN); // Enable auf High setzen
    _delay_us(1); // Kurze Verzögerung
    PORTB &= ~(1 << EN); // Enable auf Low setzen
}
 
void modul_display_sendData(uint8_t data) {
    PORTA = data; // Sendet Daten auf Datenleitungen
    PORTB |= (1 << DI); // Setzt DI auf High für Datenmodus
    PORTB &= ~(1 << RW); // Setzt RW auf Low für Schreibmodus
    PORTB |= (1 << EN); // Enable auf High setzen
    _delay_us(1); // Kurze Verzögerung
    PORTB &= ~(1 << EN); // Enable auf Low setzen
}
 
void modul_select_chip(uint8_t chip) {
    PORTB &= ~((1 << CS1) | (1 << CS2)); // Beide Chip-Selects zuerst auf Low
    if (chip == 0) {
        PORTB |= (1 << CS1); // CS1 auf High
    } else {
        PORTB |= (1 << CS2); // CS2 auf High
    }
}
 
void modul_clear_display(void) {
    for (uint8_t page = 0; page < 8; page++) {
        modul_display_sendCommand(0xB0 | page); // Setzt die Seitenadresse
        for (uint8_t col = 0; col < 64; col++) {
            modul_select_chip(col / 64);
            modul_display_sendData(0x00); // Löscht den Inhalt durch Senden von 0x00
        }
    }
}
 
void modul_write_char(uint8_t page, uint8_t col, char character) {
    uint8_t ascii_index = character - 32; // Konvertiert char zu Index in font5x8
    modul_select_chip(col / 64);
    modul_display_sendCommand(0xB0 | page); // Seitenadresse setzen
    for (uint8_t i = 0; i < 5; i++) {
        modul_display_sendData(pgm_read_byte(&font5x8[ascii_index * 5 + i])); // Sendet Zeichendaten
    }
    modul_display_sendData(0x00); // Spaltenabstand
}
 
void modul_write_string(uint8_t page, uint8_t col, const char* string) {
    while (*string) {
        if (col >= 128) {
            col = 0; // Gehe zur nächsten Zeile, wenn das Ende erreicht ist
            page++;
            if (page >= 8) page = 0; // Wrap around nach 8 Seiten
        }
        modul_write_char(page, col, *string++);
        col += 6; // Bewegt die Spalte um 6 für das nächste Zeichen
    }
}
 
void modul_display_run(void) {
    modul_display_init(); // Initialisiert das Display
    modul_clear_display(); // Löscht das Display
    modul_write_string(0, 0, "Hello World!"); // Schreibt einen String auf das Display
}



display_onlyhalfshow.PNG
 
You don't even mention the LCD controller type. How should we check the code?
Apparently character lines are named "page". Confusing.
 
Sorry for that, the
sorry for that, the controller type is KS0108. I also build a potentiometer and the error still not fixed. This is the Files. The Schematic is in the zip file under Proteus_schematic.


files.PNG
test123.PNG
 

Attachments

  • Code.rar
    9.7 MB · Views: 34

LaTeX Commands Quick-Menu:

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top