久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

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

QQ登錄

只需一步,快速開始

搜索
查看: 26476|回復(fù): 32
收起左側(cè)

51單片機(jī)示波器制作(12864顯示帶字庫)

  [復(fù)制鏈接]
ID:209954 發(fā)表于 2017-6-29 18:11 | 顯示全部樓層 |閱讀模式
  首先說明:我才接觸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)指正。
下面是效果圖。
首先是方波。
psb (2).jpg

psb (3).jpg

psb (4).jpg

psb.jpg


再是正弦波。
由于沒有函數(shù)發(fā)生器,就只能通過手機(jī)播放只做好的正弦音頻,再檢測(cè)手機(jī)耳機(jī)接口信號(hào)。
psb (5).jpg

psb (6).jpg

不知道為什么,正弦波有一半不見了,似乎是由于不能檢測(cè)到負(fù)電壓還是什么的。。。
下面貼出main.c的代碼。
  1. #include <reg52.h>
  2. #include"XPT2046.h"
  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit RS=P2^6; //LCD數(shù)據(jù)或命令選擇端
  6. sbit RW=P2^5; //LCD寫入或讀出選擇端
  7. sbit RST=P1^0; //LCD復(fù)位端口
  8. sbit LCDE=P2^7; // LCD使能端
  9. sbit PSB=P3^2;//串行或并行選擇端

  10. void delay(uchar i)
  11. {
  12.         while(i--);        
  13. } //延時(shí)函數(shù),i=1時(shí)延時(shí)約10微秒(12M晶振)

  14. void SPI_Start()
  15. {
  16.         CLK = 0;
  17.         CS  = 1;
  18.         DIN = 1;
  19.         CLK = 1;
  20.         CS  = 0;               
  21. } //ADC芯片(XPT2046)初始化函數(shù)

  22. void lcd_busy()

  23. {

  24.     RS=0;

  25.     RW=1;

  26.     P0=0XFF;

  27.     LCDE=1;

  28.     delay(14);

  29.     while((P0&0x80)==0x80);
  30.           LCDE=0;

  31. }//LCD12864(st7920驅(qū)動(dòng))查忙函數(shù)

  32. void write_com(uchar com)

  33. {

  34.     lcd_busy();RS=0;

  35.     RW=0;

  36.     LCDE=0;

  37.     P0=com;

  38.     delay(9);

  39.     LCDE=1;

  40.     delay(9);

  41.     LCDE=0;

  42. }//LCD寫指令函數(shù)

  43. void write_num(uchar num)

  44. {

  45.     lcd_busy();

  46.     RS=1;

  47.     RW=0;

  48.     LCDE=0;

  49.     P0=num;

  50.     delay(7);

  51.     LCDE=1;

  52.     delay(9);

  53.     LCDE=0;

  54. }//LCD寫數(shù)據(jù)函數(shù)

  55. uchar read_data()

  56. {

  57.     uchar read;

  58.     lcd_busy();

  59.     RS=1;

  60.     RW=1;

  61.     LCDE=0;

  62.     delay(7);

  63.     LCDE=1;

  64.     delay(9);

  65.     read=P0;

  66.     LCDE=0;

  67.     delay(11);;

  68.    

  69.     return read;

  70. } //LCD讀數(shù)據(jù)函數(shù)

  71. void clear_lcd()

  72. {   

  73.     uchar i,j;

  74.     write_com(0x34);

  75.     for(i=0;i<32;i++)             //因?yàn)長CD有縱坐標(biāo)32格所以寫三十二次

  76.     {

  77.         write_com(0x80+i);         //先寫入縱坐標(biāo)Y的值

  78.         write_com(0x80);         //再寫入橫坐標(biāo)X的值

  79.         for(j=0;j<32;j++)         //橫坐標(biāo)有16位,每位寫入兩個(gè)字節(jié)的的數(shù)據(jù),也就寫入32次

  80.         {                         //因?yàn)楫?dāng)寫入兩個(gè)字節(jié)之后橫坐標(biāo)會(huì)自動(dòng)加1,所以就不用再次寫入地址了。

  81.             write_num(0x00);   

  82.         }

  83.     }

  84.     write_com(0x36);

  85.     write_com(0x30);

  86. } //LCD清屏函數(shù)


  87. void put_point(uchar x,uchar y)

  88. {

  89.     uint bt=0,read=0;

  90.     uchar x_adr,y_adr,h_bit,l_bit;

  91.     y_adr=0x80+y%32;            //計(jì)算Y軸的地址,應(yīng)為縱坐標(biāo)有64個(gè),所有對(duì)32求余,當(dāng)Y大于31時(shí),Y的坐標(biāo)是下半屏的。

  92.     if(y>31) //計(jì)算X軸的地址當(dāng)Y大于31時(shí)X的地址在下半屏,從0X88開始,小于31時(shí)X的地址是在上半屏,從0X80開始

  93.         x_adr=0x88+x/16;        

  94.     else

  95.         x_adr=0x80+x/16;

  96.     bt=0x8000>>(x%16); //求這個(gè)點(diǎn)到底是在哪個(gè)點(diǎn)

  97.     write_com(0x34);

  98.     write_com(0x34);

  99.     write_com(y_adr);     //讀取數(shù)據(jù)的時(shí)候要先寫入所取數(shù)據(jù)的地址

  100.     write_com(x_adr);

  101.     read_data();         //讀取的第一個(gè)字節(jié)不要,

  102.     read=read_data();     //從第二個(gè)字節(jié)開始接收。

  103.     read<<=8;

  104.     read|=read_data();

  105.     bt=bt|read;

  106.     h_bit=bt>>8;

  107.     l_bit=bt;

  108.     write_com(y_adr);     //寫入點(diǎn)的時(shí)候,重新寫入地址,因?yàn)榈刂芬呀?jīng)改變。

  109.     write_com(x_adr);

  110.     write_num(h_bit);

  111.     write_num(l_bit);

  112.     write_com(0x36); //開顯示

  113.     write_com(0x30);     //轉(zhuǎn)回基本指令集        

  114. }//LCD畫點(diǎn)函數(shù)

  115. /*

  116. 液晶初始化

  117. */

  118. void lcd_init()

  119. {

  120.     PSB=1;

  121.     RST=1;

  122.     write_com(0x30);     //基本指令操作

  123.     write_com(0x0c);     //開顯示

  124.     write_com(0x01);     //清除LCD顯示

  125. }

  126. void main()

  127. {   
  128.         
  129.     float i;

  130.     uchar x,n,y;

  131.     lcd_init();

  132.     clear_lcd();

  133.     while(1)

  134.     {     
  135.                 SPI_Start();

  136.         write_com(0x34);

  137.         write_com(0x34);

  138.         write_com(0x80);

  139.         write_com(0x88);

  140.         for(i=16;i>0;i--) //畫出X軸

  141.         {

  142.             write_num(0xff);   

  143.         }

  144.         for(i=0;i<64;i++) //畫出Y軸

  145.         {

  146.             put_point(0,i);

  147.         }

  148.         for(i=0;i<128;i++)

  149.         {

  150.             x=i;//使橫坐標(biāo)自動(dòng)向前移

  151.                         n = Read_AD_Data(0xE4);//接收返回的AD值

  152.                         y=32-(n/10);//確定點(diǎn)的縱坐標(biāo)(縱坐標(biāo)是AD值,不是電壓。)

  153.             put_point(x,y);

  154.                         delay(100);

  155.         }

  156.         write_com(0x36);

  157.         write_com(0x30);

  158.         while(1);

  159.     }

  160.    

  161. }//主函數(shù)




