|
OLED數(shù)字示波器 基于STC8A8K64S4A12單片機(jī) 原作者 老劉愛搗鼓 PCB板是在B站的一個(gè)大佬那下載然后改的 希望大家喜歡
功能.png (82.9 KB, 下載次數(shù): 106)
下載附件
2020-10-17 14:12 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (18.61 KB, 下載次數(shù): 130)
下載附件
2020-10-17 17:03 上傳
51hei.png (26.84 KB, 下載次數(shù): 118)
下載附件
2020-10-17 17:03 上傳
51hei.png (3.28 KB, 下載次數(shù): 138)
下載附件
2020-10-17 17:03 上傳
單片機(jī)源程序如下:
- 簡易示波器
- 版本:V0.3
- 作者:老劉愛搗鼓
- 單片機(jī)型:STC8A8K64S4A12 @27MHz
- 老劉愛搗鼓(全網(wǎng)同名)期待您的關(guān)注!
- B站教程(初版):https://www.bilibili.com/video/BV1ai4y1t79R
- B站教程(V0.3):https://www.bilibili.com/video/BV1ai4y1t79R
- 操作說明:
- 主界面-選項(xiàng)設(shè)置模式:
- 單擊編碼器:切換開始/暫停采樣
- 雙擊編碼器:切換波形水平滾動(dòng)模式/選項(xiàng)設(shè)置模式
- 長按編碼器:進(jìn)入設(shè)置界面
- 旋轉(zhuǎn)編碼器:修改當(dāng)前參數(shù)
- 按下同時(shí)旋轉(zhuǎn)編碼器:在參數(shù)間切換
-
- 主界面-波形水平滾動(dòng)模式:
- 單擊編碼器:切換開始/暫停采樣
- 雙擊編碼器:切換波形水平滾動(dòng)模式/選項(xiàng)設(shè)置模式
- 長按編碼器:進(jìn)入設(shè)置界面
- 旋轉(zhuǎn)編碼器:水平滾動(dòng)波形(在暫停采樣狀態(tài)下有效)
- 按下同時(shí)旋轉(zhuǎn)編碼器:垂直滾動(dòng)波形(僅在暫停采樣狀態(tài)下有效)
-
- 設(shè)置界面:
- 單擊編碼器:無效
- 雙擊編碼器:無效
- 長按編碼器:返回主界面
- 旋轉(zhuǎn)編碼器:修改當(dāng)前選項(xiàng)
- 按下同時(shí)旋轉(zhuǎn)編碼器:切換選項(xiàng)
- 主界面參數(shù):
- 橫軸時(shí)間區(qū)間:"500ms", "200ms", "100ms", "50ms", "20ms", "10ms","5ms", "2ms", "1ms", "500us", "200us", "100us"(100us僅在自動(dòng)觸發(fā)模式下可用)
- 縱軸電壓區(qū)間:設(shè)定電壓量程上限,最大30V,順時(shí)針旋轉(zhuǎn)編碼器將電壓上限設(shè)置為0則進(jìn)入自動(dòng)量程,逆時(shí)針旋轉(zhuǎn)進(jìn)入手動(dòng)量程
- 觸發(fā)值:設(shè)定觸發(fā)電壓值,觸發(fā)位置被放在屏幕中心
- 觸發(fā)方向:上下箭頭,分別代表上升沿觸發(fā)和下降沿觸發(fā)
- 觸發(fā)方式:
- Auto(自動(dòng)觸發(fā)) :連續(xù)采樣,指示燈始終點(diǎn)亮,通過單擊編碼器控制啟停;觸發(fā)成功時(shí),觸發(fā)點(diǎn)位于屏幕中心,觸發(fā)失敗則波形無規(guī)律滾動(dòng),屏幕左側(cè)顯示Fail標(biāo)志
- Normal(普通觸發(fā)):等待預(yù)采樣,待指示燈亮起表示預(yù)采樣結(jié)束,這時(shí)可以輸入信號(hào);
- 觸發(fā)成功后,顯示波形,并繼續(xù)等待下次觸發(fā);
- 如果有新的觸發(fā)成功,則自動(dòng)顯示新的波形,如沒有新的觸發(fā)成功則屏幕波形保持并一直等待下次觸發(fā);
- 需注意設(shè)置正確的觸發(fā)值,否則一直處于等待觸發(fā)狀態(tài),屏幕不會(huì)顯示波形
- Single(單次觸發(fā)):等待預(yù)采樣,待指示燈亮起表示預(yù)采樣結(jié)束,這時(shí)可以輸入信號(hào);
- 觸發(fā)成功后,顯示波形,并停止采樣,需用戶單擊編碼器開始下次采樣
- 需注意設(shè)置正確的觸發(fā)值,否則一直處于等待觸發(fā)狀態(tài),屏幕不會(huì)顯示波形
-
- 主界面狀態(tài)顯示:
- Run:正在采樣
- Stop:停止采樣
- Fail:自動(dòng)模式下,觸發(fā)值超出波形范圍引起觸發(fā)失敗
- Auto:自動(dòng)量程
-
- 設(shè)置界面選項(xiàng):
- PMode(繪圖模式):
- Vector:波形以矢量顯示
- Dots :波形以點(diǎn)陣顯示
- LSB(采樣系數(shù)):分壓系數(shù)的100倍,比如用10k加2k的電阻進(jìn)行分壓,分壓系數(shù)為(10+2/2)=6,LSB理論取值為6x100=600,根據(jù)實(shí)際電阻精度進(jìn)行微調(diào)
- BRT:OLED亮度
- 保存設(shè)置:長按編碼器退出設(shè)置界面時(shí),設(shè)置界面和主界面的所有參數(shù)被保存到EEPROM
- 2020-04-30更新
- 1. 增加單次觸發(fā)和普通觸發(fā)功能,可自定義觸發(fā)點(diǎn)用來捕捉波形變化
- 2. 按照規(guī)格書要求將ADC采樣端口設(shè)置為高阻輸入
- 2020-5-3更新
- 1. 增加波形頻率顯示
- 2. 使用編碼器水平/垂直滾動(dòng)波形
- 3. 使用編碼器垂直縮放波形
- 4. 用戶可設(shè)定觸發(fā)電平
- */
- #include <reg51.h>
- #include "global.h"
- #include "delay.h"
- #include "adc_stc8.h"
- #include "config_stc.h"
- #include "settings.h"
- #include "chart.h"
- #include "ssd1306.h"
- // #include "uart.h"
- // #include "stdio.h"
- #define VBAT_UPDATE_FREQ 40 //電池電壓信息的更新頻率 VBAT_UPDATE_FREQ*25ms
- #define VBAT_LSB 600 //電池電壓采樣分壓系數(shù)*100
- #define INT_0 0 //外部中斷0序號(hào),編碼器旋轉(zhuǎn)
- #define INT_1 2 //外部中斷1序號(hào),編碼器按下
- #define TIMER_0 1 //定時(shí)器0中斷序號(hào)
- void init()
- {
- InSettings = 0; //初始化開機(jī)界面
- OptionInSettings = 0; //初始化設(shè)置界面的選項(xiàng)編號(hào)
- OptionInChart = 0; //初始化主界面的選項(xiàng)標(biāo)號(hào)
- WaveScroll = 0; //清零波形滾動(dòng)標(biāo)志
- OptionChanged = 0; //清零設(shè)置修改標(biāo)志
- ADCRunning = 1; //置位采樣標(biāo)志
- ADCInterrupt = 0; //清零ADC中斷標(biāo)志
- ADCComplete = 0; //清零ADC完成標(biāo)志
- WaveUpdate = 0; //清零波形更新標(biāo)志
- ClearWave = 0; //清零清除波形標(biāo)志
- ClearDisplay = 1; //置位清空屏幕標(biāo)志
- EC11PressAndRotate = 0; //清零編碼器旋轉(zhuǎn)標(biāo)志
- UpdateVbat = 0; //清零采樣電池電壓標(biāo)志
- ADCComplete = 0; //清零ADC完成采樣標(biāo)志
- WaveFreq = 0; //清零波形頻率
- TriPos = 50; //初始化觸發(fā)點(diǎn)位置
- TriPosOffset = 0; //初始化觸發(fā)點(diǎn)偏移量
- TriFail = 0; //清零觸發(fā)失敗標(biāo)志
- VMax = 0; //清零波形電壓最大值
- VMin = 0; //清零波形電壓最小值
- WaveLengthSumNum = 0; //清零波形長度求和次數(shù)
- WaveLengthSum = 0; //清零波形長度求和
- /* 波形滾動(dòng)模式下正在采樣則禁用外部中斷0(編碼器旋轉(zhuǎn))
- Disable external interrupt 0(Encoder rotation) in waveform scroll mode when sampling*/
- if (ADCRunning && WaveScroll)
- EX0 = 0;
- /* 獲取內(nèi)部參考電壓值
- Get internal reference voltage */
- BGV = GetBGV();
- }
- void runWhenInSettrings()
- {
- P_Ready = 0;
- ClearDisplay = 1;
- while (InSettings)
- {
- /* 更新電池電壓信息
- Update voltage infor of battery */
- if (UpdateVbat)
- {
- UpdateVbat = 0;
- VBat = GetVoltage(ADC_BAT, VBAT_LSB);
- }
- /* 更新屏幕亮度
- Update OLED Brightness */
- if (OLED_BrightnessChanged)
- {
- OLED_BrightnessChanged = 0;
- OLED_Write_Command(0x81);
- OLED_Write_Command(OLED_Brightness * 10);
- }
- /* 更新參數(shù)
- Update parameters */
- if (DisplayUpdate)
- {
- DisplayUpdate = 0;
- PlotSettings();
- OLED_Display();
- }
- }
- /* 保存設(shè)置
- Save Settings */
- EA = 0;
- if (OptionChanged)
- {
- OptionChanged = 0;
- ClearDisplay = 0;
- /* 保存設(shè)置并顯示保存狀態(tài)
- Save settings and display saving status*/
- PlotSaveStatus(Save_Options());
- OLED_Display();
- Delay1000ms();
- }
- /* 退出settings后刷新屏幕
- Redraw display after exit settings */
- ClearDisplay = 1;
- PlotChart();
- OLED_Display();
- IE0 = 0;
- IE1 = 0;
- EA = 1;
- }
- /*
- ADCRuning=1
- | WaveUpdate=1
- | | ClearWave=1
- | | ClearWave=0
- | WaveUpdate=0
- ADCRuning=0
- DisplayUpdate=1
- WaveUpdate=1
- | ClearWave=1
- | ClearWave=0
- WaveUpdate=0
- */
- void runWhenADCInterrupt()
- {
- ADCInterrupt = 0;
- P_Ready = 0;
- /* ADC采樣運(yùn)行
- ADC Sampling Running */
- if (ADCRunning)
- {
- EX0 = 0;
- if (WaveUpdate)
- {
- WaveUpdate = 0;
- ClearDisplay = 1;
- /* 清空波形緩存
- Clear waveform in buffer*/
- if (ClearWave)
- {
- ClearWave = 0;
- memset(ADCbuf, 0x00, SAMPLE_NUM * 2);
- WaveFreq = 0;
- TriFail = 0;
- VMax = 0;
- VMin = 0;
- PlotChart();
- }
- /* 顯示緩存中的波形
- Display waveform in buffer*/
- else
- {
- AnalyseData();
- PlotChart();
- PlotWave();
- }
- }
- else
- {
- ClearDisplay = 0;
- PlotChart();
- }
- OLED_Display();
- /* ADCRuning和WaveScroll同時(shí)置位時(shí),不開啟外部中斷0(編碼器旋轉(zhuǎn))
- Not to enable external interrupt 0(Encoder Rotation) when both of ADCRunning and WaveScroll set. */
- if (!WaveScroll)
- {
- IE0 = 0;
- EX0 = 1;
- }
- }
- /* ADC采樣停止
- ADC Sampling Stopped */
- else
- {
- while (!ADCRunning && !InSettings)
- {
- if (DisplayUpdate)
- {
- EX0 = 0;
- DisplayUpdate = 0;
- if (WaveUpdate)
- {
- WaveUpdate = 0;
- /* 分析緩存中完成采樣的采樣數(shù)據(jù)
- Analyse completed sampling data in buffer */
- AnalyseData();
- ClearDisplay = 1;
- /* 清空屏幕,繪制波形
- Clear display and draw waveform */
- if (ScaleH == ScaleH_tmp)
- {
- /* 采樣點(diǎn)數(shù)有限,不支持橫向縮放波形,只有時(shí)間區(qū)間與完成采樣的時(shí)間區(qū)間相同才繪制波形
- Since the sampling points limitation, scaling waveform along horizontal is not support.
- Show waveform only when time scale is same as that when sampling completed */
- PlotChart();
- PlotWave();
- }
- /* 清空屏幕,不繪制波形
- Clear display and no waveform */
- else
- {
- WaveFreq = 0; //清零WaveFreq,繪制界面時(shí),頻率位置會(huì)顯示****Hz
- PlotChart();
- }
- }
- /* 只更新屏幕上的參數(shù),波形不變
- Update parameters on display only, keep waveform */
- else
- {
- ClearDisplay = 0;
- PlotChart();
- }
- OLED_Display();
- IE0 = 0;
- EX0 = 1;
- }
- }
- }
- }
- void runWhenADCComplete()
- {
- /* ADC采樣完成 - 單次觸發(fā)
- ADC Sampling Complete - Single Trigger Mode */
- if (TriMode == 2)
- {
- EX0 = 0;
- ADCInterrupt = 1;
- DisplayUpdate = 0;
- WaveUpdate = 0;
- ADCRunning = 0; //清零ADC運(yùn)行標(biāo)志,停止采樣
- AnalyseData();
- ClearDisplay = 1;
- PlotChart();
- PlotWave();
- OLED_Display();
- IE0 = 0;
- EX0 = 1;
- }
- /* ADC采樣完成 - 自動(dòng)觸發(fā)或普通觸發(fā)
- ADC Sampling Complete - Auto or Normal Trigger Mode */
- else
- {
- //EX0 = 0;
- ClearDisplay = 1; //置位清空屏幕標(biāo)志
- AnalyseData(); //分析采樣數(shù)據(jù)
- PlotChart(); //繪制主界面
- PlotWave(); //繪制波形
- OLED_Display();
- //IE0 = 0;
- //EX0 = 1;
- }
- }
- /* 程序入口
- Program Entry */
- void main()
- {
- /* 將ADC端口P0.4,P0.6設(shè)置為高阻
- Set ADC port P0.4, P0.6 as high-impedance */
- P0M1 |= 0x50;
- P0M0 &= ~0x50;
- /* 設(shè)置指示燈端口P1.1為推挽輸出
- Set indicator port P1.1 as push-pull output */
- P0M1 &= ~0x02;
- P0M0 |= 0x02;
- /* 設(shè)置編碼器端口P3.2,P3.3,P3.4為準(zhǔn)雙向
- Set Encoder port P3.2, P3.3, P3.4 as quasi bidirectional */
- P3M1 &= ~0x1C;
- P3M0 &= ~0x1C;
- /* 設(shè)置OLED端口P2.3,P2.4,P2.5,P2.6,P2.7為準(zhǔn)雙向
- Set OLED port P2.3, P2.4, P2.5, P2.6 as quasi bidirectional */
- P2M1 &= ~0xF8;
- P2M0 &= ~0xF8;
- /* 編碼器旋轉(zhuǎn)外部中斷
- Interrupt for rotating of Encoder */
- IT0 = 0; //外部中斷0觸發(fā)方式,上升沿和下降沿
- PX0 = 1; //外部中斷0高優(yōu)先級(jí),可打斷按鍵中斷,用于判斷按下同時(shí)旋轉(zhuǎn)
- EX0 = 1; //開啟外部中斷0
- /* 編碼器按鍵外部中斷
- Interrupt for clicking of Encoder */
- IT1 = 1; //外部中斷1觸發(fā)方式,下降沿
- PX1 = 0; //外部中斷1低優(yōu)先級(jí)
- EX1 = 1; //開啟外部中斷1
- /* 定時(shí)器0,為更新電池電壓信息計(jì)時(shí)
- Timer 0, for updating voltage of battery */
- AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TL0 = 0x46; //設(shè)置定時(shí)初值 //27MHz,25ms
- TH0 = 0x24; //設(shè)置定時(shí)初值
- TF0 = 0; //清除TF0標(biāo)志
- ET0 = 1; //允許定時(shí)器0中斷
- /* 開總中斷
- Enable global interrupt */
- EA = 1;
- //UartInit();
- Read_Options();
- init();
- OLED_Init();
- OLED_SetFontWidth(6);
- PlotChart();
- OLED_Display();
- while (1)
- {
- P_Ready = 0;
- /* 采樣波形
- Sampling*/
- GetWaveData();
- /* 進(jìn)入設(shè)置界面
- Enter Settings Interface */
- if (InSettings)
- {
- runWhenInSettrings();
- }
- /* ADC采樣中斷
- ADC Sampling Interrupt */
- else if (ADCInterrupt)
- {
- runWhenADCInterrupt();
- }
- /* ADC采樣完成
- ADC Sampling Complete */
- else
- {
- runWhenADCComplete();
- }
- }
- }
- /* 分析編碼器旋轉(zhuǎn)
- Analyse Rotation of Encoder */
- void Scan_EC11(void)
- {
- /* 延時(shí)去抖動(dòng)
- Delay to remove jitter */
- Delay500us();
- /* 正轉(zhuǎn)
- Clockwise */
- if (EC11_A != EC11_B)
- {
- Change_Val(1);
- }
- /* 反轉(zhuǎn)
- Anticlockwise */
- else if (EC11_A == EC11_B)
- {
- Change_Val(0);
- }
- }
- /* 編碼器旋轉(zhuǎn)中斷
- Interrput for Encoder Rotated */
- void INT0_interrupt(void) interrupt INT_0
- {
- Delay500us();
- /* 編碼器是否被按下
- Whether the Encoder is pressed */
- if (!EC11_KEY)
- EC11PressAndRotate = 1;
- else
- EC11PressAndRotate = 0;
- Scan_EC11();
- ADCInterrupt = 1;
- DisplayUpdate = 1;
- IE1 = 0; //清零外部中斷1標(biāo)志位
- IE0 = 0; //清零外部中斷0標(biāo)志位
- }
- /* 編碼器點(diǎn)擊中斷
- Interrput for Encoder Pressed */
- void INT1_interrupt(void) interrupt INT_1
- {
- Delay50ms();
- if (!EC11_KEY)
- {
- EC11PressAndRotate = 0;
- /* 長按編碼器按鍵 - 切換主界面和設(shè)置界面
- Long presse Encoder - Switch main interface and settings interface */
- if (Delay800ms_Long_Press())
- {
- InSettings = ~InSettings;
- /* 進(jìn)入設(shè)置界面
- Enter Settings */
- if (InSettings)
- {
- DisplayUpdate = 1;
- UpdateVbat = 1;
- TF0 = 0; //清零定時(shí)器0溢出標(biāo)志
- TR0 = 1; //定時(shí)器0開始計(jì)時(shí),開始電池電壓信息更新計(jì)時(shí)
- IE0 = 0; //清零外部中斷0中斷標(biāo)志
- EX0 = 1; //開啟外部中斷0(編碼器旋轉(zhuǎn))
- }
- /* 回到主界面
- Retrurn to main interface */
- else
- {
- TR0 = 0; //清零定時(shí)器0溢出標(biāo)志
- TF0 = 0; //定時(shí)器0停止計(jì)時(shí),停止電池電壓信息更新計(jì)時(shí)
- WaveFreq = 0;
- TriFail = 0;
- VMax = 0;
- VMin = 0;
- DisplayUpdate = 1;
- WaveUpdate = 1;
- ClearWave = 0;
- }
- ADCInterrupt = 1;
- }
- /* 按住編碼器同時(shí)旋轉(zhuǎn)
- Rotate Encoder while pressing */
- else if (EC11PressAndRotate)
- {
- /* 由編碼器旋轉(zhuǎn)中斷執(zhí)行操作
- Operations Performed by Interrupt of Encoder Rotation */
- }
- /* 雙擊編碼器按鍵 - 在主界面,滾動(dòng)波形和選項(xiàng)模式之間切換
- Double click Encoder - Switch between Waveform Scroll Mode and Parameter Mode in Main Interface */
- else if (Delay300ms_Double_Click())
- {
- /* 主界面
- Main Interface*/
- if (!InSettings)
- {
- WaveScroll = ~WaveScroll;
- OptionChanged = 1;
- ADCInterrupt = 1;
- DisplayUpdate = 1;
- ClearWave = 0;
- }
- }
- /* 單擊編碼器按鍵 - 在主界面,切換Stop/Run狀態(tài)
- Single click Encoder - Switch Run/Stop in main interface */
- else if (!InSettings)
- {
- EX0 = 0;
- ADCRunning = ~ADCRunning;
- if (ADCRunning)
- {
- WaveUpdate = 1;
- ClearWave = 1;
- }
- else
- {
- DisplayUpdate = 1;
- WaveUpdate = 1;
- }
- ADCInterrupt = 1;
- IE0 = 0;
- IE1 = 0;
- }
- }
- IE1 = 0;
- }
- /* 為更新Vbat計(jì)時(shí)
- Timer for updating Vbat */
- void TIMER0_interrupt(void) interrupt TIMER_0
- {
- static uint8 n;
- if (++n >= VBAT_UPDATE_FREQ)
- {
- n = 0;
- UpdateVbat = 1;
- DisplayUpdate = 1;
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
老劉的示波器2.zip
(6.69 MB, 下載次數(shù): 362)
2020-10-17 14:09 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
MiniDSO簡易示波器_老劉愛搗鼓.zip
(561.99 KB, 下載次數(shù): 299)
2020-10-17 14:12 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|