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

QQ登錄

只需一步,快速開始

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

用STC15F2K60S2單片機(jī)+12864(KS0108版)制作的示波器 附程序

[復(fù)制鏈接]
ID:343102 發(fā)表于 2021-5-13 07:12 | 顯示全部樓層 |閱讀模式
從網(wǎng)上找到一個(gè)用STC12C5A60S2制作示波器的程序,源程序?yàn)榇蟮辣爻勺髌。由于手頭上只有STC15F2K60S2,于是嘗試用STC15F2K60S2+12864(KS0108版)制作示波器。程序中僅僅修改了管腳,按鈕只裝了T+、T-,能夠出圖,但是取樣時(shí)間不準(zhǔn),測(cè)頻時(shí)對(duì)波形也有干擾,測(cè)頻也不準(zhǔn),50HZ測(cè)成了63HZ,如圖所示。新手不知如何修改,還望大師指教。

制作出來的實(shí)物圖如下:
IMG_20210513_063108.jpg IMG_20210513_063401.jpg

本源程序由"大道必成"提供.
本人僅作些整理,及少許修改,本著開源精神,提供給大家學(xué)習(xí).
Xushunfa
============================================================
一.系統(tǒng)構(gòu)成
    STC12C5A60S2單片機(jī)內(nèi)部AD采樣(10位采樣,用高8位值);
    LCD12864(驅(qū)動(dòng)為SD7565)SPI方式顯示波形.
    LM393組成遲滯比較器,用于測(cè)量頻率(不需要頻率顯示時(shí)該部分可以省略)(本案用TL072代替)
    最大程度簡(jiǎn)化設(shè)計(jì),信號(hào)通過電容直接進(jìn)入單片機(jī)AD輸入端(因沒有放大電路,測(cè)不了太小的信號(hào).)
    小于100us/div(50/20/10)采用直接采樣,軟件延時(shí).
    大于等于100us/div采用定時(shí)器采樣.
二.基本功能及使用說明
    1.(X軸)時(shí)間/每格:10ms/5ms/2ma/1ms/500us/200us/100us/50us/20us/10us.(基本能顯示20~25Kh信號(hào))
    2.(Y軸)電壓/每格:1V/0.5V/0.2V/0.1V。
    3.Hold功能:凍結(jié)后,波形左右平移共可顯示4屏(含當(dāng)前屏)波形.
    4.有一路5Khz方波輸出(由MCU的內(nèi)部獨(dú)立頻率發(fā)生器產(chǎn)生),還有一路500hz方波輸出(由PCA定時(shí)器產(chǎn)生)
    5.正常運(yùn)行時(shí),會(huì)自動(dòng)將最近運(yùn)行的參數(shù)保存在Eeprom中,供下次開機(jī)時(shí)調(diào)用.
    6.有"設(shè)置模式"(僅設(shè)置對(duì)比度).然后按"Grid"鍵,將"默認(rèn)參數(shù)"及已調(diào)正好的"對(duì)比度值"重新寫入Eeprom中.
    7.如Eeprom中的數(shù)據(jù)丟失或出錯(cuò),開機(jī)時(shí)會(huì)自動(dòng)進(jìn)入"設(shè)置模式".
    8.如先按住"Hold鍵"不放,再上電開機(jī)就可進(jìn)入"設(shè)置模式".
    9.首次使用時(shí),最好先進(jìn)入"設(shè)置模式",將默認(rèn)參數(shù)等寫入Eeprom中.
    10.無信號(hào)輸入時(shí),調(diào)整輸入端的2M電位器使波形線處于Y軸的中心位置.