復(fù)制代碼

全部資料下載地址:
示波器(自制).zip (38.06 KB, 下載次數(shù): 238)

xpt2046中文.pdf (1.26 MB, 下載次數(shù): 116)










評(píng)分

參與人數(shù) 2黑幣 +22 收起 理由
tieq1952 + 10 很給力!
練氏 + 12

查看全部評(píng)分

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2017-6-29 18:16 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

ID:215119 發(fā)表于 2017-6-29 20:04 | 顯示全部樓層
這個(gè)是可以測(cè)頻率的嗎
回復(fù)

使用道具 舉報(bào)

ID:209954 發(fā)表于 2017-6-29 21:16 | 顯示全部樓層
blink 發(fā)表于 2017-6-29 20:04
這個(gè)是可以測(cè)頻率的嗎

不可以,就只能顯示波形。不過我參考別人寫的程序后覺得加裝LM393再修改一下程序也許就能測(cè)頻率。我現(xiàn)在沒有LM393,也許你可以試一試。
回復(fù)

使用道具 舉報(bào)

ID:209954 發(fā)表于 2017-6-30 09:28 | 顯示全部樓層
補(bǔ)充一下:這個(gè)程序在測(cè)量時(shí)需要在信號(hào)源內(nèi)加入一定的直流偏置,否則有部分波形無法正常顯示。(就像開始測(cè)正弦波時(shí)只顯示了波形的一半。) IMG_20170630_091823.jpg

回復(fù)

使用道具 舉報(bào)

