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