2

I have a 3.5" TFT LCD communicating in parallel connected to Arduino UNO.

I expect it draws a white circle on a black background but all it does is to show a white screen.

How to fix this?

main.c

// sudo apt-get install avr-libc gcc-avr binutils-avr gdb-avr avrdude
// avr-gcc -mmcu=atmega328p -Wall -Os -o main.elf main.c
// avr-objcopy -O ihex main.elf main.hex
// avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 115200 -U flash:w:main.hex


#define DDRA (*(volatile uint8_t*)0x24)
#define DDRB (*(volatile uint8_t*)0x25)
#define DDRC (*(volatile uint8_t*)0x26)
#define DDRD (*(volatile uint8_t*)0x27)

#define PORTA *((volatile uint8_t*)0x3B)
#define PORTB *((volatile uint8_t*)0x38)
#define PORTC *((volatile uint8_t*)0x35)
#define PORTD *((volatile uint8_t*)0x32)

typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long uint32_t;

typedef signed char int8_t;
typedef signed int int16_t;
typedef signed long int32_t;

#define F_CPU 16000000UL


#define LCD_RD A0
#define LCD_WR A1
#define LCD_RS A2
#define LCD_CS A3
#define LCD_RST A4

#define LCD_WIDTH 320
#define LCD_HEIGHT 480

#define LCD_DATA_PORT PORTD
#define LCD_DATA_DDR DDRD

#define LCD_RD_PORT PORTC
#define LCD_RD_DDR DDRC
#define LCD_RD_PIN 0

#define LCD_WR_PORT PORTC
#define LCD_WR_DDR DDRC
#define LCD_WR_PIN 1

#define LCD_RS_PORT PORTC
#define LCD_RS_DDR DDRC
#define LCD_RS_PIN 2

#define LCD_CS_PORT PORTC
#define LCD_CS_DDR DDRC
#define LCD_CS_PIN 3

#define LCD_RST_PORT PORTC
#define LCD_RST_DDR DDRC
#define LCD_RST_PIN 4

#define LCD_DATA_MASK 0b11111111



void delay_ms(uint16_t ms) {
    // calculate the number of cycles needed for the given number of milliseconds
    uint16_t cycles = F_CPU / 1000UL * ms / 4;
    // use a volatile variable to prevent the compiler from optimizing the loop away
    volatile uint16_t count = cycles;
    // loop until the counter reaches zero
    while (count > 0) {
        count--;
    }
}

void writeCommand(uint8_t command) {
    LCD_RS_PORT &= ~(1 << LCD_RS_PIN); // set RS pin to low for command
    LCD_CS_PORT &= ~(1 << LCD_CS_PIN); // enable chip select
    LCD_WR_PORT &= ~(1 << LCD_WR_PIN); // enable write
    LCD_DATA_PORT = command; // write the command to the data port
    asm volatile("nop"); // wait for stability
    LCD_WR_PORT |= (1 << LCD_WR_PIN); // disable write
    LCD_CS_PORT |= (1 << LCD_CS_PIN); // disable chip select
}

void writeData(uint8_t data) {
    LCD_RS_PORT |= (1 << LCD_RS_PIN); // set RS pin to high for data
    LCD_CS_PORT &= ~(1 << LCD_CS_PIN); // enable chip select
    LCD_WR_PORT &= ~(1 << LCD_WR_PIN); // enable write
    LCD_DATA_PORT = data; // write the data to the data port
    asm volatile("nop"); // wait for stability
    LCD_WR_PORT |= (1 << LCD_WR_PIN); // disable write
    LCD_CS_PORT |= (1 << LCD_CS_PIN); // disable chip select
}

void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
    writeCommand(0x2A);
    writeData(x0 >> 8);
    writeData(x0);
    writeData(x1 >> 8);
    writeData(x1);

    writeCommand(0x2B);
    writeData(y0 >> 8);
    writeData(y0);
    writeData(y1 >> 8);
    writeData(y1);

    writeCommand(0x2C);
}

