现在可以提供下载了
- /*
- 废弃的显示屏示波器
- */
- #include <Arduino.h>
- #include <U8g2lib.h>
- #include <EEPROM.h>
- #ifdef U8X8_HAVE_HW_SPI
- #include <SPI.h>
- #endif
- U8G2_ST7565_EA_DOGM128_F_4W_SW_SPI u8g2(U8G2_R0,/*clock=*/5,/*data=*/4,/*cs=*/8,/*dc=*/6,/*reset=*/7);
- int input =A0; //采集信号输入口
- int Key_hold =12; //hold显示
- int Key_mode =13; //延时选择
- int dis_width =128; //显示屏宽度
- int dis_hight =64; //显示屏高度
- int x; //绘点座标
- int Buffer[128]; //缓存值储存数组
- long Freq; //频率
- float Vp_p,Vpp; //实际电压,峰值电压
- int Dr; //占空比
- int t,i1,i2,i3,V_min,V_max,V_mid,hold=0;
- float a,b;
- int mode=0;
- int adc_n=4;
- int dTime=1;
- //产生62.5K方波
- void pwm_62_5k()
- {
- cli(); //禁止中断
- pinMode(9, OUTPUT);
- pinMode(10, OUTPUT);
- //设置timer1快速pwm,频率62.5kHz,D9 = OCR1A; D10 = OCR1B
- TCCR1A = 0;
- TCCR1B = 0;
- //比较匹配时清零 OC1A/OC1B
- TCCR1A |= _BV(COM1A1) | _BV(COM1B1);
- //配置8位快速PWM, TOP = 0xFF
- TCCR1A |= _BV(WGM10);
- TCCR1B |= _BV(WGM12);
- //时钟无分频,输出频率: 16 MHz/1/256= 62500Hz
- TCCR1B |= _BV(CS10);
- OCR1A = 127; // 占空比127/255=50%
- OCR1B = 25.5; // 占空比25.5/255=10%
- sei(); //允许中断
- }
- void setup(void) {
- Serial.begin(115200);
- u8g2.begin();
- pinMode(input,INPUT); //A0要接20K下拉电阻到地
- pinMode(Key_hold,INPUT_PULLUP);//接1K下拉电阻低电平触发
- pinMode(Key_mode,INPUT_PULLUP); //采样模式和速率选择
- u8g2.setFont(u8g2_font_blipfest_07_tr);
- u8g2.setFontDirection(0);
- u8g2.setContrast(180); //设置屏幕对比度0-255
- pwm_62_5k();
- set_adc(16); //ADC 16分频模式采样
- pinMode(11,OUTPUT);
- analogWrite(11,127);
- }
- void loop(void) {
- sample(); //ADC采样
- Measure(); //测量参数
- Transform(); //计算坐标
- u8g2.firstPage(); //清屏
- if (hold==0){ //冻结显示
- do{draw();}
- while (u8g2.nextPage());
- }
- san_key();
- }
- //寄时器中断处理A0-A5
- ISR(PCINT1_vect){
- /*ADC中断
- 放在setup内
- PCMSK1 |= bit (PCINT8); //PCINT8关联A0中断
- PCIFR |= bit (PCIF1);
- PCICR |= bit (PCIE1);
- */
- }
- //使用寄时器ADC采样,analogRead(pin)函数的采样速率太慢
- void sample(){
- ADCSRA |= _BV(ADSC); //第一次读数不准
- for(x = 0;x < dis_width;x++){
- ADCSRA |= _BV(ADSC);
- loop_until_bit_is_set(ADCSRA, ADIF);
- Buffer[x] = ADC;
- bitClear(ADCSRA, ADIF);
- //暂停x微秒
- //delayMicroseconds(dTime);
- }
- }
- //测量参数
- void Measure(){
- V_max=Buffer[0];//取最大值
- V_min=Buffer[0];//取最小值
- for(x=0;x<dis_width;x++){
- if(Buffer[x]>V_max)
- V_max=Buffer[x];
- if(Buffer[x]<V_min)
- V_min=Buffer[x];
- }
- //平均值=(最大值+最小值)/2
- V_mid=(V_max+V_min)/2;
- //振幅电压=(最大值+最小值)/2*基准电压/1023
- Vp_p=(V_max+V_min)/2*4.99/1023;
- //峰值电压=(最大值-最小值)*基准电压/1023
- Vpp=(V_max-V_min)*4.99/1023;
- for(x=0;x<dis_width-2;x++){
- //周期开始点
- if(Buffer[x]<V_mid&&Buffer[x+1]>=V_mid)
- {i1=x;break;}
- }
- for(x=i1+1;x<dis_width-2+i1;x++){
- //周期内高电平结束点
- if(Buffer[x]>V_mid&&Buffer[x+1]<=V_mid)
- {i3=x;}
- //周期结束点
- if(Buffer[x]<V_mid&&Buffer[x+1]>=V_mid)
- {i2=x;break;}
- }
- //周期时间=周期结速点-周期开始点
- t=i2-i1;
- //高电平时间=高电平结束时间-周期开始点
- a=(i3-i1);
- //占空比=高电平时间/周期时间(高电平时间+低电平时间)
- Dr=a/t*100;
- //频率=1000000/周期时间(高电平时间+低电平时间)
- if(t>1){
- if(adc_n<=16){
- Freq=16000000/adc_n/t; //16分频模式
- }else if(adc_n>16){
- Freq=16000000/255/adc_n;//非16分频模式
- }
- }else{
- Freq=0;
- }
- if(mode==0){
- //自动选择采样速率以适应高频低频信号
- if(t>30||t<10){
- adc_n=adc_n*2;
- if(adc_n>128){adc_n=4;}
- set_adc(adc_n);
- }
- }
- }
- //计算座标
- void Transform(){
- for(x = 0;x < dis_width;x++){
- //使用map函数将0-1023的模拟值映射为7~62之间的坐标值
- Buffer[x] = map(Buffer[x],0,1023,55,7);
- }
- }
-
- //显示
- void draw(){
- int dis_h=dis_hight/2;
- //显示电压峰值
- u8g2.drawStr(6,7, "V:");
- u8g2.setCursor(13, 7);
- u8g2.print(Vpp);
- //显示实际电压
- u8g2.drawStr(35,7, "Vp:");
- u8g2.setCursor(45, 7);
- u8g2.print(Vp_p);
- //显示频率
- u8g2.drawStr(68,7, "Hz:");
- u8g2.setCursor(78, 7);
- u8g2.print(Freq);
- //显示占空比
- u8g2.drawStr(105,7, "DR:");
- u8g2.setCursor(115, 7);
- u8g2.print(Dr);
- //画x坐标轴
- u8g2.drawLine(0,dis_h,dis_width,dis_h);
- //画y坐标轴
- u8g2.drawLine(dis_hight,7,dis_hight,dis_width);
- //画边框
- u8g2.drawFrame(4,0,124,dis_hight);
- for(int x=1;x<dis_width;x++){
- //显示波形
- u8g2.drawLine(x,Buffer[x],x,Buffer[x+1]);
- }
- for(x=0;x<dis_width;x+=4){
- //画x坐标刻度
- u8g2.drawLine(x,dis_h-1,x,dis_h+1);
- if (x<=dis_hight-14){
- //画Y坐标刻度
- u8g2.drawLine(dis_hight-1,x+7,dis_hight+1,x+7);
- }
- }
- //ADC采样模式,采样速率
- if(mode==0){
- u8g2.drawStr(6,62, "A:");//自动选频
- }else{
- u8g2.drawStr(6,62, "M:");//手动设置
- }
- u8g2.setCursor(12,62);
- u8g2.print(adc_n);
- //发送数据给显示屏
- u8g2.sendBuffer();
- }
- void san_key(){
- if(digitalRead(Key_hold)==LOW){
- while(digitalRead(Key_hold)==LOW);
- hold=~hold;
- }
- if(digitalRead(Key_mode)==LOW){
- while(digitalRead(Key_hold)==LOW);
- mode=mode+1;
- if(mode>6){mode=0;Serial.print(0,DEC);}
- if(mode!=0){
- adc_n=adc_n*2;
- if(adc_n>128){adc_n=4;}
- set_adc(adc_n);
- }
-
- }
- }
- //配置 ADC,提高ADC采样速率
- void set_adc(int key) {
- ADMUX = _BV(REFS0); // 使用A0脚采样,精度为(0-1023)
- //ADMUX=_BV(REFS0)|_BV(ADLAR)|0; //精度降为(0-255)
- switch (key){
- case 4://ADC Prescaler = 4
- //理论 Sample Rate可达16MHz/4/13=307.6KHz
- ADCSRA &= ~(1 << ADPS2); // 0
- ADCSRA |= (1 << ADPS1); // 1
- ADCSRA &= ~(1 << ADPS0); // 0
- break;
- case 8://ADC Prescaler = 8
- //理论 Sample Rate可达16MHz/8/13=153.8KHz,实测93.5KH
- ADCSRA &= ~(1 << ADPS2); // 0
- ADCSRA |= (1 << ADPS1); // 1
- ADCSRA |= (1 << ADPS0); // 1
- break;
- case 16://ADC Prescaler = 16
- //理论 Sample Rate 可达16MHz/32/13=76.8KHz
- ADCSRA |= (1 << ADPS2); // 1
- ADCSRA &= ~(1 << ADPS1); // 0
- ADCSRA &= ~(1 << ADPS0); // 0
- break;
- case 32://ADC Prescaler = 32
- //理论 Sample Rate 可达16MHz/32/13= 38.4KHz
- ADCSRA |= (1 << ADPS2); // 1
- ADCSRA &= ~(1 << ADPS1); // 0
- ADCSRA |= (1 << ADPS0); // 1
- break;
- case 64://ADC Prescaler = 64
- //理论 Sample Rate 可达16MHz/64/13= 19.2KHz
- ADCSRA |= (1 << ADPS2); // 1
- ADCSRA |= (1 << ADPS1); // 1
- ADCSRA &= ~(1 << ADPS0); // 0
- //ADCSRA = ADCSRA&(~7)|0x06;
- break;
- case 128://ADC Prescaler = 128
- //理论 Sample Rate 可达16MHz/128/13=9600Hz
- ADCSRA |= (1 << ADPS2); // 1
- ADCSRA |= (1 << ADPS1); // 1
- ADCSRA |= (1 << ADPS0); // 1
- break;
- default:
- break;
- }
- }
复制代码
|