admin 管理员组文章数量: 1087139
2024年4月27日发(作者:简述mvc模式的具体组成部分)
Arduino uno r3制作示波器
南京大学 kinglookfor
Arduino编程语言通俗易懂,功能全面,非常适合初学者。网上也
有不少关于Arduino制作示波器的资料,我觉得已经比较全面了。下面
我来介绍一下使用Arduino制作示波器的流程,以及遇到的问题,希望
可以对网上现有资料做一些有益处的补充。
一、关于显示屏
一般我们都使用带字库的12864,即ST7920。这种显示屏淘宝上
很多人卖,也就二十多块大洋。然而还有另一种流传的比较广的12864
显示屏,是不带字库的,型号是KS0107或者KS0108。那么这两种显
示屏最主要的不同之处在于哪里呢?我们先来看一下他们的管脚:
引脚 符号 功能说明
1 VSS
一般接地
2 VDD
接电源(+5V)
3 V0
液晶显示器对比度调整端
4 RS(CS)
RS为寄存器选择,高电平1时选择数据寄存器,
低电平0时选择指令寄存器;串行片选信号。
5 R/W(SID)
R/W为读写信号线,高电平(1)时进行读操作,
低电平(0)时进行写操作。串行数据口。
6 E(CLK)
E(或EN)端为使能端,下降沿使能;串行同步时
钟。
7 DB0
高4位三态、双向数据总线0位
8 DB1
高4位三态、双向数据总线1位
9 DB2
高4位三态、双向数据总线2位
10 DB3
高4位三态、双向数据总线3位
11 DB4
高4位三态、双向数据总线4位
12 DB5
高4位三态、双向数据总线5位
13 DB6
高4位三态、双向数据总线6位
14 DB7
高4位三态、双向数据总线7位(最高位)
15 PSB
ST7920中串并口模式选择。H-并行,L-串行
16 NC
空脚
1
17
18
19
20
RESET
VEE
BLA
BLK
复位
负压输出端(用于调节对比度)
背光电源正极
背光电源负极
看到这里有的人可能会疑惑,为什么16引脚会是空脚?
那么我们再来看几种不带字库的12864显示屏的引脚分布:
12864-1 12864-3 12864-7 12864-16
引脚
1 GND /CS1 VCC GND
2 VCC /CS2 GND VCC
3 V0 GND V0 V0
4 RS VCC RS RS
5 R/W V0 R/W R/W
6 E RS E E
7 DB0 R/W DB0 DB0
8 DB1 E DB1 DB1
9 DB2 DB0 DB2 DB2
10 DB3 DB1 DB3 DB3
11 DB4 DB2 DB4 DB4
12 DB5 DB3 DB5 DB5
13 DB6 DB4 DB6 DB6
14 DB7 DB5 DB7 DB7
15 CS1 DB6 /CS1 CS1
16 CS2 DB7 /CS2 CS2
17 /RST /RST /RST /RST
18 VOUT VOUT VOUT VOUT
19 LEDA LEDA LEDA EL/BLA
20 LEDK LEDK LEDK NC/BLK
对比之后我们可以发现,他们的区别只是在于:
带字库版本的第15、16引脚是PSB和NC,而不带字库版本的第
一种,其第15、16引脚是CS1和CS2。参考德飞莱公司的说明书,如
下:
2
其实本质上就是不带字库版本的屏幕是分为左右两半显示的,因此需要分别选
中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
按照图中连线即可。
三、程序以及解析
3
/*
arduino简易示波器
作者:kinglookfor修改后的
*/
#include
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,
4
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,
5
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,
6
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;
t(u8g_font_5x7);
age();
do {
7
tmapP( 0, 0, 16, 64, L);
} while( ge() );
delay(5000); //这里是开机画面停留的时间
}
void loop( )
{
sample( );
Measure( );
Transform( );
Key_scan( );
if(hold==0)
{
age( );
do
{
draw( );
}
while( ge( ));
}
}
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);
8
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=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] { i1=i; break; } } for(i=i1+1;i<98+i1;i++) { 9 if(Buffer[i] { 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++) ne(x,Y[x],x,Y[x+1]); //画线 //画边框 ame(0,0,97,64); // 画坐标轴 ne(48,0,48,63); ne(0,32,96,32); for(x=0;x<96;x+=8) ne(x,31,x,33); for(y=0;y<64;y+=8) ne(47,y,49,y); //画网格 for(x=8;x<96;x+=8) { 0 1 for(y=8;y<64;y+=8) xel(x,y); } //显示参数 r(98,7,"MS/div"); r(98,23,"V/div"); r(98,30,"0.324"); r(98,40,"Vpp"); ntPos( 98, 47); (Vpp); r(118,47,"V"); r(98,55,"F(HZ)"); switch(Key) { case 1: r(98,14,"0.02"); ntPos( 98, 62); (Freq*50); break; case 2: r(98,14,"0.05"); ntPos( 98, 62); (Freq*20); break; case 3: r(98,14," 0.1"); ntPos( 98, 62); (Freq*10); break; case 4: r(98,14," 0.2"); ntPos( 98, 62); (Freq*5); break; case 5: r(98,14," 0.5"); ntPos( 98, 62); (Freq*2); break; case 6: r(98,14," 1"); 1 1 ntPos( 98, 62); (Freq); break; case 7: r(98,14," 2"); ntPos( 98, 62); (Freq/2); break; case 8: r(98,14," 5"); ntPos( 98, 62); (Freq/5); break; case 9: r(98,14," 10"); ntPos( 98, 62); (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); } 2 1 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这个库并将其导入。如此之后,程 序在编译时才可以找到这个函数库。 五、显示的画面 开机画面如下:(大家可以自己定义) 显示的正弦波如下: 13 这个示波器最原始的界面就是这样的,因为模数转换以后,显示的数字必然是 从0开始,因此这时显示的波形并不是以中线为对称,而是挨着底部的。其实你可 以通过按钮将其上移,然而这并没有什么意义,测量范围始终只能是0-5V的电 压。不过显示的电压值还是比较准的,上图显示的Vpp是3.51V,我用虚拟示波器 测量出来的电压是3.506V,如下图: 14 还有很多其他可以设置的,通过arduino的8、9、10引脚连接的按键。这些 设置网上有人说过,我在此就不详述了。同学们可以自己去慢慢研究哈哈。 其实这种东西,大家也不要太当真,真正做实验有谁会拿这个去测量呢。就是 玩玩而已吧。 15
版权声明:本文标题:arduino制作示波器 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/b/1714207242a669811.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论