标题: 单片机制作字库(通过串口传输) [打印本页]

作者: 涛qq623942603    时间: 2022-8-30 12:57
标题: 单片机制作字库(通过串口传输)
在制作一些显示类的作品时,通常会有大量的数组,用来储存字库,或者图片。这个时候需要大容量的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,用来告诉主机发送完毕。
下面是部分函数:
  1. #if 1
  2. /**********************************************************
  3. 函数结果:解析字库
  4. 备  注:
  5. **********************************************************/
  6. void Font_AnalysisData(void)
  7. {
  8.           uint8_t i=0;
  9.           My_HeadPack_TypeDef *FontPack;
  10.         
  11.     if (TRUE == RingBuf_COM1_RD_Byte(&MyUart.COM1.Data))
  12.     {
  13.         MyUart.COM1.Buf_Rx[MyUart.COM1.LenRx]=MyUart.COM1.Data;
  14.         MyUart.COM1.LenRx++;
  15.     }
  16.     else
  17.     {
  18.         if (0 == MyUart.COM1.TimeOutState)//超时机制
  19.         {
  20.             if (0 != MyUart.COM1.LenRx)
  21.             {
  22.                                   FontPack=(My_HeadPack_TypeDef *)&MyUart.COM1.Buf_Rx[0];
  23.                                 
  24.                                   if(FontPack->Type == ASCII_8x5)
  25.                                 {
  26.                                           memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_8x5[(FontPack->ID[0] - Font_ASCII_8x5_Offset) * ASCII_8x5],5);
  27.                                         Uart_COM1_WR_NByte(5,(uint8_t *)&MyFont.Buf[0]);
  28.                                         Uart_COM1_WR_Byte(0x55);
  29.                                 }
  30.                                 else if(FontPack->Type == ASCII_8x16)
  31.                                 {
  32.                                           memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_8x16[(FontPack->ID[0] - Font_ASCII_8x16_Offset) * ASCII_8x16],16);
  33.                                         Uart_COM1_WR_NByte(16,(uint8_t *)&MyFont.Buf[0]);
  34.                                         Uart_COM1_WR_Byte(0x55);
  35.                                 }
  36.                                 else if(FontPack->Type == ASCII_16x16)
  37.                                 {
  38.                                           memcpy_P(&MyFont.Buf[0],&WordStock_ASCII_16x16[(FontPack->ID[0] - Font_ASCII_16x16_Offset) * ASCII_16x16],32);
  39.                                         Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
  40.                                         Uart_COM1_WR_Byte(0x55);
  41.                                 }
  42.                                 else if(FontPack->Type == CHN_16x16)
  43.                                 {
  44.                                         for (i=0;i<CHN_16x16_Len;i++)//查找汉字
  45.                                         {
  46.                                                 if ((FontPack->ID[0] == WordStock_CHN_16x16[i].Index[0])&&(FontPack->ID[1] == WordStock_CHN_16x16[i].Index[1]))
  47.                                                 {
  48.                                                         memcpy_P(&MyFont.Buf[0],&WordStock_CHN_16x16[i].Buf[0],32);
  49.                                                         Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
  50.                                                         Uart_COM1_WR_Byte(0x55);
  51.                                                         break;
  52.                                                 }
  53.                                         }
  54.                                         if(i == CHN_16x16_Len)
  55.                                         {
  56.                                                 memset(&MyFont.Buf[0] , 0xFF , 32);
  57.                                                 Uart_COM1_WR_NByte(32,(uint8_t *)&MyFont.Buf[0]);
  58.                                                 Uart_COM1_WR_Byte(0x55);
  59.                                         }
  60.                                 }
  61.                 memset(&MyUart.COM1.Buf_Rx[0] , 0 , sizeof (MyUart.COM1.Buf_Rx)); //清零
  62.                 MyUart.COM1.LenRx = 0;
  63.             }
  64.         }
  65.     }
  66. }
  67. #endif
