沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)

        上一篇文章解决了spi+dma传输数据时DC线操作时序不匹配的问题,但是屏幕依旧没有点亮,所以这一篇文章继续找还存在的问题。上一篇文章:沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑-CSDN博客

        老规矩,先用逻辑分析仪抓取一下波形。

//全屏清除函数
void LCD_Clear(uint16_t color)
{
    uint16_t i=0, j=0;
    uint8_t data[4] = {0};  //color是16bit的,每个像素点需要两个字节的显存

    /* 将16bit的color值分开为两个单独的字节 */
    data[0] = color >> 8;
    data[1] = color;

    /* 显存的值需要逐字节写入 */
    for(j = 0;j < LCD_Buf_Size/2; j++)
    {
        lcd_buf[j * 2] =  data[0];
        lcd_buf[j * 2 + 1] =  data[1];
    }
    /* 指定显存操作地址为全屏幕 */
    Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
    /* 指定接下来的数据为数据 */
    LCD_DC_SET;
    /* 将显存缓冲区的数据全部写入缓冲区 */
    LCD_Writ_Bus(data,4);
    for(i = 0;i <(LCD_TOTAL_BUF_SIZE/LCD_Buf_Size); i++)
    {

        LCD_Writ_Bus(lcd_buf, (uint16_t)LCD_Buf_Size);

   } 
}

        这是我的全屏清除函数,用数组作为缓存,dma打包发送。

        

        代码中我发送的全是oxff,但是实际上只有前面一半是0xff后面全是错乱的顺序,缩小给大家看一下。

        正常来说全是0xff的话sda应该是一直高电平,但是有一半时间是不正常的,所以说明每次缓存区中都有一半的数据丢失了,使用数组的时候如果发现后面的数据不正常,大概率是因为数组访问越界了。

        

        SPI+DMA的传输方式是发送地址不变,源地址不断自加,不断将源地址内的数据取出发送,所以我猜测是内存大小配置跟缓存区数组大小不匹配导致的。我们来验证一下这个猜测。

沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)_第1张图片

        找到DMA的配置页面,其中标出的Halfwork就是半字的意思,也就是16位。

沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)_第2张图片

        而我定义的缓存区是uint8_t,即是8位,所以也正好印证了我的猜想,就是DMA的内存位移跟缓存区的数据类型大小不匹配,DMA每次位移16位,而我的缓存区一个只有8位,因为数组中内存地址是连续的,所以DMA会在缓存区中隔一个数据发送,导致有一半的数据漏掉了,最后的一半数据都是数组越界访问得到的垃圾数据,所以后面一半数据是错乱的毫无意义的。

        

        问题找到了,既然他们不匹配,那就让他们匹配呗,把uint8_t改成uint16_t不就就好了?

        这个办法是可以的,可以看到数据已经全部变成0xff,说明传输已经正常了。但是有个问题,内存浪费,明明只有u8大小的数据却要用u16来存放,有一半的空间被浪费掉了,很明显不是最优选,那还要一个办法就是将DMA改成u8的。

沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)_第3张图片

沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)_第4张图片

沁恒微WCH32v003驱动ST7735S硬件spi+DMA调试小坑(2)_第5张图片

        修改完成,编译下载。

        传输正常,问题完美解决。

你可能感兴趣的:(risc-v,c语言,嵌入式硬件)