ID:209954 發(fā)表于 2017-7-4 11:17 | 顯示全部樓層
這幾天我又對(duì)程序進(jìn)行了修改——將AD檢測(cè)過程與屏幕刷新過程分離,大大提高了檢測(cè)速度。(此外我將程序修改為5秒自動(dòng)刷新,以方便觀察。)
修改后的main.c如下。
#include <reg52.h>
#include"XPT2046.h"
#define uint unsigned int
#define uchar unsigned char
uchar xdata a[128];

sbit RS=P2^6; //這個(gè)是LCD的數(shù)據(jù)命令選擇端
sbit RW=P2^5; //這個(gè)是LCD的寫入或是讀出選擇端
sbit RST=P1^0; //這個(gè)是LCD的復(fù)位端口
sbit LCDE=P2^7; // 這個(gè)是LCD的使能端
sbit PSB=P3^2;

void delay(uchar i)
{
        while(i--);       
}

void delayms(uint c)   //誤差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}


void lcd_busy()

{

    RS=0;

    RW=1;

    P0=0XFF;

    LCDE=1;

    delay(14);

    while((P0&0x80)==0x80);
          LCDE=0;

}

void write_com(uchar com)

{

    lcd_busy();RS=0;

    RW=0;

    LCDE=0;

    P0=com;

    delay(9);

    LCDE=1;

    delay(9);

    LCDE=0;

}

void write_num(uchar num)

{

    lcd_busy();

    RS=1;

    RW=0;

    LCDE=0;

    P0=num;

    delay(7);

    LCDE=1;

    delay(9);

    LCDE=0;

}

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;

}

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);

}

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)回基本指令集        

}

/*

液晶初始化

*/

void lcd_init()

{

    PSB=1;

    RST=1;

    write_com(0x30);     //基本指令操作

    write_com(0x0c);     //開顯示

    write_com(0x01);     //清除LCD顯示

}

void main()

{   
        while(1)

        {

    uchar x,i,y;

    lcd_init();

    clear_lcd();

        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++)
                {
                    a[i] = Read_AD_Data(0xE4);
                }

        for(i=0;i<128;i++)

        {

            x=i;

                        y=32-(a[i]/10);

            put_point(x,y);

        }

        write_com(0x36);

        write_com(0x30);

                delayms(5000);
    }



}





回復(fù)

使用道具 舉報(bào)

ID:217359 發(fā)表于 2017-7-5 14:45 | 顯示全部樓層
6666
厲害了
回復(fù)

使用道具 舉報(bào)

