arduino制作示波器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Arduino uno r3制作示波器
南京大学kinglookfor Arduino编程语言通俗易懂,功能全面,非常适合初学者。

网上也
有不少关于Arduino制作示波器的资料,我觉得已经比较全面了。

下面我来介绍一下使用Arduino制作示波器的流程,以及遇到的问题,希望可以对网上现有资料做一些有益处的补充。

一、关于显示屏
一般我们都使用带字库的12864,即ST7920。

这种显示屏淘宝上很多人卖,也就二十多块大洋。

然而还有另一种流传的比较广的12864显示屏,是不带字库的,型号是KS0107或者KS0108。

那么这两种显示屏最主要的不同之处在于哪里呢?我们先来看一下他们的管脚:
看到这里有的人可能会疑惑,为什么16引脚会是空脚?
那么我们再来看几种不带字库的12864显示屏的引脚分布:
对比之后我们可以发现,他们的区别只是在于:
带字库版本的第15、16引脚是PSB和NC,而不带字库版本的第一种,其第15、16引脚是CS1和CS2。

参考德飞莱公司的说明书,如下:
其实本质上就是不带字库版本的屏幕是分为左右两半显示的,因此需要分别选中CS1或CS2。

但是带字库版本的屏幕,其实是分为上下两半显示的,并且不需要片选,因此就多出来了一个空脚。

然而不幸的是,无论在Protues仿真软件,还是在arduino的绘图编程软件fritzing中,12864都是不带字库的版本,即需要片选CS1和CS2的。

不过我们在制作示波器的时候,选择的是带字库的版本,因此为了避免混淆,我们还是采用传统的直接写代码的方式来编程。

二、线路连接
那么arduino与12864显示屏之间是怎样连接的呢?先列出如下:
Arduino引脚12864引脚
13 E
12 R/W
11 RS
然后将Arduino的5V引脚和GND引脚分别接5V电源和接地,同时A0引脚接到信号源就可以了。

另外12864的PSB引脚必须要接地,因为我们这里采用的是串行传送数据。

至于它的供电部分,可以参考下图:
其中1、2、3(即V0引脚,接可调点位器是用来调节显示对比度)、19、20按照图中连线即可。