void fillScreen(uint16_t color) {
    setAddrWindow(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
    for (uint32_t i = 0; i < (uint32_t)LCD_WIDTH * LCD_HEIGHT; i++) {
        writeData(color >> 8);
        writeData(color);
    }
}

void initILI9488() {
    LCD_DATA_DDR = LCD_DATA_MASK;
    LCD_RD_DDR |= (1 << LCD_RD_PIN);
    LCD_WR_DDR |= (1 << LCD_WR_PIN);
    LCD_RS_DDR |= (1 << LCD_RS_PIN);
    LCD_CS_DDR |= (1 << LCD_CS_PIN);
    LCD_RST_DDR |= (1 << LCD_RST_PIN);

    LCD_RD_PORT |= (1 << LCD_RD_PIN);
    LCD_WR_PORT |= (1 << LCD_WR_PIN);
    LCD_RS_PORT |= (1 << LCD_RS_PIN);
    LCD_CS_PORT |= (1 << LCD_CS_PIN);
    LCD_RST_PORT |= (1 << LCD_RST_PIN);
    delay_ms(100);

    writeCommand(0x01); // Software reset
    delay_ms(100);

    writeCommand(0x11); // Sleep out
    delay_ms(100);

    writeCommand(0x3A); // Pixel format set
    writeData(0x55); // 16-bit color

    writeCommand(0x36); // Memory access control
    writeData(0x48); // BGR, horizontal flip

    writeCommand(0x2A); // Column address set
    writeData(0x00);
    writeData(0x00);
    writeData(0x01);
    writeData(0x3F);

    writeCommand(0x2B); // Page address set
    writeData(0x00);
    writeData(0x00);
    writeData(0x01);
    writeData(0xDF);

    writeCommand(0xB0); // Power control
    writeData(0x00);
    writeData(0x1B);
    writeData(0x14);

    writeCommand(0xB1); // Vcom control
    writeData(0x08);
    writeData(0x08);
    writeData(0x08);

    writeCommand(0xB4); // Display inversion control
    writeData(0x07);

    writeData(0x01);
    writeData(0xE0);

    writeCommand(0xC0); // Power control 1
    writeData(0x10);
    writeData(0x10);

    writeCommand(0xC1); // Power control 2
    writeData(0x41);

    writeCommand(0xC5); // VCOM control
    writeData(0x00);
    writeData(0x18);

    writeCommand(0xD0); // Power control 3
    writeData(0x07);
    writeData(0x07);

    writeCommand(0xD1); // Power control 4
    writeData(0x00);
    writeData(0x0E);

    writeCommand(0xD2); // Power control 5
    writeData(0x01);
    writeData(0x02);

    writeCommand(0xE9); // Set image function
    writeData(0x01);

    writeCommand(0x13); // Normal display mode on
    writeCommand(0x29); // Display on
}

#define PI 3.14159265

void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) {
  int16_t x = 0, y = r;
  int16_t d = 3 - 2 * r;

  while (x <= y) {
    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    if (d < 0) {
        d += 4 * x + 6;
    } else {
        d += 4 * (x - y) + 10;
        y--;
    }
    x++;

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    writeData(color >> 8);
    writeData(color);

    setAddrWindow(x0 - x, y0 - y, x0 + x, y0 + y);

    if (x != y) {
        setAddrWindow(x0 - y, y0 - x, x0 + y, y0 + x);
    }
  }
}

int main() {
    initILI9488();
    while(1)
    {
        fillScreen(0x0000); // Clear screen with black color
        drawCircle(LCD_WIDTH / 2, LCD_HEIGHT / 2, 50, 0xFFFF); // Draw white circle at the center of the screen
        delay_ms(5000); // Wait for 5 seconds
    }
    return 0;
}


Connections:

ILI9488 VCC <----> 3.3V
ILI9488 GND <----> GND
ILI9488 SD_SS <----> Arduino pin 10
ILI9488 SD_DI <----> Arduino pin 11
ILI9488 SD_DO <----> Arduino pin 12
ILI9488 SD_SCK <----> Arduino pin 13
ILI9488 RESET <----> e.g., pin 5
ILI9488 D0 <----> Arduino pin 8
ILI9488 D1 <----> Arduino pin 9
ILI9488 D2 <----> Arduino pin 2
ILI9488 D3 <----> Arduino pin 3
ILI9488 D4 <----> Arduino pin 4
ILI9488 D5 <----> Arduino pin 5
ILI9488 D6 <----> Arduino pin 6
ILI9488 D7 <----> Arduino pin 7
ILI9488 LCD_RD <----> Arduino pin A0
ILI9488 LCD_WR <----> Arduino pin A1
ILI9488 LCD_RS <----> Arduino pin A2
ILI9488 LCD_CS <----> Arduino pin A3
ILI9488 LCD_RST <----> Arduino pin A4

Photos:

enter image description here enter image description here

9
  • Which development environment are you using and did you get any compiler warnings, say duplicate definitions etc. ? Commented Mar 7, 2023 at 4:15
  • I use linux avr-gcc with no error/warning. The commands I used are the first few lines of the comment. Commented Mar 7, 2023 at 4:18
  • It may not help you much but for that board and screen I would have used the Arduino development environment and the MCUFRIEND_kbv library. Commented Mar 7, 2023 at 4:32
  • @6v6gt, is it serial or parallel? Commented Mar 7, 2023 at 4:54
  • This github.com/prenticedavid/MCUFRIEND_kbv appears to support screens based on the ILI9488 controller and some controllers with an 8bit parallel interface so you may be lucky. Commented Mar 7, 2023 at 5:52

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.