三.按鍵說明:
    正常運(yùn)行:
    1.K1(HOLD)鍵:"波形凍結(jié)"與"正常顯示"(解凍)切換.
                 短按:"凍結(jié)/解凍"切換,("凍結(jié)"狀態(tài)下,左下角會(huì)顯示Hold!字樣).
                 長(zhǎng)按:"自動(dòng)/手動(dòng)"切換,("自動(dòng)"狀態(tài)下,右上角會(huì)顯示Auto字樣).
    2.K6(Grid)鍵:短按:坐標(biāo)線樣式切換(1.散點(diǎn)加坐標(biāo)線;2.僅坐標(biāo)線;3.僅散點(diǎn);4.空白(四種樣式輪流切換))。
                 長(zhǎng)按:波形線"粗/細(xì)"切換
    3.K2/K3(V+/V-)鍵:"電壓/每格"調(diào)整.(1V/0.5V/0.2V/0.1V輪流切換)
    4.K4/K5(T+/T-)鍵:"正常顯示狀態(tài)"時(shí)為"時(shí)間/每格"調(diào)整."波形凍結(jié)"狀態(tài)時(shí)為"波形左右平移".
    設(shè)置模式:
    1.K2/K3(V+/V-)鍵:(短按)分別+/-調(diào)整對(duì)比度值.
    2.K6(Grid)鍵:(短按)存入默認(rèn)參數(shù)及當(dāng)前的對(duì)比度值,并退出.
*/

