qinyunti 发表于 2023-11-1 15:56

【ST多款开发板返场测评】STM32F767 Nucleo-144 基于UVC的FRAMEBUFFER-艺术图片

<div class='showpostmsg'> 本帖最后由 qinyunti 于 2023-11-1 22:03 编辑

<h1><b>前言</b></h1>

<p>前面我们实现了NV12格式的UVC显示,基于此我们可以实现framebuffer机制,实现任意点的颜色的读写,然后移植LVGL进行GUI开发。由于使用YUV格式需要格式转换,且需要根据采样进行插值,直接修改某点的颜色不方便,所以我们使用RGB格式,为了减少缓存大小使用RGB565格式。</p>

<p>&nbsp;</p>

<h1><b>YUV-RGB565-FRAMEBUFFER</b></h1>

<p>usbd_video.c修改描述符的GUID为</p>

<p>DBVAL(0xe436eb7b),</p>

<p>WBVAL(0x524f),</p>

<p>WBVAL(0x11ce),</p>

<p>0x9f,0x53,</p>

<p>0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70,</p>

<p>&nbsp;&nbsp;UVC_BITS_PER_PIXEL, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* bBitsPerPixel : Number of bits per pixel &nbsp;16*/</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>usbd_video_if_template.c修改大小</p>

<p>extern uint8_t s_framebuffer;</p>

<p>const &nbsp;uint8_t *tImagesList[] = {s_framebuffer};</p>

<p>uint32_t tImagesSizes[] = {H_SIZE*V_SIZE*2};</p>

<p>&nbsp;</p>

<p>framebuffer.c中实现framebuffer,其中framebuffer_update测试用RGB轮显</p>

<pre>
<code class="language-cpp">#include &lt;stdint.h&gt;

#include "stm32f7xx_hal.h"

#include "encode_dma.h"

#include "framebuffer.h"



uint8_t s_framebuffer;



uint32_t color_table[] =

{

    0xFF0000,  /*  */

    0x00FF00,  /*  */

    0x0000FF,  /*  */

};



void framebuffer_set(uint32_t xpos, uint32_t ypos, uint8_t r, uint8_t g, uint8_t b)

{

uint16_t color = (((uint16_t)r&amp;0xF8)&lt;&lt;8) | (((uint16_t)g&amp;0xFC)&lt;&lt;3) | (((uint16_t)b&amp;0xF8)&gt;&gt;3);

uint8_t* p = s_framebuffer + (xpos*H_SIZE+ypos)*2;

*(uint16_t*)p = color;

}





void framebuffer_init(void)

{



}





void framebuffer_update(void)

{

static unsigned int index = 0;

    uint8_t* p = (uint8_t*)s_framebuffer;

    uint8_t r;

    uint8_t g;

    uint8_t b;

    if(index &gt;= sizeof(color_table)/sizeof(color_table))

    {

        index = 0;

    }

    r = (color_table &gt;&gt; 16) &amp; 0xFF;

    g = (color_table &gt;&gt; 8) &amp; 0xFF;

    b = (color_table &gt;&gt; 0) &amp; 0xFF;

for(int x=0; x&lt;H_SIZE; x++)

    {

for(int y=0; y&lt;V_SIZE; y++)

      {

   framebuffer_set(x, y, r, g, b);

}

}

index++;

}</code></pre>

<h1><b>艺术图片测试</b></h1>

<p>基于任意的写点函数,通过一些数学公式产生有意思的图片。</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p>代码如下</p>

<pre>
<code class="language-cpp">#include &lt;stdint.h&gt;
#include "stm32f7xx_hal.h"
#include "encode_dma.h"
#include "framebuffer.h"
#include &lt;math.h&gt;

uint8_t s_framebuffer;


#define DIM H_SIZE
#define DM1 (DIM-1)
#define _sq(x) ((x)*(x))                        
#define _cb(x) abs((x)*(x)*(x))            
#define _cr(x) (unsigned short)(pow((x),1.0/3.0))

