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. ?
    – 6v6gt
    Mar 7 at 4:15
  • I use linux avr-gcc with no error/warning. The commands I used are the first few lines of the comment.
    – ar2015
    Mar 7 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.
    – 6v6gt
    Mar 7 at 4:32
  • @6v6gt, is it serial or parallel?
    – ar2015
    Mar 7 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.
    – 6v6gt
    Mar 7 at 5:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.