xld0932 发表于 2022-7-18 08:57

【国民技术低功耗系列N32L43x测评】05.SPI驱动TFT屏&TF卡实现中英文混合显示

<p>国民N32L43X系列MCU带有2个硬件SPI接口,我们可以使用其中一路来驱动SPI接口的TFT显示屏;虽然这个系列的MCU没有SDIO接口来操作TF卡,但TF卡可以工作在SPI模式,所以我们另外一路SPI可用作来驱动TF卡,通过移植FatFs文件系统来实现对文件的读取操作。</p>

<p>&nbsp;</p>

<p style="">N32L43X系列MCU的SPI接口可工作于主机或从机模式,支持全双工、单工高速通讯模式,具有硬件CRC计算并可配置多主机模式,具有如下特征:</p>

<ul>
        <li style="">全双工和单工同步传输</li>
        <li style="">支持主模式、从模式、多主模式</li>
        <li style="">8位或16位数据帧格式</li>
        <li style="">数据位顺序可编程</li>
        <li style="">软件或硬件进行NSS管理</li>
        <li style="">时钟极性和相位可编程</li>
        <li style="">发送和接收支持硬件CRC计算、校验</li>
        <li style="">支持DMA操作</li>
</ul>

<p style="">&nbsp;</p>

<p style="">我们使用SPI1接口来驱动TF卡,使用SPI2接口来驱动TFT显示屏,具体的引脚使用分配如下表所示:</p>

<table class="MsoTableGrid" style="border-collapse:collapse; border:none;Times New Roman&quot;">
        <tbody>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">复用功能</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">管脚</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">重映射</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI1_NSS</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB6</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF4</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI1_SCK</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB3</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF1</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI1_MISO</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB4</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF1</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI1_MOSI</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB5</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF0</p>
                        </td>
                </tr>
        </tbody>
</table>

<p style="">&nbsp;</p>

<table class="MsoTableGrid" style="border-collapse:collapse; border:none;Times New Roman&quot;">
        <tbody>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">复用功能</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">管脚</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:1px solid black; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">重映射</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI2_NSS</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB12</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF0</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI2_SCK</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB13</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF0</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI2_MISO</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB14</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF0</p>
                        </td>
                </tr>
                <tr>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">SPI2_MOSI</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">PB15</p>
                        </td>
                        <td style="border-bottom:1px solid black; border-top:none; border-right:1px solid black; border-left:1px solid black" valign="top">
                        <p align="center" style="">AF0</p>
                        </td>
                </tr>
        </tbody>
</table>

<p style="">&nbsp;</p>

<p style="">&nbsp;</p>

<p style=""><span style="color:#e74c3c;"><strong>实现功能</strong></span></p>

<p style="">通过N32L43X系列MCU的SPI1接口来驱动TF卡,通过移植FatFs文件系统实现对存放在TF卡中的字库文件GBK_FONT.bin的数据读取操作、通过SPI2接口来驱动TFT显示屏,结合Image2Lcd工具提取图形数据,在TFT显示屏上显示图形、使用存放在MCU FLASH的英文字库点阵数据和存放在TF卡中的GBK中文字库点阵数据,在TFT上实现中英文的混合显示。主要实现代码如下所示:</p>

<p style="">&nbsp;</p>

<p style=""><span style="color:#3498db;">读取GBK中文汉字字库点阵数据</span></p>

<pre>
<code class="language-cpp">void FatFs_GetGBK(const char *str, uint8_t *Buffer)
{
    FIL   File;
    FRESULT Result;
    UINT    br = 0;

    uint8_tGBKH   = str;
    uint8_tGBKL   = str;
    uint32_t Offset = 0;

    if(GBKL &lt; 0x7F) Offset = ((GBKH - 0x81) * 190 + GBKL - 0x40);
    else            Offset = ((GBKH - 0x81) * 190 + GBKL - 0x41);

    Result = f_open(&amp;File, "/GBK_FONT.bin", FA_OPEN_ALWAYS | FA_READ);

    if(Result != RES_OK)
    {
      printf("\r\nf_open Fail! Result = %d\r\n", Result);
    }
    else
    {
      f_lseek(&amp;File, Offset * 32);

      Result = f_read(&amp;File, Buffer, 32, &amp;br);

      f_close(&amp;File);
    }
}</code></pre>

<p style="">&nbsp;</p>

<p style=""><span style="color:#3498db;">显示图片</span></p>

<pre>
<code class="language-cpp">void LCD_DrawImage(void)
{
    uint16_t Color = 0;
    uint32_t Index = 8;

    for(uint32_t i = 0; i &lt; 30; i++)
    {
      for(uint32_t j = 0; j &lt; 113; j++)
      {
            Color   = gImage_LOGO;
            Color &lt;&lt;= 8;
            Color|= gImage_LOGO;

            TFT_DrawPoint(64 + j, 30 + i, Color);
      }
    }

    Index = 8;

    for(uint32_t i = 0; i &lt; 40; i++)
    {
      for(uint32_t j = 0; j &lt; 135; j++)
      {
            Color   = gImage_EEWORLD;
            Color &lt;&lt;= 8;
            Color|= gImage_EEWORLD;

            TFT_DrawPoint(52 + j, 100 + i, Color);
      }
    }
}</code></pre>

