找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

單片機(jī)+TLC549 AD采樣LCD12864顯示的仿真與程序源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 destiny_xl 于 2018-6-2 13:49 編輯


AD采樣顯示(TLC549+LCD12864)

大家好,第一次發(fā)帖,本來(lái)準(zhǔn)備早點(diǎn)發(fā)的,但是有個(gè)程序bug調(diào)了幾天都沒(méi)有解決,因?yàn)榭飚厴I(yè)啦,手頭許多硬件都賣啦。然后無(wú)意間在51黑電子論壇看到個(gè)帶字庫(kù)的LCD12864,有點(diǎn)感興趣,順便用了一款8位的串行接口采用逐次逼近型的A/D轉(zhuǎn)換器TLC549,合在一起做了一個(gè)AD實(shí)時(shí)采樣電壓并用LCD12864顯示的電路,整體圖如下圖所示,因?yàn)榭s放的太小啦,LCD12864的字符無(wú)法顯示,無(wú)奈屏幕不夠大,講究看下把。



圖1 TLC549進(jìn)行AD轉(zhuǎn)換用LCD12864顯示

下面我簡(jiǎn)單地來(lái)介紹一下,代碼部分注釋的也比較詳細(xì),我只簡(jiǎn)單地說(shuō)下原理,具體的還得看datesheet搞懂原理和時(shí)序,編寫程序才能得心應(yīng)手。因?yàn)闀r(shí)間關(guān)系,很多代碼也是基于別人基礎(chǔ)上改的,我主要解決的問(wèn)題是讓LCD12864能顯示數(shù)字。大家可能覺(jué)得很奇怪,LCD12864本來(lái)就可以顯示數(shù)字啊,但是有時(shí)候手頭沒(méi)硬件,又急需測(cè)試下自己的LCD12864能否正常工作,proteus沒(méi)有找到帶字庫(kù)的LCD12864。但是論壇有個(gè)人分享了一個(gè)LCD12864的庫(kù),我按照他的方法真的可以實(shí)現(xiàn)在proteus仿真LCD12864,具體操作方法請(qǐng)看帖子:使用proteus中12864液晶再也不用擔(dān)心沒(méi)有字庫(kù)了?,我在這里就不詳述了。


大家也像我迫不及待的裝好LCD12864的庫(kù)之后,發(fā)現(xiàn)不能顯示數(shù)字、英文符號(hào)和英文標(biāo)點(diǎn),同時(shí)測(cè)試的時(shí)候發(fā)現(xiàn),有些復(fù)雜的漢字也無(wú)法顯示。畢竟字符種類太多,也沒(méi)有辦法全部一一封裝進(jìn)去。意外發(fā)現(xiàn)有個(gè)數(shù)字帶圈的特殊字符可以顯示,然后就到網(wǎng)上收集,發(fā)現(xiàn)可以完全支持我的實(shí)驗(yàn)需要的字符,分享給大家◎①②③④⑤⑥⑦⑧⑨⊙Ⅴ,值得一題的是,是中文的數(shù)字5,不是英文的V,前者是漢字2個(gè)字符,后者是英文1個(gè)字符。



圖2 顯示字符


東西都齊啦,就開(kāi)始編寫程序啦,C語(yǔ)言也很久沒(méi)學(xué)啦,對(duì)于字符的處理費(fèi)了很大一部分時(shí)間,不過(guò)終于寫好了,就是程序中的字符轉(zhuǎn)換函數(shù)

bitchange,這個(gè)函數(shù)的功能主要是將英文的字符轉(zhuǎn)換成帶圈的中文字符,原理就是把一個(gè)字節(jié)的字符轉(zhuǎn)換成2個(gè)字符,具體的大家分析下程序就可以看
懂,利用了一個(gè)strcpy復(fù)制函數(shù),包含在string.h的頭文件中。


