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: