在制作一些显示类的作品时,通常会有大量的数组,用来储存字库,或者图片。这个时候需要大容量的MCU,导致严重消耗MCU的FLASH,当然可以挂一个外部FLASH芯片。我的DIY喜好是利用身边的元器件去DIY,能不去买元器件,决不去买!
手上大把的MCU,利用起来。
首先先仿真一下,验证理论上是否行的通,有的人认为仿真不如实际的板子,似乎很鄙视仿真。但是仿真可以摸鱼呀
,毕竟上班时候拿个板子在那里调试不好。当然仿真成功后,还是得用实际的板子验证下!
直接上图吧
这是用AVR的MCU写的,之所以用AVR是因为Proteus对AVR比较支持吧,运行速度也还行,之前用C51写过,好多外设没有,要软件模拟。你也可以移植到其他型号的MCU。
原理比较简单,主机发送命令格式给字库单片机,字库单片机接收到命令数据,返回字库数据给主机。
我的格式是
主机发送:“1Bit字符类型”+“2Bit字符”,比如我需要写8*16的字符A,那么发送的数据就是0x10,0x41,0x00 , 0x10就是字符类型,这个可以自己定义,0x41和0x00就是大写字母A,这个用了2个Bit表示,是为了兼容汉字。
字库单片机返回:解析后,返回字库数组,在数据最后面发送一个0x55,用来告诉主机发送完毕。
下面是部分函数:
- #if 1
-
/**********************************************************
- 函数结果:解析字库
- 备 注:
-
**********************************************************/
- void Font_AnalysisData(void)
- {
- uint8_t i=0;
- My_HeadPack_TypeDef *FontPack;
-
-
if (TRUE == RingBuf_COM1_RD_Byte(&MyUart.COM1.Data))
- {
-
MyUart.COM1.Buf_Rx[MyUart.COM1.LenRx]=MyUart.COM1.Data;
- MyUart.COM1.LenRx++;
- }
- else
- {
-
if (0 == MyUart.COM1.TimeOutState)//超时机制
- {
- if (0 != MyUart.COM1.LenRx)
- {
-
FontPack=(My_HeadPack_TypeDef *)&MyUart.COM1.Buf_Rx[0];
-
- if(FontPack->Type == ASCII_8x5)
- {
-
memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_8x5[(FontPack->ID[0] - Font_ASCII_8x5_Offset) * ASCII_8x5],5);
-
Uart_COM1_WR_NByte(5,(uint8_t *)&MyFont.Buf[0]);
- Uart_COM1_WR_Byte(0x55);
- }
- else if(FontPack->Type == ASCII_8x16)
- {
-
memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_8x16[(FontPack->ID[0] - Font_ASCII_8x16_Offset) * ASCII_8x16],16);
-
Uart_COM1_WR_NByte(16,(uint8_t *)&MyFont.Buf[0]);
- Uart_COM1_WR_Byte(0x55);
- }
- else if(FontPack->Type == ASCII_16x16)
- {
-
memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_16x16[(FontPack->ID[0] - Font_ASCII_16x16_Offset) * ASCII_16x16],32);
-
Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
- Uart_COM1_WR_Byte(0x55);
- }
- else if(FontPack->Type == CHN_16x16)
- {
-
for (i=0;i<CHN_16x16_Len;i++)//查找汉字
- {
-
if ((FontPack->ID[0] == WordStock_CHN_16x16[i].Index[0])&&(FontPack->ID[1] == WordStock_CHN_16x16[i].Index[1]))
- {
-
memcpy_P(&MyFont.Buf[0],&WordStock_CHN_16x16[i].Buf[0],32);
-
Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
- Uart_COM1_WR_Byte(0x55);
- break;
- }
- }
- if(i == CHN_16x16_Len)
- {
- memset(&MyFont.Buf[0] , 0xFF , 32);
-
Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
- Uart_COM1_WR_Byte(0x55);
- }
- }
-
memset(&MyUart.COM1.Buf_Rx[0] , 0 , sizeof (MyUart.COM1.Buf_Rx)); //清零
- MyUart.COM1.LenRx = 0;
- }
- }
- }
- }
- #endif
复制代码
- #if 1
-
/***********************************************************
- 函数结果:Font_RD_NByte
- 备 注: 读取串口的字符数据
-
***********************************************************/
-
void Font_RD_NByte(MyFont_Enum_TypeDef Font, uint8_t *CharacterBuf, char *String, uint8_t Len)
- {
- uint16_t Flag=0xFFFF;
-
- Uart_COM1_WR_Byte(Font);
-
Uart_COM1_WR_NByte(2,(uint8_t *)String);
- while(Flag)
- {
- Flag--;
-
if (TRUE == RingBuf_COM1_RD_Byte(&MyUart.COM1.Data))
- {
-
MyUart.COM1.Buf_Rx[MyUart.COM1.LenRx]=MyUart.COM1.Data;
- MyUart.COM1.LenRx++;
- }
- else
- {
-
if (0 == MyUart.COM1.TimeOutState)//超时机制
- {
- if (0 != MyUart.COM1.LenRx)
- {
-
if (0x55 == MyUart.COM1.Buf_Rx[Len-1])//接收到0x55,表示丛机发送完毕了,可以拷贝数据
- {
-
memcpy(CharacterBuf,&MyUart.COM1.Buf_Rx[0],Font);
- Flag=0;
- }
-
memset(&MyUart.COM1.Buf_Rx[0] , 0 , sizeof (MyUart.COM1.Buf_Rx)); //清零
- MyUart.COM1.LenRx = 0;
- }
- }
- }
- if(Flag == 1)//超时
- {
- memset(CharacterBuf , 0xFF, Font); //丛机长时间不回应,串口通信失败,全部点亮
- Flag=0;
- }
- }
- }
- #endif
复制代码
先到这里了,过几天测试下实物看看通信稳不稳定。
Uart_Font.zip(366.62 KB, 下载次数: 10)