程序的大致流程是首先我們通過(guò)AD采樣,將采樣的數(shù)據(jù)進(jìn)行簡(jiǎn)單的補(bǔ)償后儲(chǔ)存,然后調(diào)用LCD12864顯示模塊進(jìn)行顯示。期間一直有個(gè)問(wèn)題,調(diào)了幾天還是沒(méi)有解決,開(kāi)始都是分開(kāi)調(diào)的,后面發(fā)現(xiàn)聯(lián)調(diào)的時(shí)候這個(gè)bug又消失啦,所以大家還是有硬件的最好測(cè)試喜愛(ài),順便告訴下我。TLC549的處理模塊,比較簡(jiǎn)單,按照時(shí)序進(jìn)行移位儲(chǔ)存即可,bug的原因出現(xiàn)在LCD12864中,就是我加上Ⅴ字符后程序顯示有問(wèn)題,去掉這個(gè)字符顯示一切正常,問(wèn)題的截圖和去掉當(dāng)我把b[n]=zf[22];b[n+1]=zf[23];兩條語(yǔ)句去掉后的結(jié)果如下圖所示。


圖3 顯示異常結(jié)果  


                                      圖4 去掉Ⅴ之后的顯示結(jié)果


我初步估計(jì)可能有兩個(gè)原因,一是我的字符轉(zhuǎn)換函數(shù)bitchange有問(wèn)題,但是我VC6.0編譯通過(guò)才拿來(lái)用的,可能還是有什么隱藏的bug;二是那個(gè)LCD12864的bug,希望和大家一起討論,共同進(jìn)步,教程就到這里,代碼如下。

  1. #include <reg51.h>
  2. #include <stdio.h> //sprintf函數(shù)包含庫(kù)
  3. #include <intrins.h>
  4. #include <string.h> //strcpy函數(shù)包含庫(kù)
  5. #define uchar unsigned char
  6. #define uint  unsigned int
  7. #define LCD_data  P0             //數(shù)據(jù)口
  8. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  9. //LCD型號(hào):TS12864A-3(帶漢字庫(kù)) 控制器ST7920
  10. sbit LCD_RS = P2^0; //寄存器選擇輸入
  11. sbit LCD_RW = P2^1; //液晶讀/寫控制
  12. sbit LCD_EN = P2^2; //液晶使能控制
  13. sbit LCD_PSB= P2^3; //串/并方式控制

  14. //TLC549端口定義
  15. sbit DIO=P3^5; //數(shù)據(jù)線
  16. sbit CS=P3^6;        //片選
  17. sbit CLK=P3^4; //io口時(shí)鐘

  18. //proteus的帶字庫(kù)LCD12864不支持?jǐn)?shù)字、英文符號(hào)和英文標(biāo)點(diǎn)
  19. //顯示字符:◎①②③④⑤⑥⑦⑧⑨⊙Ⅴ
  20. uchar code dis1[]="電壓值:";
  21. uchar code zf[]="◎①②③④⑤⑥⑦⑧⑨⊙Ⅴ";
  22. uchar a[14]; //直接給數(shù)組a賦值,會(huì)出現(xiàn)V.34V,就是第一個(gè)字符被吞并,沒(méi)實(shí)物測(cè)試,不知道原因,希望有硬件的幫忙測(cè)試下^_^

  23. void bitchange(uchar c[]) //字符轉(zhuǎn)換函數(shù)
  24. {
  25.         uchar i,m=0,n=0,b[14];
  26.         for(i=0;c[i]!='\0';i++,n+=2)
  27.         {
  28.                 if(c[i]!='.')
  29.                 {
  30.                         m=c[i]-48;
  31.                         b[n]=zf[m*2];
  32.                         b[n+1]=zf[m*2+1];
  33.                 }
  34.                 else
  35.                 {
  36.                         b[n]=zf[20];
  37.                         b[n+1]=zf[21];
  38.                 }
  39.         }
  40.         b[n]=zf[22];
  41.         b[n+1]=zf[23];
  42.         b[n+2]='\0';
  43.         strcpy(c,b);
  44. }

  45. void delay(int ms) //延時(shí)函數(shù)
  46. {
  47.     while(ms--)
  48.         {
  49.       uchar i;
  50.           for(i=0;i<250;i++)  
  51.            {
  52.                         _nop_();                           
  53.                         _nop_();
  54.                         _nop_();
  55.                         _nop_();
  56.            }
  57.         }
  58. }               

  59. bit lcd_busy() //檢查L(zhǎng)CD忙狀態(tài),lcd_busy為1時(shí),忙,等待;lcd-busy為0時(shí),閑,可寫指令與數(shù)據(jù)。
  60. {                          
  61.     bit result;
  62.     LCD_RS=0;
  63.     LCD_RW=1;
  64.     LCD_EN=1;
  65.     delayNOP();
  66.     result=(bit)(P0&0x80); //強(qiáng)制取最高位P0.7的狀態(tài)
  67.     LCD_EN=0;
  68.     return(result);
  69. }

  70. void lcd_wcmd(uchar cmd) //寫指令數(shù)據(jù)到LCD,RS=L,RW=L,E=高脈沖,D0-D7=指令碼。
  71. {                          
  72.    while(lcd_busy());
  73.     LCD_RS=0;
  74.     LCD_RW=0;
  75.     LCD_EN=0;
  76.     _nop_();
  77.     _nop_();
  78.     P0=cmd;
  79.     delayNOP();
  80.     LCD_EN=1;
  81.     delayNOP();
  82.     LCD_EN=0;  
  83. }

  84. void lcd_wdat(uchar dat) //寫顯示數(shù)據(jù)到LCD,RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。
  85. {                          
  86.    while(lcd_busy());
  87.     LCD_RS=1;
  88.     LCD_RW=0;
  89.     LCD_EN=0;
  90.     P0=dat;
  91.     delayNOP();
  92.     LCD_EN=1;
  93.     delayNOP();
  94.     LCD_EN=0;
  95. }

  96. void lcd_pos(uchar X,uchar Y) //設(shè)定顯示位置
  97. {                          
  98.    uchar  pos;
  99.    if (X==0)
  100.      {X=0x80;}
  101.    else if (X==1)
  102.      {X=0x90;}
  103.    else if (X==2)
  104.      {X=0x88;}
  105.    else if (X==3)
  106.      {X=0x98;}
  107.    pos=X+Y ;  
  108.    lcd_wcmd(pos); //顯示地址
  109. }

  110. void lcd_init() //LCD初始化設(shè)定
  111. {

  112.     LCD_PSB=1; //并口方式
  113.     lcd_wcmd(0x30); //基本指令操作
  114.     delay(5);
  115.     lcd_wcmd(0x0C); //顯示開(kāi),關(guān)光標(biāo)
  116.     delay(5);
  117.     lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容
  118.     delay(5);
  119. }

  120. uint TLC549_AD() //TLC549處理
  121. {
  122.         uchar i;
  123.         uint data_ad=0;
  124.         CS=1; //初始化,啟動(dòng)
  125.         CLK=0;
  126.         DIO=1;
  127.         CS=0;
  128.         _nop_();                    
  129.         for(i=0;i<8;i++) //讀取采集數(shù)據(jù),讀取的是上一次采集數(shù)據(jù)
  130.         {
  131.                 CLK=1;         
  132.                 if(DIO)data_ad|=0x01;
  133.                 CLK=0;  
  134.                 data_ad<<=1;  
  135.         }         
  136.         CS=1;
  137.         data_ad=data_ad*(500/256)+0.5; //0.5V進(jìn)行四舍五入補(bǔ)償
  138.         return(data_ad);
  139. }

  140. void main()
  141. {
  142.     uchar i;
  143.         float AD_convert;
  144.         uchar AD1=35;
  145.     delay(10); //延時(shí)
  146.     lcd_init(); //初始化LCD      
  147.         while(1)
  148.         {
  149.             AD_convert=TLC549_AD()/100.0;
  150.         sprintf(a, "%.2f", AD_convert); //將轉(zhuǎn)換結(jié)果轉(zhuǎn)換成字符
  151.         i=0;
  152.             lcd_pos(1,0);             //設(shè)置顯示位置為第一行的第1個(gè)字符
  153.             while(dis1[i] != '\0')
  154.              {                         //顯示“電壓值:”
  155.                lcd_wdat(dis1[i]);
  156.                i++;
  157.              }
  158.                 i=0;
  159.             lcd_pos(2,3);             //設(shè)置顯示位置為第二行的第3個(gè)字符
  160.                 bitchange(a);
  161.             while(a[i] != '\0')
  162.              {                         //顯示采集的電壓值
  163.                lcd_wdat(a[i]);
  164.                    i++;
  165.              }
  166.          }   
  167. }

