【国民技术低功耗系列N32L43x测评】05.SPI驱动TFT屏&TF卡实现中英文混合显示
<p>国民N32L43X系列MCU带有2个硬件SPI接口,我们可以使用其中一路来驱动SPI接口的TFT显示屏;虽然这个系列的MCU没有SDIO接口来操作TF卡,但TF卡可以工作在SPI模式,所以我们另外一路SPI可用作来驱动TF卡,通过移植FatFs文件系统来实现对文件的读取操作。</p><p> </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=""> </p>
<p style="">我们使用SPI1接口来驱动TF卡,使用SPI2接口来驱动TFT显示屏,具体的引脚使用分配如下表所示:</p>
<table class="MsoTableGrid" style="border-collapse:collapse; border:none;Times New Roman"">
<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=""> </p>
<table class="MsoTableGrid" style="border-collapse:collapse; border:none;Times New Roman"">
<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=""> </p>
<p style=""> </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=""> </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 < 0x7F) Offset = ((GBKH - 0x81) * 190 + GBKL - 0x40);
else Offset = ((GBKH - 0x81) * 190 + GBKL - 0x41);
Result = f_open(&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(&File, Offset * 32);
Result = f_read(&File, Buffer, 32, &br);
f_close(&File);
}
}</code></pre>
<p style=""> </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 < 30; i++)
{
for(uint32_t j = 0; j < 113; j++)
{
Color = gImage_LOGO;
Color <<= 8;
Color|= gImage_LOGO;
TFT_DrawPoint(64 + j, 30 + i, Color);
}
}
Index = 8;
for(uint32_t i = 0; i < 40; i++)
{
for(uint32_t j = 0; j < 135; j++)
{
Color = gImage_EEWORLD;
Color <<= 8;
Color|= gImage_EEWORLD;
TFT_DrawPoint(52 + j, 100 + i, Color);
}
}
}</code></pre>
<p style=""> </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 < 16; i++)
{
Data = ASCII_1608;
for(uint8_t j = 0; j < 8; j++)
{
if((Data >> j) & 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 < 8; i++)
{
for(uint8_t j = 0; j < 4; j++)
{
uint8_t Data = Buffer;
for(uint8_t k = 0; k < 4; k++)
{
if(Data & (0x08 >> (k-0)))Array = 1;
else Array = 0;
}
for(uint8_t k = 4; k < 8; k++)
{
if(Data & (0x80 >> (k-4)))Array = 1;
else Array = 0;
}
}
}
for(uint8_t i = 0; i < 16; i++)
{
for(uint8_t j = 0; j < 16; j++)
{
Point = Array;
}
}
for(uint8_t i = 0; i < 16; i++)
{
for(uint8_t j = 0; j < 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 < 0x7F)
{
if(StartX > (240 - 8))
{
StartX = 0; StartY += 16;
}
if(StartY > (320 - 16))
{
StartX = 0; StartY = 0;
TFT_ClearScreen(BACKCOLOR);
}
TFT_DrawEN(StartX, StartY, *str);
StartX += 0x08;
str += 0x01;
}
else
{
if(StartX > (240 - 16))
{
StartX = 0; StartY += 16;
}
if(StartY > (320 - 16))
{
StartX = 0; StartY = 0;
TFT_ClearScreen(BACKCOLOR);
}
TFT_DrawCN(StartX, StartY,str);
StartX += 0x10;
str += 0x02;
}
}
}</code></pre>
<p style=""> </p>
<p style="">其它比如SPI的配置、TFT显示屏的驱动及配置、TF卡的读写操作、FATFS文件系统的移植等等代码,具体可以参考附件中的软件工程源代码。</p>
<p style=""> </p>
<p style=""><span style="color:#e74c3c;"><strong>运行效果</strong></span></p>
<p style=""></p>
<p style=""> </p>
<p style=""><span style="color:#e74c3c;"><strong>附件</strong></span></p>
<p style="">软件工程源代码:</p>
SPI接口可工作于主机或从机模式,支持全双工、单工高速通讯模式,具有硬件CRC计算并可配置多主机模式 学习 刷屏速率多大呢? DavidZH 发表于 2022-7-18 11:55
刷屏速率多大呢?
<p>当前整屏刷肯定会有明显的感觉,本文主要是实现驱动、显示图片、以及中英文混合显示,没有测试过刷新速率,再加上是使用杜绑线的接引方式,所以在通讯速率上肯定会的影响;想要测试还是需要做一块显示板,配合DMA的方式,刷新速率更高。</p>
这界面做得非常漂亮呀。 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>
不错
页:
[1]