金属探测器
扫描二维码
随时随地手机看文章
硬件设计
(末尾附文件)
本文设计的金属探测是根据电磁感应原理制成的,将一金属置于变化的磁场当中时,根据电磁感应原理就会在金属内部产生涡流,涡流产生的磁场反过来又影响原磁场,这种变化可以转换为频率和幅值的变化,供相关电路进行检测。
由电容三点式振荡电路产生正弦波,对其放大和整形后,送入单片机,由单片机探测它频率的变化。当遇见金属时由于电磁感应原理原先建立起来的振荡将受到影响,频率将发生变化,单片机探测到这种变化后进行报警。
本文的金属探测器设计了接口,可以和外围的系统进行通讯,实现了与AT89S52管理的液晶显示及键盘组成的外围数据处理与显示模块的通信。对前端探测到的数据进行再处理和分析,并将结果显示在液晶屏幕上,并可以通过键盘对前端的探测精度进行设置。
方案:
原理图:
程序设计
#include
#include"eeprom52.h"
#define uchar unsigned char //宏定义
#define uint unsigned int // 6T 工作模式
#define LCD1602_dat P0 //9V供电
sbit LCD1602_rs=P2^5; //I/O 定义
sbit LCD1602_rw=P2^6; //I/O 定义
sbit LCD1602_e=P2^7;
sbit key_1=P1^3; //按键定义
sbit key_2=P1^4;
sbit beep=P1^5; //蜂鸣器及led定义
sbit led=P1^0;
unsigned long shu1,shu=1500; //设置值和采集置定义
uchar ms,sec; //时间中间值
uint cs;
bit OK,beep1; //变量
void delay(uint T) //延时程序
{
while(T--);
}
void LCD1602_write(uchar order,dat) //1602 一个字节 处理
{
LCD1602_e=0;
LCD1602_rs=order;
LCD1602_dat=dat;
LCD1602_rw=0;
LCD1602_e=1;
delay(10);
LCD1602_e=0;
}
void LCD1602_writebyte(uchar *prointer) //1602 字符串 处理
{
while(*prointer!='\0')
{
LCD1602_write(1,*prointer);
prointer++;
}
}
void LCD1602_cls() //1602 初始化
{
LCD1602_write(0,0x01); //1602 清屏 指令
delay(1500);
LCD1602_write(0,0x38); // 功能设置 8位、5*7点阵
delay(1500);
LCD1602_write(0,0x0c); //设置 光标 不显示开关、不显示光标、字符不闪烁
LCD1602_write(0,0x06);
LCD1602_write(0,0xd0);
delay(1500);
}
void show()
{
LCD1602_write(0,0x80); //第一行显示内容
LCD1602_writebyte("Now:");
LCD1602_write(1,0x30+shu1/100000%10);
LCD1602_write(1,0x30+shu1/10000%10);
LCD1602_write(1,0x30+shu1/1000%10);
LCD1602_writebyte(".");
LCD1602_write(1,0x30+shu1/100%10);
// LCD1602_write(1,0x30+shu1/10%10);
// LCD1602_write(1,0x30+shu1%10);
LCD1602_writebyte("KHz");
LCD1602_write(0,0xc0); //第二行显示内容
LCD1602_writebyte("S:");
LCD1602_write(1,0x30+shu/1000%10);
LCD1602_write(1,0x30+shu/100%10);
LCD1602_write(1,0x30+shu/10%10);
LCD1602_writebyte(".");
LCD1602_write(1,0x30+shu%10);
LCD1602_writebyte("KHz");
if(beep1 == 1)
{LCD1602_writebyte(" OKJS");} //检测到金属
else
{LCD1602_writebyte(" ERJS");} //检测到金属
}
void key()
{
if(OK==1) //按键检测
{
if(!key_1)
{
OK=0;
if(sec==3)
{
if(shu<3000) shu+=10; //设置值 ++
}
SectorErase(0x2000); //保存上限值
byte_write(0x2000,shu/256);
byte_write(0x2001,shu%256);
}
if(!key_2)
{
OK=0;
if(sec==3)
{
if(shu>200) shu-=10; //设置值 --
}else
{
if(shu>200) shu-=1;
}
SectorErase(0x2000); //保存上限值
byte_write(0x2000,shu/256);
byte_write(0x2001,shu%256);
}
}
if(key_1==1&&key_2==1)
{
sec=0;
}
}
void proc()
{
if(shu1>=(shu*100)|shu1==0) //对比采集与设置
{
led=0; //对比采集与设置
beep1=1;
}else
{
led=1;
beep1=0; //对比采集与设置
}
}
void main()
{
uchar H,L;
TMOD=0x51;
TH1=0;
TL1=0;
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
TR0=1; //定时器
TR1=1;
EA=1;
ET0=1; //定时器终端
ET1=1;
H=byte_read(0x2000); //福初始值
L=byte_read(0x2001);
shu=H*256+L;
if(shu>3000) shu=1500;
LCD1602_cls();
while(1)
{
key(); //按键处理
show();