PIC30F4013 示波器
製作一個 PIC30F4013 示波器需要以下零件:PIC30F4013 微控制器
128x64 黑白 OLED 顯示屏
AD9288 8 位類比數位轉換器(ADC)
LM324 動態增益放大器(AGC)
74HC14 門電路(用於產生觸發信號)
電容和電阻等零件
電源模組
以下是 PIC30F4013 的連結腳位:
VDD:供應電源正極
VSS:供應電源負極
OSC1:晶體振盪器輸入
OSC2:晶體振盪器輸出
AN0-AN15:類比輸入通道
RA0-RA7:數位輸入/輸出通道
RB0-RB7:數位輸入/輸出通道
RD0-RD7:數位輸入/輸出通道
以下是這個示波器的基本程式碼,該程式碼使用 C 語言編寫:
#include <p30f4013.h>
// 定義 ADC 通道
#define ADC_CHN 0
// 定義 OLED 顯示屏寬度和高度
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// 定義 ADC 值緩存區大小
#define ADC_BUFFER_SIZE 256
// 定義觸發模式(自由模式、單次模式)
#define TRIG_MODE_FREE 0
#define TRIG_MODE_SINGLE 1
// 定義觸發邊緣(上升沿、下降沿、兩極性)
#define TRIG_EDGE_RISING 0
#define TRIG_EDGE_FALLING 1
#define TRIG_EDGE_BOTH 2
// 定義觸發狀態(等待觸發、觸發中、已觸發)
#define TRIG_STATUS_WAITING 0
#define TRIG_STATUS_TRIGGERING 1
#define TRIG_STATUS_TRIGGERED 2
// 定義控制 LED 燈的宏
#define LED_ON 0
#define LED_OFF 1
// 定義控制觸發 LED 燈的宏
#define TRIG_LED_ON 0
#define TRIG_LED_OFF 1
// 定義 AGC 增益表
const int AGC_GAIN_TABLE = {0, 1, 2, 4, 8, 16, 32, 64};
// 定義 ADC 緩存區
unsigned int adc_buffer;
// 定義 ADC 緩存區指針
unsigned int adc_buffer_ptr = 0;
// 定義觸發模式和觸發邊緣
unsigned char trig_mode = TRIG_MODE_FREE;
unsigned char trig_edge = TRIG_EDGE_RISING;
// 定義觸發狀態和觸發閾值
unsigned char trig_status = TRIG_STATUS_WAITING;
unsigned int trig_threshold = 512;
// 定義 LED 燈狀態
unsigned char led_status = LED_OFF;
unsigned char trig_led_status = TRIG_LED_OFF;
// 設置 ADC 轉換參數
void setup_adc() {
// 設置 ADC 輸入通道
ADPCFG = ~(1 << ADC_CHN);
// 設置 ADC 轉換參數
ADCON1bits.ADON = 1; // 啟用 ADC
ADCON1bits.ADRC = 0; // 使用系統時鐘
ADCON1bits.SSRC = 7; // 自動轉換
ADCON1bits.FORM = 0; // 整數輸出
ADCON1bits.SIMSAM = 0; // 單通道
ADCON2bits.CHPS = 0; // 設置通道 0
ADCON2bits.SMPI = 0; // 單次轉換
ADCON2bits.BUFM = 0; // 16 位緩存區
ADCON2bits.ALTS = 0; // 輪流掃描通道
ADCON3bits.SAMC = 31; // 31 TAD 的採樣時間
ADCON3bits.ADRC = 0; // 使用系統時鐘
ADCON3bits.ADCS = 63; // 時鐘分頻器設置為 63
ADCHSbits.CH0SA = ADC_CHN; // 選擇通道 0
}
// 讀取 ADC 值
unsigned int read_adc() {
ADCHSbits.CH0SA = ADC_CHN; // 選擇通道 0
ADCON1bits.SAMP = 1; // 啟動採樣
while (!ADCON1bits.DONE); // 等待轉換完成
return ADCBUF0; // 返回轉換結果
}
// 設置觸發閾值
void set_trig_threshold(unsigned int threshold) {
trig_threshold = threshold;
}
// 設置觸發模式
void set_trig_mode(unsigned char mode) {
trig_mode = mode;
}
// 設置觸發邊緣
void set_trig_edge(unsigned char edge) {
trig_edge = edge;
}
// 設置 AGC 增益
void set_agc_gain(unsigned char gain) {
int agc_gain = AGC_GAIN_TABLE;
// TODO: 設置 AGC 增益
}
// 設置 LED 燈狀態
void set_led(unsigned char status) {
led_status = status;
// TODO: 控制 LED 燈
}
// 設置觸
void set_trig_led(unsigned char status) {
trig_led_status = status;
// TODO: 控制觸發 LED 燈
}
// 檢查是否觸發
void check_trig(unsigned int adc_value) {
if (trig_status == TRIG_STATUS_WAITING) { // 等待觸發
if (trig_mode == TRIG_MODE_AUTO && adc_value >= trig_threshold) { // 自動觸發
trig_status = TRIG_STATUS_TRIGGERED;
} else if (trig_mode == TRIG_MODE_NORMAL && trig_edge == TRIG_EDGE_RISING && adc_value >= trig_threshold) { // 正緣觸發
trig_status = TRIG_STATUS_TRIGGERED;
} else if (trig_mode == TRIG_MODE_NORMAL && trig_edge == TRIG_EDGE_FALLING && adc_value <= trig_threshold) { // 負緣觸發
trig_status = TRIG_STATUS_TRIGGERED;
}
} else if (trig_status == TRIG_STATUS_TRIGGERED) { // 已觸發
if (trig_mode == TRIG_MODE_AUTO) { // 自動觸發
trig_status = TRIG_STATUS_WAITING;
} else if (trig_mode == TRIG_MODE_NORMAL && trig_edge == TRIG_EDGE_RISING && adc_value < trig_threshold) { // 正緣觸發
trig_status = TRIG_STATUS_WAITING;
} else if (trig_mode == TRIG_MODE_NORMAL && trig_edge == TRIG_EDGE_FALLING && adc_value > trig_threshold) { // 負緣觸發
trig_status = TRIG_STATUS_WAITING;
}
}
}
// 主函數
void main(void) {
// 初始化
setup_adc();
set_trig_threshold(512);
set_trig_mode(TRIG_MODE_AUTO);
set_trig_edge(TRIG_EDGE_RISING);
set_agc_gain(AGC_GAIN_0);
set_led(LED_OFF);
set_trig_led(TRIG_LED_OFF);
while (1) {
unsigned int adc_value = read_adc(); // 讀取 ADC 值
check_trig(adc_value); // 檢查是否觸發
// TODO: 繪製波形圖
}
}
頁:
[1]