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

一、环境:

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了吧,可是显示出了紫色。尼马?!!!

写成表格如下

数值与问题颜色
数值0xf8000x07e00x001f
颜色蓝  绿

看来问题不是简单的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。

相像中的排列为(大端):

地址0x00000x0001
内容0x800x01

实际上(小端):

地址0x00000x0001
内容0x010x80

可以看到步骤2使用的函数取值使用:

ST7735_WriteData(image[i * 2]);
ST7735_WriteData(image[i * 2 + 1]);

先取0x0000 再取 0x0001。

所以回归到最开始的现像:

数值0xf8000x07e00x001f
颜色蓝  绿

实际为:

       

数值0x00f80xe0070x1f00
颜色蓝  绿

所以破案了。

四、避坑,一个好的方法:

颜色值不是两个字节吗,可以一次读入到一个变量uint16中再通过>> 、&运算,避免大小端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值