复制代码
  1. #if 1
  2. /***********************************************************
  3. 函数结果:Font_RD_NByte
  4. 备  注:  读取串口的字符数据
  5. ***********************************************************/
  6. void Font_RD_NByte(MyFont_Enum_TypeDef Font, uint8_t *CharacterBuf, char *String, uint8_t Len)
  7. {
  8.           uint16_t Flag=0xFFFF;
  9.           
  10.           Uart_COM1_WR_Byte(Font);
  11.         Uart_COM1_WR_NByte(2,(uint8_t *)String);
  12.     while(Flag)
  13.     {
  14.                   Flag--;
  15.         if (TRUE == RingBuf_COM1_RD_Byte(&MyUart.COM1.Data))
  16.                 {
  17.                         MyUart.COM1.Buf_Rx[MyUart.COM1.LenRx]=MyUart.COM1.Data;
  18.                         MyUart.COM1.LenRx++;
  19.                 }
  20.                 else
  21.                 {
  22.                         if (0 == MyUart.COM1.TimeOutState)//超时机制
  23.                         {
  24.                                 if (0 != MyUart.COM1.LenRx)
  25.                                 {
  26.                                           if (0x55 == MyUart.COM1.Buf_Rx[Len-1])//接收到0x55,表示丛机发送完毕了,可以拷贝数据
  27.                                         {
  28.                                                   memcpy(CharacterBuf,&MyUart.COM1.Buf_Rx[0],Font);
  29.                                                 Flag=0;
  30.                                         }
  31.                                         memset(&MyUart.COM1.Buf_Rx[0] , 0 , sizeof (MyUart.COM1.Buf_Rx)); //清零
  32.                                         MyUart.COM1.LenRx = 0;
  33.                                 }
  34.                         }
  35.                 }
  36.         if(Flag == 1)//超时
  37.                 {
  38.                           memset(CharacterBuf , 0xFF, Font); //丛机长时间不回应,串口通信失败,全部点亮
  39.                           Flag=0;
  40.                 }
  41.     }
  42. }
  43. #endif
复制代码
先到这里了,过几天测试下实物看看通信稳不稳定。
Uart_Font.zip (366.62 KB, 下载次数: 10)






作者: by64214    时间: 2022-9-3 11:16
谢谢楼主分享 只有仿真  能分享一下程序吗
作者: 涛qq623942603    时间: 2022-9-8 16:48
by64214 发表于 2022-9-3 11:16
谢谢楼主分享 只有仿真  能分享一下程序吗

等我整理好一起发出来,最近上班有点忙,没时间整理
作者: zhhdok    时间: 2022-9-8 19:57
楼主请教你下,怎么让单片机发送类似于“AA 55 01 02 02”的数据我的单片机只能发送一个如AA在给后面写就错误了
作者: zhhdok    时间: 2022-9-8 20:06
怎么写??
收到0x01发送55 AA 03 00 02延时1秒再发送55 AA 03 02 02
收到0x02 发送55 AA 03 01 03延时1秒再发送55 AA 03 03 03在延时1秒发送55 AA 03 04 01
……
一共30条到0x1e
求大神赐教
作者: 涛qq623942603    时间: 2022-9-9 08:35
zhhdok 发表于 2022-9-8 20:06
怎么写??
收到0x01发送55 AA 03 00 02延时1秒再发送55 AA 03 02 02
收到0x02 发送55 AA 03 01 03延时1 ...

利用环形数组接收数据,再用定时器计算一帧数据的间隔,就是定时器里面记数标志一直不断加一,串口接收中断一进去,就清零定时器记数标志,这样当串口中断没进去的时候,定时器的记数标志位肯定往上加到一定阀值,达到那个阀值说明一帧数据接收到了,这个时候你就可以解码了。
作者: lvlintan    时间: 2022-9-23 13:49
这个用X Modem或者Y Modem就可以很好地传输了
然后X Y 猫用超级终端就有,还有一些远程终端也有的




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1