|
首先說明:我才接觸51單片機(jī)3個(gè)星期(6月8號(hào)才高考完),對(duì)C語言還很陌生。我就是一個(gè)萌新,還希望大佬們多多指導(dǎo)。
12864(帶字庫st7920驅(qū)動(dòng))為顯示器,XPT2046為AD轉(zhuǎn)換芯片。(不要問我為什么用這個(gè)芯片,開發(fā)板自帶的坑貨。我在網(wǎng)上下載的示波器程序大多以ADC0832或ADC0808為AD轉(zhuǎn)換芯片,結(jié)果我都用不了,所以才被迫自寫程序。)
示波器程序由main.c XPT2046.c XPT2046.h三個(gè)子文件構(gòu)成,main.c是我根據(jù)網(wǎng)上的一個(gè)12864畫圖程序改編而成我也加了一些注釋,后面兩個(gè)文件取自開發(fā)板自帶的例程并進(jìn)行了修改。所以說這個(gè)程序基本上不是我編寫的,也有很多問題和不足之處還請(qǐng)指正。
下面是效果圖。
首先是方波。
再是正弦波。
由于沒有函數(shù)發(fā)生器,就只能通過手機(jī)播放只做好的正弦音頻,再檢測(cè)手機(jī)耳機(jī)接口信號(hào)。
不知道為什么,正弦波有一半不見了,似乎是由于不能檢測(cè)到負(fù)電壓還是什么的。。。
下面貼出main.c的代碼。
- #include <reg52.h>
- #include"XPT2046.h"
- #define uint unsigned int
- #define uchar unsigned char
- sbit RS=P2^6; //LCD數(shù)據(jù)或命令選擇端
- sbit RW=P2^5; //LCD寫入或讀出選擇端
- sbit RST=P1^0; //LCD復(fù)位端口
- sbit LCDE=P2^7; // LCD使能端
- sbit PSB=P3^2;//串行或并行選擇端
- void delay(uchar i)
- {
- while(i--);
- } //延時(shí)函數(shù),i=1時(shí)延時(shí)約10微秒(12M晶振)
- void SPI_Start()
- {
- CLK = 0;
- CS = 1;
- DIN = 1;
- CLK = 1;
- CS = 0;
- } //ADC芯片(XPT2046)初始化函數(shù)
- void lcd_busy()
- {
- RS=0;
- RW=1;
- P0=0XFF;
- LCDE=1;
- delay(14);
- while((P0&0x80)==0x80);
- LCDE=0;
- }//LCD12864(st7920驅(qū)動(dòng))查忙函數(shù)
- void write_com(uchar com)
- {
- lcd_busy();RS=0;
- RW=0;
- LCDE=0;
- P0=com;
- delay(9);
- LCDE=1;
- delay(9);
- LCDE=0;
- }//LCD寫指令函數(shù)
- void write_num(uchar num)
- {
- lcd_busy();
- RS=1;
- RW=0;
- LCDE=0;
- P0=num;
- delay(7);
- LCDE=1;
- delay(9);
- LCDE=0;
- }//LCD寫數(shù)據(jù)函數(shù)
- uchar read_data()
- {
- uchar read;
- lcd_busy();
- RS=1;
- RW=1;
- LCDE=0;
- delay(7);
- LCDE=1;
- delay(9);
- read=P0;
- LCDE=0;
- delay(11);;
-
- return read;
- } //LCD讀數(shù)據(jù)函數(shù)
- void clear_lcd()
- {
- uchar i,j;
- write_com(0x34);
- for(i=0;i<32;i++) //因?yàn)長CD有縱坐標(biāo)32格所以寫三十二次
- {
- write_com(0x80+i); //先寫入縱坐標(biāo)Y的值
- write_com(0x80); //再寫入橫坐標(biāo)X的值
- for(j=0;j<32;j++) //橫坐標(biāo)有16位,每位寫入兩個(gè)字節(jié)的的數(shù)據(jù),也就寫入32次
- { //因?yàn)楫?dāng)寫入兩個(gè)字節(jié)之后橫坐標(biāo)會(huì)自動(dòng)加1,所以就不用再次寫入地址了。
- write_num(0x00);
- }
- }
- write_com(0x36);
- write_com(0x30);
- } //LCD清屏函數(shù)
- void put_point(uchar x,uchar y)
- {
- uint bt=0,read=0;
- uchar x_adr,y_adr,h_bit,l_bit;
- y_adr=0x80+y%32; //計(jì)算Y軸的地址,應(yīng)為縱坐標(biāo)有64個(gè),所有對(duì)32求余,當(dāng)Y大于31時(shí),Y的坐標(biāo)是下半屏的。
- if(y>31) //計(jì)算X軸的地址當(dāng)Y大于31時(shí)X的地址在下半屏,從0X88開始,小于31時(shí)X的地址是在上半屏,從0X80開始
- x_adr=0x88+x/16;
- else
- x_adr=0x80+x/16;
- bt=0x8000>>(x%16); //求這個(gè)點(diǎn)到底是在哪個(gè)點(diǎn)
- write_com(0x34);
- write_com(0x34);
- write_com(y_adr); //讀取數(shù)據(jù)的時(shí)候要先寫入所取數(shù)據(jù)的地址
- write_com(x_adr);
- read_data(); //讀取的第一個(gè)字節(jié)不要,
- read=read_data(); //從第二個(gè)字節(jié)開始接收。
- read<<=8;
- read|=read_data();
- bt=bt|read;
- h_bit=bt>>8;
- l_bit=bt;
- write_com(y_adr); //寫入點(diǎn)的時(shí)候,重新寫入地址,因?yàn)榈刂芬呀?jīng)改變。
- write_com(x_adr);
- write_num(h_bit);
- write_num(l_bit);
- write_com(0x36); //開顯示
- write_com(0x30); //轉(zhuǎn)回基本指令集
- }//LCD畫點(diǎn)函數(shù)
- /*
- 液晶初始化
- */
- void lcd_init()
- {
- PSB=1;
- RST=1;
- write_com(0x30); //基本指令操作
- write_com(0x0c); //開顯示
- write_com(0x01); //清除LCD顯示
- }
- void main()
- {
-
- float i;
- uchar x,n,y;
- lcd_init();
- clear_lcd();
- while(1)
- {
- SPI_Start();
- write_com(0x34);
- write_com(0x34);
- write_com(0x80);
- write_com(0x88);
- for(i=16;i>0;i--) //畫出X軸
- {
- write_num(0xff);
- }
- for(i=0;i<64;i++) //畫出Y軸
- {
- put_point(0,i);
- }
- for(i=0;i<128;i++)
- {
- x=i;//使橫坐標(biāo)自動(dòng)向前移
- n = Read_AD_Data(0xE4);//接收返回的AD值
- y=32-(n/10);//確定點(diǎn)的縱坐標(biāo)(縱坐標(biāo)是AD值,不是電壓。)
- put_point(x,y);
- delay(100);
- }
- write_com(0x36);
- write_com(0x30);
- while(1);
- }
-
- }//主函數(shù)
復(fù)制代碼
全部資料下載地址:
示波器(自制).zip
(38.06 KB, 下載次數(shù): 238)
2017-6-29 18:09 上傳
點(diǎn)擊文件名下載附件
所有程序
xpt2046中文.pdf
(1.26 MB, 下載次數(shù): 116)
2017-6-29 18:10 上傳
點(diǎn)擊文件名下載附件
XPT2046中文資料
|
評(píng)分
-
查看全部評(píng)分
|