找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2156|回复: 6
收起左侧

单片机制作字库(通过串口传输)

[复制链接]
ID:78835 发表于 2022-8-30 12:57 | 显示全部楼层 |阅读模式
在制作一些显示类的作品时,通常会有大量的数组,用来储存字库,或者图片。这个时候需要大容量的MCU,导致严重消耗MCU的FLASH,当然可以挂一个外部FLASH芯片。我的DIY喜好是利用身边的元器件去DIY,能不去买元器件,决不去买!手上大把的MCU,利用起来。
首先先仿真一下,验证理论上是否行的通,有的人认为仿真不如实际的板子,似乎很鄙视仿真。但是仿真可以摸鱼呀,毕竟上班时候拿个板子在那里调试不好。当然仿真成功后,还是得用实际的板子验证下!
直接上图吧
51hei截图_20220830110828.png

这是用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)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:44037 发表于 2022-9-3 11:16 | 显示全部楼层
谢谢楼主分享 只有仿真  能分享一下程序吗
回复

使用道具 举报

ID:78835 发表于 2022-9-8 16:48 | 显示全部楼层
by64214 发表于 2022-9-3 11:16
谢谢楼主分享 只有仿真  能分享一下程序吗

等我整理好一起发出来,最近上班有点忙,没时间整理
回复

使用道具 举报

ID:467178 发表于 2022-9-8 19:57 | 显示全部楼层
楼主请教你下,怎么让单片机发送类似于“AA 55 01 02 02”的数据我的单片机只能发送一个如AA在给后面写就错误了
回复

使用道具 举报

ID:467178 发表于 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
求大神赐教
回复

使用道具 举报

ID:78835 发表于 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 ...

利用环形数组接收数据,再用定时器计算一帧数据的间隔,就是定时器里面记数标志一直不断加一,串口接收中断一进去,就清零定时器记数标志,这样当串口中断没进去的时候,定时器的记数标志位肯定往上加到一定阀值,达到那个阀值说明一帧数据接收到了,这个时候你就可以解码了。
回复

使用道具 举报

ID:759131 发表于 2022-9-23 13:49 | 显示全部楼层
这个用X Modem或者Y Modem就可以很好地传输了
然后X Y 猫用超级终端就有,还有一些远程终端也有的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表