TFTLCD驱动


在使用Img2LCD取模软件和ST7735S驱动IC控制LCD时,发现API中显示图片的函数调用后显示异常

原函数:

void ST7735_DrawImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t* data) {
    if((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) return;
    if((x + w - 1) >= ST7735_WIDTH) return;
    if((y + h - 1) >= ST7735_HEIGHT) return;

    ST7735_Select();
    ST7735_SetAddressWindow(x, y, x+w-1, y+h-1);
    ST7735_WriteData((uint8_t*)data, sizeof(uint16_t)*w*h);
    ST7735_Unselect();
}

输入数据要求16位rgb565格式图片,与Img2LCD取模软件两个8位数表示一个像素点的编码逻辑不同,首次修改仅改了原函数输入数据的格式:将data16位常量数据指针类型改为8位无符号变量指针类型,且在spi写入数据时将数据量乘以2,修改后的函数如下:

void ST7735_DrawImage8bit_Img2LCD(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t* data)
{
    if((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) return;
    if((x + w - 1) >= ST7735_WIDTH) return;
    if((y + h - 1) >= ST7735_HEIGHT) return;
    
    ST7735_Select();
    ST7735_SetAddressWindow(x, y, x+w-1, y+h-1);	
    ST7735_WriteData((uint8_t*)data, sizeof(uint8_t)*w*h*2);
    ST7735_Unselect();
}

但是烧录测试后LCD显示颜色异常且边缘模糊,初步推测是图片数据原本的问题,考虑到可能2个8位数据合并时高8位与低8位的顺序反了,在MATLAB中进行数组元素两两翻转验证:

function swappedArray = swapPairs(inputArray)
    if iscolumn(inputArray)
        inputArray = inputArray';
    end
    n = length(inputArray);
    if mod(n, 2) ~= 0
        inputArray(end+1) = NaN; 
    end
    swappedArray = inputArray;
    swappedArray(1:2:end) = inputArray(2:2:end);
    swappedArray(2:2:end) = inputArray(1:2:end);
    swappedArray = swappedArray(~isnan(swappedArray));
end

将原始图片数据处理后再进行烧录,发现显示正常,问题定位到数组元素的写入顺序,解决方法较多,这里我直接在函数中将原始数组变换,最终的函数如下:

void ST7735_DrawImage8bit_Img2LCD(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t* data)
{
	uint32_t i = 0;
	uint8_t temp = 0;
    if((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) return;
    if((x + w - 1) >= ST7735_WIDTH) return;
    if((y + h - 1) >= ST7735_HEIGHT) return;
	/* Swap adjacent elements in the data array	*/
	for ( i = 0; i < w * h * 2; i += 2) {
	    if (i + 1 < w * h * 2) {
	        temp = data[i];
	        data[i] = data[i + 1];
	        data[i + 1] = temp;
	    }
	}
	ST7735_Select();
	ST7735_SetAddressWindow(x, y, x+w-1, y+h-1);	
	ST7735_WriteData((uint8_t*)data, sizeof(uint8_t)*w*h*2);
	ST7735_Unselect();
}

看看显示效果: