完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
`这个DIY的示波器采样率0-1MHz左右
能显示峰值电压,实际电压,频率,占空比。 上代码: /* 农业银行U盾显示屏示波器 */ #include #include #include #ifdef U8X8_HAVE_HW_SPI #include #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 =11; //hold显示 int dis_width =128; //显示屏宽度 int dis_hight =64; //显示屏高度 int x; //绘点座标 int Buffer[128]; //缓存值储存数组 long Freq; //频率 float Vp_p,Vpp; //实际电压,峰值电压 int Hr; int i1,i2,i3,V_min,V_max,V_mid,t,hold=0; float a,b; //产生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); // 时钟无分频 //输出 A 频率: 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); pinMode(Key_hold,INPUT); digitalWrite(Key_hold,HIGH); u8g2.setFont(u8g2_font_blipfest_07_tr); u8g2.setFontDirection(0); u8g2.setContrast(180); //设置屏幕对比度0-255 pwm_62_5k(); set_adc(8); } void loop(void) { sample(); //采样 Measure(); //测量 Transform();//计算坐标 u8g2.firstPage();//清屏 if (hold==0){ do{draw();} while (u8g2.nextPage()); } san_key(); } /*ADC中断 放在setup内 PCMSK1 |= bit (PCINT8); // A0中断 PCIFR |= bit (PCIF1); // clear any outstanding interrupts PCICR |= bit (PCIE1); */ ISR(PCINT1_vect){ } //采样 void sample(){ for(x = 0;x < dis_width;x++){ ADCSRA |= _BV(ADSC); loop_until_bit_is_set(ADCSRA, ADIF); Buffer[x] = ADC; bitClear(ADCSRA, ADIF); //delayMicroseconds(800); //暂停x微秒 } } //测量 void Measure() { V_max=Buffer[0];//取最大值 V_min=Buffer[0];//取最小值 for(x=0;x if(Buffer[x]>V_max) V_max=Buffer[x]; if(Buffer[x] } //平均值 V_mid=(V_max+V_min)/2; Vp_p=(V_max+V_min)/2*4.98/1023; //计算电压 Vpp=(V_max-V_min)*4.98/1023; for(x=0;x if(Buffer[x] {i1=x;break;} } for(x=i1+1;x if(Buffer[x]>V_mid&&Buffer[x+1]<=V_mid) {i3=x;} if(Buffer[x] {i2=x;break;} } t=i2-i1; a=(i3-i1); //pwm占空比 Hr=a/t*100; if(t>0){ Freq=16000000/16/t; }else{ Freq=0; } } //显示 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(103,7, "Dr:"); u8g2.setCursor(115, 7); u8g2.print(Hr); //画x坐标轴 u8g2.drawLine(0,dis_h,dis_width,dis_h); //画y坐标轴 u8g2.drawLine(dis_hight,0,dis_hight,dis_width); //画边框 u8g2.drawFrame(4,0,124,dis_hight); //显示波形 for(int x=1;x u8g2.drawLine(x,Buffer[x],x,Buffer[x+1]); } //画x坐标刻度 for(x=0;x u8g2.drawLine(x,dis_h-1,x,dis_h+1); if (x<=dis_hight){ //画Y坐标刻度 u8g2.drawLine(dis_hight-1,x,dis_hight+1,x); } } //发送数据给显示屏 u8g2.sendBuffer(); } //计算座标 void Transform() { for(x = 0;x < dis_width;x++){ //Buffer[i]对等转换至62 – 7之间的数值。 Buffer[x] = map(Buffer[x],0,1023,62,7); //计算坐标 } } void san_key(){ if(digitalRead(Key_hold)==LOW) { while(digitalRead(Key_hold)==LOW); hold=~hold; } } void set_adc(int key) { //配置 ADC,提高ADC采样速率 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 可達 153KHz, 但實測93.5KH ADCSRA=_BV(ADEN)|_BV(ADSC)|_BV(ADPS2); ADCSRB=0; 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 ADCSRA = ADCSRA&(~7)|0x06; break; case 128://ADC Prescaler = 128 /* clock=16MHz/128=125KHz;一次ADC轉換要踢它13下, 就是要13 clock(tick),於是變成 125KHz/13 = 9600Hz */ ADCSRA |= (1 << ADPS2); // 1 ADCSRA |= (1 << ADPS1); // 1 ADCSRA |= (1 << ADPS0); // 1 break; default: break; } } ` |
|
相关推荐
|
|
你好,能分享下 这个屏幕的 PIN 定义吗?我有这个机器,和你一样的屏, 没有能力 确认 这个PIN 的定义, 以及怎么连接线, 能分享下吗?我邮箱 hbchenruyi@aliyun.comaliyun.com
|
|
|
|
|
|
怎么改变ADC采样率,里面的CASE4什么的怎么触发,只有一个暂停功能
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
WIO Terminal +MCP2515 实现车辆OBD的速度监控
9943 浏览 0 评论
60659 浏览 77 评论
5677 浏览 3 评论
一块扩展板完成Arduino的10类37项实验(代码+图形+仿真)
33110 浏览 219 评论
9835 浏览 0 评论
209浏览 1评论
【教程】使用Arduino和ATFC043彩屏将LM35温度数值图形化显示
4244浏览 1评论
2143浏览 1评论
请教:esp32中用u8g2显示shtc3传感器数据到i2c液晶屏,显示不稳定的问题
922浏览 1评论
1042浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-3-29 13:51 , Processed in 0.588643 second(s), Total 76, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 深圳华秋电子有限公司
电子发烧友 (电路图) 粤公网安备 44030402000349 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号