復(fù)制代碼

來(lái)張成功的圖片,老臉一紅。



圖5 顯示結(jié)果


還有壓縮包的內(nèi)容,有寫好的程序和仿真,還有把LCD12864的程序分割出來(lái)啦,bug就出現(xiàn)啦。



圖6 程序與仿真






AD采樣顯示(TLC549+LCD12864).zip

443.56 KB, 下載次數(shù): 136, 下載積分: 黑幣 -5

全部代碼和程序

評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:305196 發(fā)表于 2018-5-4 09:44 | 只看該作者
哎呀,格式一直用不好,出現(xiàn)各種問(wèn)題,感覺(jué)好無(wú)奈。
回復(fù)

使用道具 舉報(bào)

板凳
ID:1 發(fā)表于 2018-5-4 16:48 | 只看該作者
destiny_xl 發(fā)表于 2018-5-4 09:44
哎呀,格式一直用不好,出現(xiàn)各種問(wèn)題,感覺(jué)好無(wú)奈。

格式還可以,資料也不錯(cuò) 謝謝分享,編輯一下,有一個(gè)未使用附件 使用即可
回復(fù)

使用道具 舉報(bào)

地板
ID:305196 發(fā)表于 2018-5-5 20:12 | 只看該作者
admin 發(fā)表于 2018-5-4 16:48
格式還可以,資料也不錯(cuò) 謝謝分享,編輯一下,有一個(gè)未使用附件 使用即可

