找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3458|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

單片機制作字庫(通過串口傳輸)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:78835 發(fā)表于 2022-8-30 12:57 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
在制作一些顯示類的作品時,通常會有大量的數(shù)組,用來儲存字庫,或者圖片。這個時候需要大容量的MCU,導(dǎo)致嚴重消耗MCU的FLASH,當(dāng)然可以掛一個外部FLASH芯片。我的DIY喜好是利用身邊的元器件去DIY,能不去買元器件,決不去買!手上大把的MCU,利用起來。
首先先仿真一下,驗證理論上是否行的通,有的人認為仿真不如實際的板子,似乎很鄙視仿真。但是仿真可以摸魚呀,畢竟上班時候拿個板子在那里調(diào)試不好。當(dāng)然仿真成功后,還是得用實際的板子驗證下!
直接上圖吧


這是用AVR的MCU寫的,之所以用AVR是因為Proteus對AVR比較支持吧,運行速度也還行,之前用C51寫過,好多外設(shè)沒有,要軟件模擬。你也可以移植到其他型號的MCU。
原理比較簡單,主機發(fā)送命令格式給字庫單片機,字庫單片機接收到命令數(shù)據(jù),返回字庫數(shù)據(jù)給主機。
我的格式是
主機發(fā)送:“1Bit字符類型”+“2Bit字符”,比如我需要寫8*16的字符A,那么發(fā)送的數(shù)據(jù)就是0x10,0x41,0x00 , 0x10就是字符類型,這個可以自己定義,0x41和0x00就是大寫字母A,這個用了2個Bit表示,是為了兼容漢字。
字庫單片機返回:解析后,返回字庫數(shù)組,在數(shù)據(jù)最后面發(fā)送一個0x55,用來告訴主機發(fā)送完畢。
下面是部分函數(shù):
  1. #if 1
  2. /**********************************************************
  3. 函數(shù)結(jié)果:解析字庫
  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
復(fù)制代碼
  1. #if 1
  2. /***********************************************************
  3. 函數(shù)結(jié)果:Font_RD_NByte
  4. 備  注:  讀取串口的字符數(shù)據(jù)
  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,表示叢機發(fā)送完畢了,可以拷貝數(shù)據(jù)
  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); //叢機長時間不回應(yīng),串口通信失敗,全部點亮
  39.                           Flag=0;
  40.                 }
  41.     }
  42. }
  43. #endif
復(fù)制代碼
先到這里了,過幾天測試下實物看看通信穩(wěn)不穩(wěn)定。
Uart_Font.zip (366.62 KB, 下載次數(shù): 10)





評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:44037 發(fā)表于 2022-9-3 11:16 | 只看該作者
謝謝樓主分享 只有仿真  能分享一下程序嗎
回復(fù)

使用道具 舉報

板凳
ID:78835 發(fā)表于 2022-9-8 16:48 | 只看該作者
by64214 發(fā)表于 2022-9-3 11:16
謝謝樓主分享 只有仿真  能分享一下程序嗎

等我整理好一起發(fā)出來,最近上班有點忙,沒時間整理
回復(fù)

使用道具 舉報

地板
ID:467178 發(fā)表于 2022-9-8 19:57 | 只看該作者
樓主請教你下,怎么讓單片機發(fā)送類似于“AA 55 01 02 02”的數(shù)據(jù)我的單片機只能發(fā)送一個如AA在給后面寫就錯誤了
回復(fù)

使用道具 舉報

5#
ID:467178 發(fā)表于 2022-9-8 20:06 | 只看該作者
怎么寫??
收到0x01發(fā)送55 AA 03 00 02延時1秒再發(fā)送55 AA 03 02 02
收到0x02 發(fā)送55 AA 03 01 03延時1秒再發(fā)送55 AA 03 03 03在延時1秒發(fā)送55 AA 03 04 01
……
一共30條到0x1e
求大神賜教
回復(fù)

使用道具 舉報

6#
ID:78835 發(fā)表于 2022-9-9 08:35 | 只看該作者
zhhdok 發(fā)表于 2022-9-8 20:06
怎么寫??
收到0x01發(fā)送55 AA 03 00 02延時1秒再發(fā)送55 AA 03 02 02
收到0x02 發(fā)送55 AA 03 01 03延時1 ...

利用環(huán)形數(shù)組接收數(shù)據(jù),再用定時器計算一幀數(shù)據(jù)的間隔,就是定時器里面記數(shù)標志一直不斷加一,串口接收中斷一進去,就清零定時器記數(shù)標志,這樣當(dāng)串口中斷沒進去的時候,定時器的記數(shù)標志位肯定往上加到一定閥值,達到那個閥值說明一幀數(shù)據(jù)接收到了,這個時候你就可以解碼了。
回復(fù)

使用道具 舉報

7#
ID:759131 發(fā)表于 2022-9-23 13:49 | 只看該作者
這個用X Modem或者Y Modem就可以很好地傳輸了
然后X Y 貓用超級終端就有,還有一些遠程終端也有的
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表