ID:220115 發(fā)表于 2017-7-16 21:08 | 顯示全部樓層
15576118519 發(fā)表于 2017-7-4 11:17
這幾天我又對(duì)程序進(jìn)行了修改——將AD檢測(cè)過程與屏幕刷新過程分離,大大提高了檢測(cè)速度。(此外我將程序修改 ...

a=Read_AD_Data(0xE4);這句代碼怎么來的?
回復(fù)

使用道具 舉報(bào)

ID:98792 發(fā)表于 2017-7-27 14:49 | 顯示全部樓層
XPT2046是AD轉(zhuǎn)換芯片?你確定?不是觸摸屏控制芯片?樓主你逗我呢
回復(fù)

使用道具 舉報(bào)

ID:48413 發(fā)表于 2017-8-7 19:28 | 顯示全部樓層
謝謝樓主的分享
回復(fù)

使用道具 舉報(bào)

ID:220927 發(fā)表于 2017-12-6 14:08 | 顯示全部樓層
負(fù)半周期電壓不見了是樓主對(duì)電位差沒有理解,如果理解了這樣就能采集到負(fù)半周期的波形了,頻率這種定西還要啟動(dòng)定時(shí)器,真麻煩
回復(fù)

使用道具 舉報(bào)

ID:253767 發(fā)表于 2017-12-21 15:20 | 顯示全部樓層
這是個(gè)很實(shí)用的家伙
回復(fù)

使用道具 舉報(bào)

ID:263148 發(fā)表于 2017-12-26 15:56 | 顯示全部樓層
謝謝樓主的分享
回復(fù)

使用道具 舉報(bào)

ID:302712 發(fā)表于 2018-4-19 10:00 | 顯示全部樓層
學(xué)習(xí)中,謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:319015 發(fā)表于 2018-4-29 17:11 | 顯示全部樓層
積分不夠下,能透漏下XPT2046.c和 XPT2046.h的內(nèi)容嘛?謝
回復(fù)

使用道具 舉報(bào)

ID:8130 發(fā)表于 2018-6-8 21:15 | 顯示全部樓層
19960601 發(fā)表于 2017-7-27 14:49
XPT2046是AD轉(zhuǎn)換芯片?你確定?不是觸摸屏控制芯片?樓主你逗我呢

別逗,XPT2046是一種典型的逐次逼近型模數(shù)轉(zhuǎn)換器(SARADC),自己百度
回復(fù)

使用道具 舉報(bào)

ID:384206 發(fā)表于 2018-10-12 15:14 | 顯示全部樓層
你好  我在用普中科技板子上的xpt2046寫示波器的程序   但是 我是的外部輸入端(12腳)  在沒有輸入的時(shí)候 數(shù)碼管也會(huì)顯示900=1500 的示數(shù) ,  并且在我接上正弦信號(hào)后沒有任何反應(yīng), 12腳接地也沒反應(yīng) 這是為什么 ...  求解
回復(fù)

使用道具 舉報(bào)

ID:399179 發(fā)表于 2018-10-12 19:29 來自觸屏版 | 顯示全部樓層
這個(gè)能不能用?
回復(fù)

使用道具 舉報(bào)

ID:229939 發(fā)表于 2018-10-20 10:46 | 顯示全部樓層
學(xué)習(xí)中,謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:511507 發(fā)表于 2019-4-14 20:04 來自觸屏版 | 顯示全部樓層
這個(gè)read_data函數(shù)是干嘛用的
回復(fù)

使用道具 舉報(bào)

ID:481742 發(fā)表于 2019-5-3 11:30 | 顯示全部樓層
看看
回復(fù)

使用道具 舉報(bào)

ID:481742 發(fā)表于 2019-5-3 11:31 | 顯示全部樓層
試試能不能用
回復(fù)

使用道具 舉報(bào)

ID:544490 發(fā)表于 2019-5-25 09:36 | 顯示全部樓層
用你這個(gè)程序有的點(diǎn)偏離比較大是什么原因
回復(fù)

使用道具 舉報(bào)

ID:118132 發(fā)表于 2020-3-17 17:14 | 顯示全部樓層
謝謝分享,領(lǐng)教了
回復(fù)

使用道具 舉報(bào)

ID:702057 發(fā)表于 2020-3-17 18:22 | 顯示全部樓層
跪拜,大神啊!
回復(fù)

使用道具 舉報(bào)

ID:288930 發(fā)表于 2020-3-19 15:01 | 顯示全部樓層
很好,謝謝分享!
回復(fù)

使用道具 舉報(bào)

ID:696556 發(fā)表于 2020-3-25 23:51 | 顯示全部樓層
接線圖分享一下唄
回復(fù)

使用道具 舉報(bào)

ID:253767 發(fā)表于 2020-5-26 07:38 | 顯示全部樓層
謝謝分享!!!
回復(fù)

使用道具 舉報(bào)

ID:866313 發(fā)表于 2021-1-15 20:27 | 顯示全部樓層
山椒雞爪 發(fā)表于 2017-7-16 21:08
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

XPT2046的命令,0xE4選擇的是AUX輸入模擬信號(hào)
回復(fù)

使用道具 舉報(bào)

ID:102800 發(fā)表于 2021-1-21 09:39 | 顯示全部樓層
謝謝分享最近正在搞這個(gè)東東
回復(fù)

使用道具 舉報(bào)

ID:876818 發(fā)表于 2021-1-22 08:56 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

ID:689120 發(fā)表于 2021-1-23 09:59 | 顯示全部樓層
謝謝樓主,有電路圖就更好了。
回復(fù)

使用道具 舉報(bào)

ID:880853 發(fā)表于 2021-1-27 11:30 | 顯示全部樓層
厲害了,一直都打算玩單片機(jī),都不敢動(dòng)手,看了你們的帖子有點(diǎn)躍躍欲試了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧洲一区二区 | 亚洲欧美视频一区 | 成人欧美一区二区三区 | 午夜免费网 | 欧美日韩国产不卡 | 蜜桃视频一区二区三区 | 激情综合五月 | 免费久久久 | 亚洲91视频 | 一区二区三区四区在线 | 男人视频网站 | 99久久久无码国产精品 | 亚洲欧美在线视频 | 一区二区三区韩国 | 成人免费一区二区三区视频网站 | 欧美精品一级 | 中文字幕在线第一页 | 国产黄色在线观看 | 免费在线一区二区 | 中文字幕不卡在线观看 | 99色视频 | 在线婷婷 | 日韩精品一区二区三区视频播放 | 三级成人在线观看 | 九九热在线免费视频 | 美女福利视频一区 | 97久久精品午夜一区二区 | 亚洲视频在线观看 | 欧美综合国产精品久久丁香 | 亚洲欧美成人 | 日韩一级二级片 | 高清色| 在线免费观看毛片 | 午夜网站视频 | 亚洲综合视频一区 | 亚洲人va欧美va人人爽 | 性高湖久久久久久久久 | 人人看人人搞 | 在线视频 亚洲 | 99色在线视频 | 久久青 |