unsigned char RD(int i,int j){
        return (char)(_sq(cos(atan2(j-65,i-65)/2))*255);
}

unsigned char GR(int i,int j){
        return (char)(_sq(cos(atan2(j-65,i-65)/2-2*acos(-1)/3))*255);
}

unsigned char BL(int i,int j){
        return (char)(_sq(cos(atan2(j-65,i-65)/2+2*acos(-1)/3))*255);
}


unsigned char RD0(int i,int j)
{
        float s=3./(j+99);
        float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
        return ((int)((i+DIM)*s+y)%2+(int)((DIM*2-i)*s+y)%2)*127;
}

unsigned char GR0(int i,int j){
        float s=3./(j+99);
        float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
        return ((int)(5*((i+DIM)*s+y))%2+(int)(5*((DIM*2-i)*s+y))%2)*127;
}

unsigned char BL0(int i,int j){
        float s=3./(j+99);
        float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
        return ((int)(29*((i+DIM)*s+y))%2+(int)(29*((DIM*2-i)*s+y))%2)*127;
}



unsigned char RD1(int i, int j) {
#define r(n)(rand()%n)
    static char c; return!c ? c = !r(999) ? r(256) : RD((i + r(2)) % 1024, (j + r(2)) % 1024) : c;
}

unsigned char GR1(int i, int j) {
    static char c; return!c ? c = !r(999) ? r(256) : GR((i + r(2)) % 1024, (j + r(2)) % 1024) : c;
}

unsigned char BL1(int i, int j) {
    static char c; return!c ? c = !r(999) ? r(256) : BL((i + r(2)) % 1024, (j + r(2)) % 1024) : c;
}


unsigned char RD2(int i, int j) {
    static double k; k += rand() / 1. / 0x7FFF; int l = k; l %= 512; return l &gt; 255 ? 511 - l : l;
}

unsigned char GR2(int i, int j) {
    static double k; k += rand() / 1. / 0x7FFF; int l = k; l %= 512; return l &gt; 255 ? 511 - l : l;
}

unsigned char BL2(int i, int j) {
    static double k; k += rand() / 1. / 0x7FFF; int l = k; l %= 512; return l &gt; 255 ? 511 - l : l;
}

unsigned char RD3(int i, int j) {
    return (unsigned char)sqrt((double)(_sq(i - DIM / 2) * _sq(j - DIM / 2)) * 2.0);
}

unsigned char GR3(int i, int j) {
    return (unsigned char)sqrt((double)(
      (_sq(i - DIM / 2) | _sq(j - DIM / 2)) *
      (_sq(i - DIM / 2) &amp; _sq(j - DIM / 2))
      ));
}

unsigned char BL3(int i, int j) {
    return (unsigned char)sqrt((double)(_sq(i - DIM / 2) &amp; _sq(j - DIM / 2)) * 2.0);
}

unsigned char RD4(int i, int j) {
    static int r; int p = rand() % 9 - 4; r = i &amp; r ? (r + r) / 2 : i ? r : 512; r += r + p &gt; 0 ? p : 0; return r ? r &lt; DIM ? r : DM1 : 0;
}

unsigned char GR4(int i, int j) {
    static int r; int p = rand() % 7 - 3; r = i &amp; r ? (r + r) / 2 : i ? r : 512; r += r + p &gt; 0 ? p : 0; return r ? r &lt; DIM ? r : DM1 : 0;
}

unsigned char BL4(int i, int j) {
    static int r; int p = rand() % 15 - 7; r = i &amp; r ? (r + r) / 2 : i ? r : 512; r += r + p &gt; 0 ? p : 0; return r ? r &lt; DIM ? r : DM1 : 0;

}

void test0(void)
{
        for(int i=0;i&lt;H_SIZE;i++)
        {
                for(int j=0;j&lt;V_SIZE;j++)
                {
                        static unsigned short color;
                        color = RD(i,j)&amp;255;
                        color = GR(i,j)&amp;255;
                        color = BL(i,j)&amp;255;
                        framebuffer_set(i, j, color, color, color);
                }
        }
}

