硬件設(shè)計
(末尾附文件)
本文設(shè)計的金屬探測是根據(jù)電磁感應(yīng)原理制成的,將一金屬置于變化的磁場當(dāng)中時,根據(jù)電磁感應(yīng)原理就會在金屬內(nèi)部產(chǎn)生渦流,渦流產(chǎn)生的磁場反過來又影響原磁場,這種變化可以轉(zhuǎn)換為頻率和幅值的變化,供相關(guān)電路進行檢測。
由電容三點式振蕩電路產(chǎn)生正弦波,對其放大和整形后,送入單片機,由單片機探測它頻率的變化。當(dāng)遇見金屬時由于電磁感應(yīng)原理原先建立起來的振蕩將受到影響,頻率將發(fā)生變化,單片機探測到這種變化后進行報警。
本文的金屬探測器設(shè)計了接口,可以和外圍的系統(tǒng)進行通訊,實現(xiàn)了與AT89S52管理的液晶顯示及鍵盤組成的外圍數(shù)據(jù)處理與顯示模塊的通信。對前端探測到的數(shù)據(jù)進行再處理和分析,并將結(jié)果顯示在液晶屏幕上,并可以通過鍵盤對前端的探測精度進行設(shè)置。
方案:

原理圖:

程序設(shè)計

#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; //蜂鳴器及l(fā)ed定義
sbit led=P1^0;
unsigned long shu1,shu=1500; //設(shè)置值和采集置定義
uchar ms,sec; //時間中間值
uint cs;
bit OK,beep1; //變量
void delay(uint T) //延時程序
{
while(T--);
}
void LCD1602_write(uchar order,dat) //1602 一個字節(jié) 處理
{
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); // 功能設(shè)置 8位、5*7點陣
delay(1500);
LCD1602_write(0,0x0c); //設(shè)置 光標(biāo) 不顯示開關(guān)、不顯示光標(biāo)、字符不閃爍
LCD1602_write(0,0x06);
LCD1602_write(0,0xd0);
delay(1500);
}
void show()
{
LCD1602_write(0,0x80); //第一行顯示內(nèi)容
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); //第二行顯示內(nèi)容
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; //設(shè)置值 ++
}
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; //設(shè)置值 --
}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) //對比采集與設(shè)置
{
led=0; //對比采集與設(shè)置
beep1=1;
}else
{
led=1;
beep1=0; //對比采集與設(shè)置
}
}
void main()
{
uchar H,L;
TMOD=0x51;
TH1=0;
TL1=0;
TL0 = 0xB0; //設(shè)置定時初值
TH0 = 0x3C; //設(shè)置定時初值
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();