一、环境:
IAR8.30、AT32F403Avet7、ST7735S(128*160 4线硬件SPI, RGB565)
二、现象:
单片机上电后,HSI低速配置ST7735S,刷屏正常,颜色正常,但是只有4帧。
然后配置时钟HSE到240MHZ,目测达到一二直帧往上,但是颜色显示不正常,如下:
0XF800(本应显示RED确显示BLUE)猜测可能是设置成BGR模式了。
那么将错就错 0x001F 本应显示RED,却显示成了GREEN。这就其怪了。
将颜色设置为0x07e0,应该是RGB中的一个吧,前面显示了B、G,这回该显示RED了吧,可是显示出了紫色。尼马?!!!
写成表格如下
看来问题不是简单的RGB设置问题。
三、问题排查:
我又反复检查了一遍ST7735S的配置:
ST7735_WriteCommand(ST7735_COLMOD);//0x3A
ST7735_DELAY(1);
ST7735_WriteData(0x55);
ST7735_WriteCommand(ST7735_MADCTL);
ST7735_WriteData(0xa0);
设置没有问题。
检查操作步骤,发现出现:
1、上电后先刷屏,刷不同的颜色。
2、全屏显示图片。
而步骤1使用的函数是:
void ST7735_DrawRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
ST7735_SetAddressWindow(x, y, x + width - 1, y + height - 1);
ST7735_WriteCommand(ST7735_RAMWR);
ST7735_DELAY(1);
// Write the color data
for (uint16_t i = 0; i < width * height; i++)
{
ST7735_WriteData(color>>8);
ST7735_WriteData(color&0xff);
}
}
而步骤2使用的函数是:
void ST7735_DrawImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *image)
{
ST7735_SetAddressWindow(x, y, x + width - 1, y + height - 1);
ST7735_WriteCommand(ST7735_RAMWR);
for (uint32_t i = 0; i < width * height; i++)
{
ST7735_WriteData(image[i * 2]);
ST7735_WriteData(image[i * 2 + 1]);
}
}
那么对比可知,是大小端的问题。
由于颜色是uint16_t类型,占用2个字节。假设地址从0x0000开始,到0x0001结束。颜色值为0x8001。
相像中的排列为(大端):
实际上(小端):
可以看到步骤2使用的函数取值使用:
ST7735_WriteData(image[i * 2]);
ST7735_WriteData(image[i * 2 + 1]);
先取0x0000 再取 0x0001。
所以回归到最开始的现像:
数值 0xf800 0x07e0 0x001f
颜色 蓝 紫 绿
实际为:
数值 0x00f8 0xe007 0x1f00
颜色 蓝 紫 绿
所以破案了。
四、避坑,一个好的方法:
颜色值不是两个字节吗,可以一次读入到一个变量uint16中再通过>> 、&运算,避免大小端。
————————————————
版权声明:本文为CSDN博主「casdfxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/c_1969/article/details/132598491
|