三、程序以及解析
/*
arduino简易示波器
作者:kinglookfor修改后的
*/
#include <U8glib.h> //声明库
U8GLIB_ST7920_128X64_4X u8g(13, 12, 11); // 声明液晶屏引脚连接
int Input = A0; //声明输入引脚
int Key_add = 8; //声明按钮引脚
int Key_sub = 9;
int Key_hold = 10;
int x,y; //声明坐标
int i,i1,i2,V_min,V_max,V_mid,t,t0,t1,sta,Key=1,hold=0;
long Freq;
float Vpp;
int Y[96]; //声明信号值储存数组
int Buffer[192];
//开机画面
const uint8_t L[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x06,0x10,0x04,0x18,0x00,0x00,0x81,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x06,0x51,0x07,0xF8,0x3F,0xF8,0x61,0x80,0xF7,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x07,0xFF,0x04,0x18,0x3F,0xE8,0x61,0x80,0x96,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x09,0x6C,0x07,0xF8,0x00,0x00,0x3F,0xF0,0x96,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x1B,0xFF,0x04,0x18,0x00,0x01,0x99,0xB0,0xF7,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0F,0x7F,0x07,0xF8,0xFF,0xFC,0xF9,0xA0,0x99,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0D,0x92,0x07,0x18,0x7F,0x7C,0xE9,0xA3,0xFF,0xE0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0xFA,0x07,0xFE,0x09,0x40,0x2F,0xF0,0x36,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0x92,0x0D,0xB4,0x1D,0x60,0x6A,0x60,0x63,0x80,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0xF2,0x19,0x2C,0x19,0x30,0x4B,0x41,0xF7,0xF0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0x92,0x33,0x6C,0x31,0x19,0xD9,0xC3,0xF7,0xE0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0xF2,0x0E,0xCC,0x61,0x0C,0xD9,0x80,0x94,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0D,0x92,0x19,0x8C,0xCD,0x0C,0xD3,0x60,0xF7,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0x0E,0x07,0x38,0x8F,0x00,0xEE,0x78,0xF7,0xC0,0x00,0x00,0x00,0x00,0x 00,0x00,
0x0C,0x06,0x0C,0x10,0x02,0x00,0x78,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x01,0xF8,0x00,0x70,0xC0,0x00,0x18,0x00,0x18,0x03,0x80,0x00,0x00,0x 00,0x00,
0x00,0x00,0xFC,0x00,0x30,0x80,0x00,0x18,0x00,0x18,0x06,0xC0,0x00,0x00,0x 00,0x00,
0x00,0x00,0xC6,0x00,0x30,0x00,0x00,0x18,0x00,0x18,0x06,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0xC7,0xDC,0x3E,0xDE,0x38,0x19,0xC3,0x9B,0x8F,0x71,0xE0,0x00,0x 00,0x00,
0x00,0x00,0xFD,0xC8,0x35,0xDF,0x6E,0x1B,0x66,0xDB,0x0F,0xDB,0xE0,0x00,0x 00,0x00,
0x00,0x00,0xDE,0xD8,0x38,0xDB,0x64,0x1B,0x3C,0xDE,0x06,0xCD,0x80,0x00,0x 00,0x00,
0x00,0x00,0xC6,0x50,0x38,0xDB,0x64,0x1B,0x3C,0xDC,0x06,0xCD,0x80,0x00,0x 00,0x00,
0x00,0x00,0xC6,0x70,0x3C,0xDB,0x38,0x1B,0x3C,0xDE,0x06,0xCD,0x80,0x00,0x 00,0x00,
0x00,0x00,0xCE,0x70,0x3C,0xDB,0x7C,0x1B,0x36,0xDB,0x06,0xCD,0x80,0x00,0x 00,0x00,
0x00,0x01,0xFC,0x20,0x77,0xFB,0xBE,0x3D,0xE7,0xBF,0x8F,0x7B,0x80,0x00,0x 00,0x00,
0x00,0x00,0x00,0x20,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x01,0xC0,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x01,0xC0,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x C0,0x00,
0x00,0x00,0x00,0x1E,0x78,0x00,0x64,0x00,0x01,0xF7,0x81,0x80,0x00,0x00,0x C0,0x00,
0x00,0x00,0x00,0x06,0x10,0x00,0x00,0x00,0x00,0xC3,0x00,0x00,0x00,0x00,0x 08,0x00,
0x00,0x00,0x00,0x07,0x10,0x00,0x00,0x00,0x00,0xC3,0x00,0x00,0x00,0x00,0x 08,0x00,
0x00,0x00,0x00,0x05,0x93,0xFF,0x6D,0xF9,0xF0,0xC3,0xFD,0xBB,0xFB,0xDF,0x FF,0xB0,
0x00,0x00,0x00,0x05,0xD6,0xDB,0x64,0xDB,0x70,0xC3,0x6D,0x93,0x4D,0xB6,0x DB,0x20,
0x00,0x00,0x00,0x04,0xD1,0xDB,0x64,0xDB,0x60,0xC3,0x6D,0x9A,0xFD,0x98,0x D9,0xA0,
0x00,0x00,0x00,0x04,0x73,0xDB,0x64,0xDB,0x60,0xC3,0x6D,0x9A,0xC1,0x9E,0x D9,0xE0,
0x00,0x00,0x00,0x04,0x36,0xDB,0x64,0xDB,0x80,0xC2,0x6D,0x8E,0x45,0xA6,0x D8,0xC0,
0x00,0x00,0x00,0x06,0x37,0xFB,0x6E,0xDB,0xF0,0x66,0x6D,0x8C,0x79,0xB6,0x DC,0xC0,
0x00,0x00,0x00,0x0F,0x13,0x7F,0xEF,0xFF,0xF0,0x3C,0xFF,0xC4,0x3B,0xBD,0x EC,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x 00,0x80,
0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x 03,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,
};
void setup( )
{
pinMode(Key_add,INPUT);
digitalWrite(Key_add,HIGH);
pinMode(Key_sub,INPUT);
digitalWrite(Key_sub,HIGH);
pinMode(Key_hold,INPUT);
digitalWrite(Key_hold,HIGH);
ADMUX=0x60;
ADCSRA=0xe2;
u8g.setFont(u8g_font_5x7);
u8g.firstPage();
do {
u8g.drawBitmapP( 0, 0, 16, 64, L); } while( u8g.nextPage() );
delay(5000); //这里是开机画面停留的时间 }
void loop( )
{
sample( );
Measure( );
Transform( );
Key_scan( );
if(hold==0)
{
u8g.firstPage( );
do
{
draw( );
}
while( u8g.nextPage( ));
}
}
void sample( )
{ for(i = 0;i < 192;i++)
{
Buffer[i] = ADCH;
switch(Key)
{
case 1:
break;
case 2:
delayMicroseconds(4);
break;
case 3:
delayMicroseconds(10);
break;
case 4:
delayMicroseconds(23);
break;
case 5:
delayMicroseconds(60);
break;
case 6:
delayMicroseconds(123);
break;
case 7:
delayMicroseconds(248);
break;
case 8:
delayMicroseconds(623);
break;
case 9:
delayMicroseconds(1247);
break;
default:break;
}
}
}
void Measure()
{
V_max=Buffer[0];//这里是通过比较,来找到最大电压和最小电压 V_min=Buffer[0];
for(i=0;i<192;i++)
{
if(Buffer[i]>V_max)
V_max=Buffer[i];
if(Buffer[i]<V_min)
V_min=Buffer[i];
}
V_mid=(V_max+V_min)/2;
Vpp=(V_max-V_min)*5.0/255;
for(i=0;i<97;i++)
{
if(Buffer[i]<V_mid&&Buffer[i+1]>=V_mid)
{
i1=i;
break;
}
}
for(i=i1+1;i<98+i1;i++)
{
if(Buffer[i]<V_mid&&Buffer[i+1]>=V_mid) {
i2=i;
break;
}
}
t=i2-i1;
if(t>0)
Freq=8000/t;
else
Freq=0;
}
void Transform( )
{
for(sta=0;sta<96;sta++)
{
if(Buffer[sta]<128&&Buffer[sta+2]>128) break;
}
for(i = 0;i < 96;i++)
Y[i] = 63-(Buffer[i+sta]>>2);
}
void draw( )
{
for(x = 0;x < 95;x++)
u8g.drawLine(x,Y[x],x,Y[x+1]); //画线
//画边框
u8g.drawFrame(0,0,97,64);
// 画坐标轴
u8g.drawLine(48,0,48,63);
u8g.drawLine(0,32,96,32);
for(x=0;x<96;x+=8)
u8g.drawLine(x,31,x,33);
for(y=0;y<64;y+=8)
u8g.drawLine(47,y,49,y);
//画网格
for(x=8;x<96;x+=8)
{
for(y=8;y<64;y+=8)
u8g.drawPixel(x,y);
}
//显示参数
u8g.drawStr(98,7,"MS/div");
u8g.drawStr(98,23,"V/div");
u8g.drawStr(98,30,"0.324");
u8g.drawStr(98,40,"Vpp");
u8g.setPrintPos( 98, 47);
u8g.print(Vpp);
u8g.drawStr(118,47,"V");
u8g.drawStr(98,55,"F(HZ)");
switch(Key)
{
case 1:
u8g.drawStr(98,14,"0.02"); u8g.setPrintPos( 98, 62); u8g.print(Freq*50);
break;
case 2:
u8g.drawStr(98,14,"0.05"); u8g.setPrintPos( 98, 62); u8g.print(Freq*20);
break;
case 3:
u8g.drawStr(98,14," 0.1"); u8g.setPrintPos( 98, 62); u8g.print(Freq*10);
break;
case 4:
u8g.drawStr(98,14," 0.2"); u8g.setPrintPos( 98, 62); u8g.print(Freq*5);
break;
case 5:
u8g.drawStr(98,14," 0.5"); u8g.setPrintPos( 98, 62); u8g.print(Freq*2);
break;
case 6:
u8g.drawStr(98,14," 1");
u8g.setPrintPos( 98, 62);
u8g.print(Freq);
break;
case 7:
u8g.drawStr(98,14," 2");
u8g.setPrintPos( 98, 62);
u8g.print(Freq/2);
break;
case 8:
u8g.drawStr(98,14," 5");
u8g.setPrintPos( 98, 62);
u8g.print(Freq/5);
break;
case 9:
u8g.drawStr(98,14," 10");
u8g.setPrintPos( 98, 62);
u8g.print(Freq/10);
break;
default:break;
}
}
//键盘扫描
void Key_scan()
{
if(digitalRead(Key_add)==LOW)
{
while(digitalRead(Key_add)==LOW);
Key++;
if(Key==10)
Key=9;
delay(10);
}
if(digitalRead(Key_sub)==LOW)
{
while(digitalRead(Key_sub)==LOW);
Key--;
if(Key==0)
Key=1;
delay(10);
}
if(digitalRead(Key_hold)==LOW)
{
while(digitalRead(Key_hold)==LOW);
hold=~hold;
delay(10);
}
}
四、注意的问题
(1)由于arduino自带的模数转换,只能转换正电压,因此这个示波器其实只能测量正电压的波形。

那么我们在用信号发生器给我们刚刚制作好的示波器输入信号的时候,必须要先调电压偏置,将输出波形全部置于正电压部分,这样才能被准确的测量。

(2)必须要先下载u8glib_arduino_v1.15这一个库,并且将它解压后放在arduino安装目录下的libraries文件下,然后在Arduino编程软件中选择Sketch→导入库→添加库,然后选中u8glib_arduino_v1.15这个库并将其导入。

如此之后,程序在编译时才可以找到这个函数库。

五、显示的画面
开机画面如下:(大家可以自己定义)
显示的正弦波如下:
这个示波器最原始的界面就是这样的,因为模数转换以后,显示的数字必然是从0开始,因此这时显示的波形并不是以中线为对称,而是挨着底部的。

其实你可以通过按钮将其上移,然而这并没有什么意义,测量范围始终只能是0-5V的电压。

不过显示的电压值还是比较准的,上图显示的Vpp是3.51V,我用虚拟示波器测量出来的电压是3.506V,如下图:
还有很多其他可以设置的,通过arduino的8、9、10引脚连接的按键。

这些设置网上有人说过,我在此就不详述了。

同学们可以自己去慢慢研究哈哈。

其实这种东西,大家也不要太当真,真正做实验有谁会拿这个去测量呢。

就是玩玩而已吧。

相关文档
最新文档