单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:2295|回复:6
打印上一主题下一主题

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

[复制链接]
跳转到指定楼层
楼主
ID:78835发表于 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)





评分

黑币 +50
收起理由
+ 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在给后面写就错误了
5#
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
求大神赐教
6#
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 ...

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

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

Powered by 单片机教程网