打印
[AT32F403/403A]

大小端引发的显示问题,以及避免摧残灵魂的方法。

[复制链接]
1021|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qcliu|  楼主 | 2023-9-12 09:41 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、环境:
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


使用特权

评论回复
沙发
tpgf| | 2023-10-10 19:31 | 只看该作者
现在是不是大部分都默认的大端了啊

使用特权

评论回复
板凳
nawu| | 2023-10-10 19:46 | 只看该作者
有没有办法可以让单片机自动识别大小端呢

使用特权

评论回复
地板
aoyi| | 2023-10-10 20:06 | 只看该作者
nawu 发表于 2023-10-10 19:46
有没有办法可以让单片机自动识别大小端呢

这个应该是还不能做到自动识别吧

使用特权

评论回复
5
zljiu| | 2023-10-11 10:48 | 只看该作者
所以我们在使用芯片的时候必须要详细了解寄存器设置

使用特权

评论回复
6
gwsan| | 2023-10-11 11:08 | 只看该作者
这种高字节和低字节差很多的 应该是会报错啊

使用特权

评论回复
7
tfqi| | 2023-10-11 11:31 | 只看该作者
这种避坑方式的前提也的是我知道是大端还是小端吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

3308

帖子

4

粉丝