單片機(jī)源程序如下:
  1. #include <stdio.h>
  2. #include <intrins.h>
  3. #include "ADC.h"
  4. #include "PCA.h"
  5. //#include "Chars.h"
  6. #include "EEPROM.h"
  7. #include "LCD12864(ks0108).h"
  8. #include "STC15.h"

  9. //時(shí)間/每格3-10ms 4-5ms 5-2ms 6-1ms 7-500us 8-200us 9-100us 10-50us 11-20us 12-10us
  10. unsigned char timpd;                        
  11. unsigned char volpd;                                        //示波器 電壓/每格 1--1V/d,2--0.5V/d,3--0.2V/d
  12. unsigned long freqin;                                        //示波器輸入的信號(hào)頻率,單位Hz
  13. unsigned int  T1count;                                        //T1定時(shí)器,頻率計(jì)數(shù)
  14. unsigned int  PCA0loop;                                        //PCA0循環(huán)初值
  15. unsigned int  PCA1loop;                                        //PCA1循環(huán)初值
  16. unsigned int  PCA0count;                                //PCA0計(jì)時(shí)累計(jì)
  17. unsigned int  PCA1count;                                //PCA1循環(huán)遞增值,即輸出方波周期/2.5
  18. unsigned int  samptime;                                        //采樣時(shí)間,即定時(shí)器0的初值
  19. unsigned int  T0count;                                        //定時(shí)器采樣時(shí)間間隔計(jì)數(shù)
  20. unsigned int  index;                                        //每次采樣的wave0數(shù)組下標(biāo)
  21. unsigned int  shiftindex;                                //移位時(shí)數(shù)組下標(biāo)位置
  22. unsigned char hold;                                                //hold鍵標(biāo)志位
  23. unsigned char autotim;                                        //是否根據(jù)頻率自動(dòng)選擇時(shí)間每格,是=1,否=其它
  24. unsigned char shift;                                        //hold狀態(tài)移位標(biāo)志位。1、左移;2、右移
  25. //unsigned char grid;                                        //點(diǎn)格樣式
  26. unsigned char shap;                                            //波形失真修正,上下輪流顯示
  27. unsigned char ROMEN;                                        //需要寫EEPROM時(shí)=0x55;不需要=其它
  28. unsigned char EEPROM[5];                                //四字節(jié)掉電保存數(shù)據(jù),點(diǎn)格樣式,時(shí)間/每格,電壓/每格,波形樣式,自動(dòng)選時(shí)間檔
  29. unsigned char idata wave[127];                        //當(dāng)前顯示數(shù)組
  30. unsigned char xdata wave0[512];                        //采樣數(shù)組,處于不斷更新狀態(tài)
  31. unsigned char xdata wavep[512];                        //顯示及HOLD緩存數(shù)組

  32. //******************************************************************//
  33. //小于100us/div(50/20/10)采用直接采樣,軟件延時(shí)
  34. //大于等于100us/div采用定時(shí)器采樣
  35. //******************************************************************//

  36. void main(void)
  37. {
  38.         unsigned char disp;                                        //disp顯示刷新標(biāo)志位
  39.         unsigned char grid;                                        //點(diǎn)格樣式
  40.         unsigned char wavemode;                                //波形樣式
  41. //        unsigned char volmax;        
  42.         unsigned int i,j;
  43.         unsigned int delaybtn;                                //按鍵消抖延時(shí)
  44.         unsigned long int delay,delaymin,freqauto;        

  45.         disp=0;
  46.     freqin=0;
  47.         autotim=0;                                                        //默認(rèn)設(shè)置,手動(dòng)
  48.         timpd=8;                                                        //默認(rèn)設(shè)置200us/div                                                        
  49.         volpd=1;                                                        //默認(rèn)設(shè)置1V/div                                       
  50.         index=0;                                                            //賦值0非常重要
  51.         shiftindex=0;
  52.         T0count=0;
  53.         T1count=0;
  54.         PCA0loop=50000;                                                //PCA0定時(shí)20ms  //不分頻時(shí)PCA0loop=62500; 480個(gè)周期1s
  55.         PCA0count=0;
  56.         //PCA1loop=15000;                                                //PCA1(P1.4)輸出500Hz方波(產(chǎn)生LCD負(fù)壓),本程序沒開啟                                                
  57.         //PCA1count=15000;
  58.         hold=0;
  59.         shift=0;
  60.         grid=1;                                                                //默認(rèn)設(shè)置,坐標(biāo)線
  61.         wavemode=1;                                                        //默認(rèn)設(shè)置,粗線;=2細(xì)線
  62.         samptime=0xfee3;                                        //精確延時(shí)100us,此值嚴(yán)禁任何改動(dòng)samptime=0xfee2;        
  63.         EEPROM[0]=grid;
  64.           EEPROM[1]=timpd;  
  65.           EEPROM[2]=volpd;  
  66.         EEPROM[3]=wavemode;
  67.         EEPROM[4]=autotim;
  68.         ROMEN=0x55;                                                        //臨時(shí)測(cè)試,正式必須=0;

  69.         //M1/M0:00弱上拉,01強(qiáng)推挽,10輸入(高阻),11開漏
  70.         P0M1=0x00;P0M0=0x00;                                //
  71.         P1M1=0xee;P1M0=0x11;                                //P1.0/P1.4推挽輸出,其余設(shè)為輸入
  72.         P2M1=0x00;P2M0=0x00;                                //
  73.         P3M1=0x00;P3M0=0x00;                                //

  74. //        init_st7565();                                                //12864初始化
  75.     init_ks0108();

  76. //        dispchar16(1,8,16,7,HZ1);                        //開機(jī)LOGO
  77.         write_string8(3,16,"www.crystalradio.cn");
  78. //        dispchar16(5,10,12,9,HZ2);

  79.         ADCinit();
  80.         timerinit();
  81.         PCAinit();

  82.         //for(i=500;i>0;i--)for(j=5000;j>0;j--);        //延時(shí)1

  83.         IAPReadData(0,5,EEPROM);                        //讀取上一次關(guān)機(jī)前最后的用戶設(shè)置
  84.         if((EEPROM[0]>=0)&&(EEPROM[0]<=2)&&(EEPROM[1]>=3)&&(EEPROM[1]<=16)
  85.         &&(EEPROM[2]>=1)&&(EEPROM[2]<=4)&&(EEPROM[3]>=1)&&(EEPROM[3]<=2)&&(EEPROM[4]==0)||(EEPROM[4]==1))
  86.         {                                                                        //讀取到合法設(shè)置則賦值,否則顯示默認(rèn)設(shè)置
  87.                 grid=EEPROM[0];
  88.                   timpd=EEPROM[1];  
  89.                   volpd=EEPROM[2];
  90.                 wavemode=EEPROM[3];
  91.              autotim=EEPROM[4];
  92.         }
  93.         
  94.         //for(i=500;i>0;i--)for(j=5000;j>0;j--);                //延時(shí)2

  95.         disp_grid(grid);                                        //顯示網(wǎng)格
  96.     disp_osc_settings();                                //顯示示波器設(shè)置

  97.         while(1)
  98.         {
  99.                 //---------------------1、采樣-----------------------//
  100.                 //按了HOLD鍵,采樣繼續(xù),但不允許對(duì)wavep緩存數(shù)組更新
  101.                 if(hold==0)
  102.                 {
  103.                         switch(timpd)        
  104.                         {
  105.                                 case  3:
  106.                                 case  4:                                        //5ms/div
  107.                                 case  5:                                        //2ms/div
  108.                                 case  6:                                        //1ms/div
  109.                                 case  7:                                        //500us/div
  110.                                 case  8:                                        //200us/div
  111.                                 case  9:                                        //100us/div
  112.                                 {
  113.                                         TR0=1;ET0=1;
  114.                                         if(index>=511)                        
  115.                                         {
  116.                                                 for(i=0;i<512;i++)
  117.                                                 {
  118.                                                         wavep[i]=wave0[i];
  119.                                                 }
  120.                                                 index=0;                        //采樣下一組數(shù)據(jù)
  121.                                                 disp=1;                                //刷新標(biāo)志置位
  122.                                         }
  123.                                         break;
  124.                                 }
  125.                                 case  10:                                        //50us/div
  126.                                 {        
  127.                                         TR0=0;ET0=0;
  128.                                         for(i=0;i<512;i++)                //50us/div
  129.                                         {
  130.                                                 wavep[i]=getADC(1);
  131.                                                 _nop_();_nop_();
  132.                                                 _nop_();_nop_();
  133.                                         }
  134.                                         disp=1;                                        //刷新標(biāo)志置位
  135.                                         break;
  136.                                 }
  137.                                 case  11:                                        //20us(40us插值得來)
  138.                                 {
  139.                                         TR0=0;ET0=0;
  140.                                         fastADC();
  141.                                         for(i=0;i<512;i++)          //賦值(包含插值運(yùn)算)
  142.                                         {
  143.                                                 if(!(i%2))
  144.                                                 {wavep[i]=wave0[i/2];}
  145.                                                 else
  146.                                                 {wavep[i]=(unsigned int)(wave0[i/2]+wave0[i/2+1])/2;}
  147.                                         }
  148.                                         disp=1;                                        //刷新標(biāo)志置位
  149.                                         break;
  150.                                 }
  151.                                 case  12:                                        //10us(40us兩次插值得來)
  152.                                 {
  153.                                         TR0=0;ET0=0;
  154.                                         fastADC();
  155.                                         for(i=0;i<512;i++)          //賦值(包含插值運(yùn)算)
  156.                                         {
  157.                                                 if(!(i%2))
  158.                                                 {wavep[i]=wave0[i/2];}
  159.                                                 else
  160.                                                 {wavep[i]=(unsigned int)(wave0[i/2]+wave0[i/2+1])/2;}
  161.                                         }
  162.                                         for(i=0;i<512;i++)          //賦值(包含插值運(yùn)算)
  163.                                         {
  164.                                                 wave0[i]=wavep[i];
  165.                                         }
  166.                                         for(i=0;i<512;i++)          //賦值(包含插值運(yùn)算)
  167.                                         {
  168.                                                 if(!(i%2))
  169.                                                 {wavep[i]=wave0[i/2];}
  170.                                                 else
  171.                                                 {wavep[i]=(unsigned int)(wave0[i/2]+wave0[i/2+1])/2;}
  172.                                         }
  173.                                         disp=1;                                        //刷新標(biāo)志置位
  174.                                         break;        
  175.                                 }
  176.                         }//switch(timpd)采樣結(jié)束
  177.                 }

  178.                 //-------------------2-1:波形觸發(fā)處理-----------------//
  179.                 if((disp==1)&&(hold==0))                        //接收到新數(shù)據(jù)且正常顯示時(shí)才處理
  180.                 {
  181.                         for(i=2;i<127;i++)               
  182.                         {
  183.                                 if( (((signed int)wavep[i-2]-127)<=0)&&(((signed int)wavep[i-1]-127)<=0)//&&(((signed int)wavep[i]-127)<=0)
  184.                                 &&(((signed int)wavep[i+1]-127)>=0)&&(((signed int)wavep[i+2]-127)>=0)&&(((signed int)wavep[i+3]-127)>0) )
  185.                                 {        
  186.                                         shiftindex=i;
  187.                                         break;
  188.                                 }               
  189.                         }
  190.                 }//if((disp==1)&&(hold==0))波形觸發(fā)處理結(jié)束

  191.                 //-------------------2-2:HOLD狀態(tài)移位處理-----------------//
  192.                 if(hold==1)
  193.                 {
  194.                         if(shift==2)                                        //左移
  195.                         {
  196.                                 shiftindex=shiftindex+9;
  197.                                 if((shiftindex+126)>=512)
  198.                                 {
  199.                                         shiftindex=shiftindex-9;
  200.                                 }
  201.                         }
  202.                         if(shift==1)                                        //右移
  203.                         {
  204.                                 shiftindex=shiftindex-9;        //注意無符號(hào)數(shù)
  205.                                 if(shiftindex>512)                        //相當(dāng)于判斷小于0
  206.                                 {
  207.                                         shiftindex=shiftindex+9;//防止無限遞減
  208.                                 }
  209.                         }
  210.                 }

  211.                 //-------------------3、電壓衰減處理-----------------//
  212.                 switch(volpd)                                        //此部分余數(shù)計(jì)算可能有問題,需改進(jìn)
  213.                 {
  214.                         case  1:                                        //1v/div
  215.                         {
  216.                                 for(i=0;i<127;i++)                  
  217.                                 {
  218.                                         if(((signed int)wavep[i+shiftindex]>=127))
  219.                                         {
  220.                                                 if(((wavep[i+shiftindex]-127)*35/256)<128)
  221.                                                         wave[i]=(unsigned int)(wavep[i+shiftindex]-127)*35/256+28;
  222.                                                 else
  223.                                                         wave[i]=(unsigned int)(wavep[i+shiftindex]-127)*35/256+29;
  224.                                         }
  225.                                         else
  226.                                         {
  227.                                                 if(((127-wavep[i+shiftindex])*35/256)<128)
  228.                                                         wave[i]=27-(unsigned int)(127-wavep[i+shiftindex])*35/256;
  229.                                                 else
  230. ……………………

  231. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
51hei.png
所有資料51hei提供下載:
簡(jiǎn)易示波器源程序stc15f2k60s2+12864(KS0108版)4ok.rar (1.17 MB, 下載次數(shù): 89)

回復(fù)

使用道具 舉報(bào)

ID:71233 發(fā)表于 2021-5-14 08:23 | 顯示全部樓層
看那附件,LCD12864是用并口模式驅(qū)動(dòng)的,而不是SPI方式
#define DATA P0

sbit RS=P2^5;               
sbit RW=P2^4;               
sbit EN=P2^3;               
sbit CS1=P2^2;               
sbit CS2=P2^1;               
sbit RST=P2^0;               



/*========write one byte command==============*/
void write_command(unsigned char cmd)
{
        Read_busy();
        RS=0;                                //選擇命令
        RW=0;                                //讀操作
        DATA=cmd;
        EN=1;                                //EN由1----0鎖存有效數(shù)據(jù)
        delay100ns(8);
        EN=0;
        delay100ns(8);
}
回復(fù)

使用道具 舉報(bào)

ID:600695 發(fā)表于 2021-5-14 13:14 | 顯示全部樓層
一塊屏幕怎么看主控芯片,都是黑膠
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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