我是準(zhǔn)備上傳附件的,但是點(diǎn)了上傳不了,在試試
回復(fù)

使用道具 舉報(bào)

5#
ID:305196 發(fā)表于 2018-10-23 10:36 | 只看該作者
真是巧,最近要用LCD12864,原來(lái)12864還有多種規(guī)格啊,這個(gè)12864-S自帶對(duì)比度調(diào)節(jié),不用焊接電位器了,還有并串口模式,今天檢測(cè)了下以前寫的一個(gè)程序,發(fā)現(xiàn)是同樣的問(wèn)題, 開(kāi)始以為是proteus中12864庫(kù)的問(wèn)題,最后檢查程序發(fā)現(xiàn),是while一直循環(huán)有問(wèn)題,改成放到最后while(1); 就可以啦,仿真和實(shí)物都可以通過(guò)。


回復(fù)

使用道具 舉報(bào)

6#
ID:76408 發(fā)表于 2019-3-13 09:10 | 只看該作者
謝謝樓主,收藏了。
回復(fù)

使用道具 舉報(bào)

7#
ID:408974 發(fā)表于 2019-3-17 11:47 | 只看該作者
在仿真軟件中沒(méi)有自帶的LCD12864要自己去下載嗎?
回復(fù)

使用道具 舉報(bào)

8#
ID:408974 發(fā)表于 2019-3-17 11:48 | 只看該作者
成森林 發(fā)表于 2019-3-13 09:10
謝謝樓主,收藏了。

ISIS仿真軟件中沒(méi)有自帶的LCD12864怎么辦,下載這個(gè)文件打開(kāi)說(shuō)沒(méi)有LCD12864這個(gè)中文字庫(kù)
回復(fù)

使用道具 舉報(bào)

9#
ID:408974 發(fā)表于 2019-3-17 12:15 | 只看該作者
在ISIS仿真軟件中沒(méi)有LCD12864怎么辦
回復(fù)

使用道具 舉報(bào)

10#
ID:512403 發(fā)表于 2019-4-23 20:46 | 只看該作者
怎么顯示不一樣
回復(fù)

使用道具 舉報(bào)

11#
ID:964308 發(fā)表于 2021-10-17 15:34 來(lái)自手機(jī) | 只看該作者
gongzuoshi 發(fā)表于 2019-3-17 11:48
ISIS仿真軟件中沒(méi)有自帶的LCD12864怎么辦,下載這個(gè)文件打開(kāi)說(shuō)沒(méi)有LCD12864這個(gè)中文字庫(kù)

百度應(yīng)該能找到
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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