|
本帖最后由 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ú)奈屏幕不夠大 ,講究看下把。
TLC549進(jìn)行AD轉(zhuǎn)換用LCD12864顯示.png (27.16 KB, 下載次數(shù): 72)
下載附件
TLC549進(jìn)行AD轉(zhuǎn)換用LCD12864顯示
2018-5-4 09:15 上傳
圖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è)字符。
顯示字符.png (43.94 KB, 下載次數(shù): 89)
下載附件
顯示字符
2018-5-4 09:02 上傳
圖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é)果如下圖所示。
顯示異常結(jié)果.png (11.69 KB, 下載次數(shù): 64)
下載附件
2018-5-4 09:38 上傳
圖3 顯示異常結(jié)果
去掉Ⅴ的顯示結(jié)果.png (11.69 KB, 下載次數(shù): 68)
下載附件
2018-5-4 09:28 上傳
圖4 去掉Ⅴ之后的顯示結(jié)果
我初步估計(jì)可能有兩個(gè)原因,一是我的字符轉(zhuǎn)換函數(shù)bitchange有問(wèn)題,但是我VC6.0編譯通過(guò)才拿來(lái)用的,可能還是有什么隱藏的bug;二是那個(gè)LCD12864的bug,希望和大家一起討論,共同進(jìn)步,教程就到這里,代碼如下 。
- #include <reg51.h>
- #include <stdio.h> //sprintf函數(shù)包含庫(kù)
- #include <intrins.h>
- #include <string.h> //strcpy函數(shù)包含庫(kù)
- #define uchar unsigned char
- #define uint unsigned int
- #define LCD_data P0 //數(shù)據(jù)口
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- //LCD型號(hào):TS12864A-3(帶漢字庫(kù)) 控制器ST7920
- sbit LCD_RS = P2^0; //寄存器選擇輸入
- sbit LCD_RW = P2^1; //液晶讀/寫控制
- sbit LCD_EN = P2^2; //液晶使能控制
- sbit LCD_PSB= P2^3; //串/并方式控制
- //TLC549端口定義
- sbit DIO=P3^5; //數(shù)據(jù)線
- sbit CS=P3^6; //片選
- sbit CLK=P3^4; //io口時(shí)鐘
- //proteus的帶字庫(kù)LCD12864不支持?jǐn)?shù)字、英文符號(hào)和英文標(biāo)點(diǎn)
- //顯示字符:◎①②③④⑤⑥⑦⑧⑨⊙Ⅴ
- uchar code dis1[]="電壓值:";
- uchar code zf[]="◎①②③④⑤⑥⑦⑧⑨⊙Ⅴ";
- uchar a[14]; //直接給數(shù)組a賦值,會(huì)出現(xiàn)V.34V,就是第一個(gè)字符被吞并,沒(méi)實(shí)物測(cè)試,不知道原因,希望有硬件的幫忙測(cè)試下^_^
- void bitchange(uchar c[]) //字符轉(zhuǎn)換函數(shù)
- {
- uchar i,m=0,n=0,b[14];
- for(i=0;c[i]!='\0';i++,n+=2)
- {
- if(c[i]!='.')
- {
- m=c[i]-48;
- b[n]=zf[m*2];
- b[n+1]=zf[m*2+1];
- }
- else
- {
- b[n]=zf[20];
- b[n+1]=zf[21];
- }
- }
- b[n]=zf[22];
- b[n+1]=zf[23];
- b[n+2]='\0';
- strcpy(c,b);
- }
- void delay(int ms) //延時(shí)函數(shù)
- {
- while(ms--)
- {
- uchar i;
- for(i=0;i<250;i++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- bit lcd_busy() //檢查L(zhǎng)CD忙狀態(tài),lcd_busy為1時(shí),忙,等待;lcd-busy為0時(shí),閑,可寫指令與數(shù)據(jù)。
- {
- bit result;
- LCD_RS=0;
- LCD_RW=1;
- LCD_EN=1;
- delayNOP();
- result=(bit)(P0&0x80); //強(qiáng)制取最高位P0.7的狀態(tài)
- LCD_EN=0;
- return(result);
- }
- void lcd_wcmd(uchar cmd) //寫指令數(shù)據(jù)到LCD,RS=L,RW=L,E=高脈沖,D0-D7=指令碼。
- {
- while(lcd_busy());
- LCD_RS=0;
- LCD_RW=0;
- LCD_EN=0;
- _nop_();
- _nop_();
- P0=cmd;
- delayNOP();
- LCD_EN=1;
- delayNOP();
- LCD_EN=0;
- }
-
- void lcd_wdat(uchar dat) //寫顯示數(shù)據(jù)到LCD,RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。
- {
- while(lcd_busy());
- LCD_RS=1;
- LCD_RW=0;
- LCD_EN=0;
- P0=dat;
- delayNOP();
- LCD_EN=1;
- delayNOP();
- LCD_EN=0;
- }
- void lcd_pos(uchar X,uchar Y) //設(shè)定顯示位置
- {
- uchar pos;
- if (X==0)
- {X=0x80;}
- else if (X==1)
- {X=0x90;}
- else if (X==2)
- {X=0x88;}
- else if (X==3)
- {X=0x98;}
- pos=X+Y ;
- lcd_wcmd(pos); //顯示地址
- }
-
- void lcd_init() //LCD初始化設(shè)定
- {
- LCD_PSB=1; //并口方式
- lcd_wcmd(0x30); //基本指令操作
- delay(5);
- lcd_wcmd(0x0C); //顯示開(kāi),關(guān)光標(biāo)
- delay(5);
- lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容
- delay(5);
- }
- uint TLC549_AD() //TLC549處理
- {
- uchar i;
- uint data_ad=0;
- CS=1; //初始化,啟動(dòng)
- CLK=0;
- DIO=1;
- CS=0;
- _nop_();
- for(i=0;i<8;i++) //讀取采集數(shù)據(jù),讀取的是上一次采集數(shù)據(jù)
- {
- CLK=1;
- if(DIO)data_ad|=0x01;
- CLK=0;
- data_ad<<=1;
- }
- CS=1;
- data_ad=data_ad*(500/256)+0.5; //0.5V進(jìn)行四舍五入補(bǔ)償
- return(data_ad);
- }
- void main()
- {
- uchar i;
- float AD_convert;
- uchar AD1=35;
- delay(10); //延時(shí)
- lcd_init(); //初始化LCD
- while(1)
- {
- AD_convert=TLC549_AD()/100.0;
- sprintf(a, "%.2f", AD_convert); //將轉(zhuǎn)換結(jié)果轉(zhuǎn)換成字符
- i=0;
- lcd_pos(1,0); //設(shè)置顯示位置為第一行的第1個(gè)字符
- while(dis1[i] != '\0')
- { //顯示“電壓值:”
- lcd_wdat(dis1[i]);
- i++;
- }
- i=0;
- lcd_pos(2,3); //設(shè)置顯示位置為第二行的第3個(gè)字符
- bitchange(a);
- while(a[i] != '\0')
- { //顯示采集的電壓值
- lcd_wdat(a[i]);
- i++;
- }
- }
- }
復(fù)制代碼來(lái)張成功的圖片, 老臉一紅。
AD采樣并用LCD12864顯示.png (102.25 KB, 下載次數(shù): 81)
下載附件
2018-5-4 09:23 上傳
圖5 顯示結(jié)果
還有壓縮包的內(nèi)容,有寫好的程序和仿真,還有把LCD12864的程序分割出來(lái)啦,bug就出現(xiàn)啦 。
程序與仿真.png (64.45 KB, 下載次數(shù): 77)
下載附件
2018-5-4 09:51 上傳
圖6 程序與仿真
|
評(píng)分
-
查看全部評(píng)分
|