void test1(void)
{
        for(int i=0;i&lt;H_SIZE;i++)
        {
                for(int j=0;j&lt;V_SIZE;j++)
                {
                        static unsigned short color;
                        color = RD1(i,j)&amp;255;
                        color = GR1(i,j)&amp;255;
                        color = BL1(i,j)&amp;255;
                        framebuffer_set(i, j, color, color, color);
                }
        }
}

void test2(void)
{
        for(int i=0;i&lt;H_SIZE;i++)
        {
                for(int j=0;j&lt;V_SIZE;j++)
                {
                        static unsigned short color;
                        color = RD2(i,j)&amp;255;
                        color = GR2(i,j)&amp;255;
                        color = BL2(i,j)&amp;255;
                        framebuffer_set(i, j, color, color, color);
                }
        }
}

void test3(void)
{
        for(int i=0;i&lt;H_SIZE;i++)
        {
                for(int j=0;j&lt;V_SIZE;j++)
                {
                        static unsigned short color;
                        color = RD3(i,j)&amp;255;
                        color = GR3(i,j)&amp;255;
                        color = BL3(i,j)&amp;255;
                        framebuffer_set(i, j, color, color, color);
                }
        }
}

void test4(void)
{
        for(int i=0;i&lt;H_SIZE;i++)
        {
                for(int j=0;j&lt;V_SIZE;j++)
                {
                        static unsigned short color;
                        color = RD4(i,j)&amp;255;
                        color = GR4(i,j)&amp;255;
                        color = BL4(i,j)&amp;255;
                        framebuffer_set(i, j, color, color, color);
                }
        }
}


uint32_t color_table[] =
{
    0xFF0000,/**/
    0x00FF00,/**/
    0x0000FF,/**/
};

typedef void (*test_pf)(void);

test_pf pf_table[] =
{
    test0,/**/
    test1,/**/
    test2,/**/
    test3,/**/
    test4,/**/
};

void framebuffer_set(uint32_t xpos, uint32_t ypos, uint8_t r, uint8_t g, uint8_t b)
{
        uint16_t color = (((uint16_t)r&amp;0xF8)&lt;&lt;8) | (((uint16_t)g&amp;0xFC)&lt;&lt;3) | (((uint16_t)b&amp;0xF8)&gt;&gt;3);
        uint8_t* p = s_framebuffer + (xpos*H_SIZE+ypos)*2;
        *(uint16_t*)p = color;
}


void framebuffer_init(void)
{

}


void framebuffer_update(void)
{
#if 0
                static unsigned int index = 0;
    uint8_t* p = (uint8_t*)s_framebuffer;
    uint8_t r;
    uint8_t g;
    uint8_t b;
    if(index &gt;= sizeof(color_table)/sizeof(color_table))
    {
      index = 0;
    }
    r = (color_table &gt;&gt; 16) &amp; 0xFF;
    g = (color_table &gt;&gt; 8) &amp; 0xFF;
    b = (color_table &gt;&gt; 0) &amp; 0xFF;
                for(int x=0; x&lt;H_SIZE; x++)
    {
                        for(int y=0; y&lt;V_SIZE; y++)
      {
                           framebuffer_set(x, y, r, g, b);
                        }
                }
                index++;
#else
                static unsigned int index = 0;
    if(index &gt;= sizeof(pf_table)/sizeof(pf_table))
    {
      index = 0;
    }
                pf_table();
                //pf_table();
                index++;
#endif
}


</code></pre>

<h1><b>总结</b></h1>

<p>以上实现了基于UVC的FRAMEBUFFER可以进行任意写点,并进行了有意思的艺术图片生成测试。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

helloworld86 发表于 2023-11-1 16:49

有意思,过来看看

jobszheng5 发表于 2023-11-1 17:34

<p>牛逼!</p>

<p><img height="59" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan061.gif" width="67" /></p>
页: [1]
查看完整版本: 【ST多款开发板返场测评】STM32F767 Nucleo-144 基于UVC的FRAMEBUFFER-艺术图片