<p style="">&nbsp;</p>

<p style=""><span style="color:#3498db;">显示中英文</span></p>

<pre>
<code class="language-cpp">void TFT_DrawEN(uint16_t StartX, uint16_t StartY, char ch)
{
    uint8_tData= 0;
    uint16_t Color = 0;

    for(uint8_t i = 0; i &lt; 16; i++)
    {
      Data = ASCII_1608;

      for(uint8_t j = 0; j &lt; 8; j++)
      {
            if((Data &gt;&gt; j) &amp; 0x01) Color = TFT_Forecolor;
            else                   Color = BACKCOLOR;

            TFT_DrawPoint(StartX + j, StartY + i, Color);
      }
    }
}

void TFT_DrawCN(uint16_t StartX, uint16_t StartY, const char *str)
{
    uint8_t Buffer;
    uint8_t Array;
    uint8_t Point;

    FatFs_GetGBK(str, Buffer);

    for(uint8_t i = 0; i &lt; 8; i++)
    {
      for(uint8_t j = 0; j &lt; 4; j++)
      {
            uint8_t Data = Buffer;

            for(uint8_t k = 0; k &lt; 4; k++)
            {
                if(Data &amp; (0x08 &gt;&gt; (k-0)))Array = 1;
                else                        Array = 0;
            }

            for(uint8_t k = 4; k &lt; 8; k++)
            {
                if(Data &amp; (0x80 &gt;&gt; (k-4)))Array = 1;
                else                        Array = 0;
            }
      }
    }

    for(uint8_t i = 0; i &lt; 16; i++)
    {
      for(uint8_t j = 0; j &lt; 16; j++)
      {
            Point = Array;
      }
    }

    for(uint8_t i = 0; i &lt; 16; i++)
    {
      for(uint8_t j = 0; j &lt; 16; j++)
      {
            if(Point)
            {
                TFT_DrawPoint(StartX+i, StartY+j, TFT_Forecolor);
            }
            else
            {
                TFT_DrawPoint(StartX+i, StartY+j, BACKCOLOR);
            }
      }
    }
}

void TFT_ShowLOG(uint16_t StartX, uint16_t StartY, const char *str)
{
    while(*str != '\0')
    {
      if(*str &lt; 0x7F)
      {
            if(StartX &gt; (240 - 8))
            {
                StartX = 0; StartY += 16;
            }

            if(StartY &gt; (320 - 16))
            {
                StartX = 0; StartY = 0;

                TFT_ClearScreen(BACKCOLOR);
            }

            TFT_DrawEN(StartX, StartY, *str);

            StartX += 0x08;
            str    += 0x01;
      }
      else
      {
            if(StartX &gt; (240 - 16))
            {
                StartX = 0; StartY += 16;
            }

            if(StartY &gt; (320 - 16))
            {
                StartX = 0; StartY = 0;

                TFT_ClearScreen(BACKCOLOR);
            }

            TFT_DrawCN(StartX, StartY,str);

            StartX += 0x10;
            str    += 0x02;
      }
    }
}</code></pre>

<p style="">&nbsp;</p>

<p style="">其它比如SPI的配置、TFT显示屏的驱动及配置、TF卡的读写操作、FATFS文件系统的移植等等代码,具体可以参考附件中的软件工程源代码。</p>

<p style="">&nbsp;</p>

<p style=""><span style="color:#e74c3c;"><strong>运行效果</strong></span></p>

<p style=""></p>

<p style="">&nbsp;</p>

<p style=""><span style="color:#e74c3c;"><strong>附件</strong></span></p>

<p style="">软件工程源代码:</p>

476700838 发表于 2022-7-18 10:08

SPI接口可工作于主机或从机模式,支持全双工、单工高速通讯模式,具有硬件CRC计算并可配置多主机模式 学习

DavidZH 发表于 2022-7-18 11:55

刷屏速率多大呢?

xld0932 发表于 2022-7-18 15:47

DavidZH 发表于 2022-7-18 11:55
刷屏速率多大呢?

<p>当前整屏刷肯定会有明显的感觉,本文主要是实现驱动、显示图片、以及中英文混合显示,没有测试过刷新速率,再加上是使用杜绑线的接引方式,所以在通讯速率上肯定会的影响;想要测试还是需要做一块显示板,配合DMA的方式,刷新速率更高。</p>

lugl4313820 发表于 2022-7-23 21:28

这界面做得非常漂亮呀。

xld0932 发表于 2022-7-24 19:27

lugl4313820 发表于 2022-7-23 21:28
这界面做得非常漂亮呀。

<p><img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan33.gif" width="58" /></p>

lfp136 发表于 2022-12-15 10:07

不错
页: [1]
查看完整版本: 【国民技术低功耗系列N32L43x测评】05.SPI驱动TFT屏&TF卡实现中英文混合显示