?? chaosheng.c
字號(hào):
#include"reg51.h"
#include"intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit DS=P1^4;
sbit START=P1^5;
sbit SCK=P1^0;
sbit SI=P1^1;
sbit SO=P1^2;
sbit cs_feed=P1^3;//喂狗信號(hào)
uchar code *init="超聲波液位儀";
uchar code *work_temp="工作溫度 ℃";
uchar code *test= "測(cè)量距離 mm";
uchar code *fail=": 失敗mm";
uchar code *num_data="0123456789";
uchar code *chao_v="超聲波速 m/s";
uchar data temp_data[2];//={0x00,0x00}; //讀出溫度暫存單元 {0x91,0x01} 25度; 高位存高位 低位存低位
uint data plus_data;//存放中斷時(shí)的計(jì)數(shù)
uint data average=0;
//RT12864寫(xiě)指令
void cmd (uchar intr)
{
P2=0x04;
P0=intr;
P2=0x00;
P2=0x03;// 寫(xiě)指令周期結(jié)束
}
//RT12864寫(xiě)數(shù)據(jù)
void dat (uchar *p,uchar data j)
{
uchar data i,k;
for(i=0;i<j;i++)
{
for(k=0;k<10;k++); //延時(shí)大約100us
P2=0x05;
P0=*(p+i);
P2=0x01;
P2=0x02;// 寫(xiě)數(shù)據(jù)周期結(jié)束
}
}
//
void delay(uint t)
{
for(;t>0;t--);//循環(huán)一次延時(shí)11us
}
//18b20復(fù)位程序
void reset()
{
bit bdata flag=1;
while(flag)
{
while(flag)
{
DS=1;
_nop_(); _nop_(); _nop_();
DS=0;//以上程序段制造一個(gè)下降延
delay(50);//延時(shí)550us 最短延時(shí)480us
DS=1;//18b20在上升延后等待15~60us發(fā)出存在脈沖,低電平持續(xù)60~240us 復(fù)位成功
delay(3);
flag=DS;
}
delay(50);//延時(shí)550us 看電平能不能升高 如果能升高證明是 低電平脈沖
DS=1;
flag=~DS;
}
}
//18b20寫(xiě)命令函數(shù)
void write(uchar rule)
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=rule&0x01;
DS=1;
_nop_(); _nop_(); _nop_();
DS=0;//以上程序段制造一個(gè)下降延
_nop_(); _nop_(); _nop_();
DS=temp;//從低位起 按位取出 送給18B20
rule=rule>>1;
delay(6);//延時(shí)66us
}
DS=1;
delay(1);
}
//讀一溫度字節(jié)
uchar read()
{
uchar data i;
uchar data temp=0x00;
uchar data value=0;
for(i=0;i<8;i++)
{
DS=1;
_nop_(); _nop_(); _nop_();
DS=0;//以上程序段制造一個(gè)下降延
_nop_(); _nop_(); _nop_();
DS=1;
_nop_(); _nop_(); _nop_();
value>>=1;
DS=0;
_nop_(); _nop_(); _nop_(); _nop_();
DS=1;
_nop_(); _nop_(); _nop_(); _nop_();
if(DS) value|=0x80;
delay(6);
}
DS=1;
return(value);
}
//讀出溫度函數(shù)
void read_temp()
{
reset();
write(0xcc);//發(fā)skiprom命令
write(0x44);//發(fā)送轉(zhuǎn)換命令
reset();
write(0xcc);//發(fā)skiprom命令
write(0xbe); //讀命令
temp_data[0]=read();
temp_data[1]=read();
reset();
}
//數(shù)據(jù)處理顯示函數(shù)
uchar deal_dis()
{
uchar data k;
uchar data tmp[2];
uchar data dis_data[6];
dis_data[0]=':';
if(temp_data[1]>127) //判斷小于零
{
temp_data[1]=~temp_data[1]+1;
temp_data[0]=~temp_data[0]+1;
dis_data[1]='-';
}
else
dis_data[1]=0x20; //清空單元
tmp[0]=temp_data[1]<<4;
tmp[1]=temp_data[0]>>4;
tmp[1]=tmp[1]&0x0f;
tmp[0]=tmp[0]|tmp[1];//整數(shù)部分
tmp[1]=temp_data[0]&0x0f; //小數(shù)部分
dis_data[2]=*(num_data+tmp[0]%100/10);
dis_data[3]=*(num_data+tmp[0]%10); //dis_data[0--3]內(nèi)容是"-" 高位到低位
dis_data[4]='.';
if(tmp[1]==0x00)
dis_data[5]='0';
else if(tmp[1]==0x0f)
dis_data[5]='9';
else
dis_data[5]= *(num_data+tmp[1]/2+1);
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x94); //位置 //
for(k=0;k<10;k++); //延時(shí)大約100us
dat(dis_data ,6); // 溫度
return(tmp[0]); //返回溫度整數(shù)部分用來(lái)超聲波計(jì)算超聲波速度
}
//開(kāi)始發(fā)送超聲波
void send_wave()
{
uchar w;
START=0;//開(kāi)始發(fā)送超聲波
TR0=1;
for(w=0;w<15;w++);//延時(shí)大約100us
START=1; //停止發(fā)送
for(w=0;w<5;w++);//延時(shí)等待超聲波換能器余震 過(guò)去
EX0=1;//外部中斷0允許
}
// 測(cè)試失敗
void failed()
{
uchar k;
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x9c); //位置
for(k=0;k<10;k++); //延時(shí)大約100us
dat(fail,8); //距離
}
//計(jì)算速度和距離并顯示
void math(uchar t)
{
uint data s;
float v;
uchar data i;
float data temp1,temp2;
uchar data distan_data[6];
uint data div;//記錄有多少個(gè)100個(gè)脈沖 用來(lái)解決直接計(jì)算的越界問(wèn)題
v=331.5+0.6*t;
s=v; //s是整形量 用來(lái)存儲(chǔ)v的整數(shù)部分
distan_data[0]=':';
distan_data[1]=' ';
distan_data[2]=*(num_data+s/100);
distan_data[3]=*(num_data+s%100/10);
distan_data[4]=*(num_data+s%10);
for(i=0;i<10;i++); //延時(shí)大約100us
cmd(0x8c); //位置
for(i=0;i<10;i++); //延時(shí)大約100us
dat(distan_data,5); //距離
// plus_data=50001 ;
if(plus_data>50000||TF0==1)
{
failed();
for(i=0;i<100;i++); //延時(shí)大約100us
return ;
}
plus_data/=2;
div=plus_data/100;
plus_data=plus_data%100;
temp1=100*v/1000;
temp1=div*temp1;
temp2=plus_data*v/1000;
s=temp1+temp2;
if(average==0)
average=s; //第一次測(cè)量的是第一次值二倍的平均值
average=(average+s)>>1;//每次測(cè)量的值都和上一次的平均值取平均 逐次逼近可以加快計(jì)算速度
distan_data[0]=':';
distan_data[1]=' ';
distan_data[2]=*(num_data+average/1000);
distan_data[3]=*(num_data+average%1000/100);
distan_data[4]=*(num_data+average%100/10);
distan_data[5]=*(num_data+average%10);
for(i=0;i<10;i++); //延時(shí)大約100us
cmd(0x9c); //位置
for(i=0;i<10;i++); //延時(shí)大約100us
dat(distan_data,6); //距離
}
/*
sbit SCK=P1^0;
sbit SI=P1^1;
sbit SO=P1^2;
sbit cs_feed=P1^3;//喂狗信號(hào)
*/
//看門(mén)狗初始化
void WTD_init()
{
uchar i;
uchar instr;
cs_feed=0; // 用來(lái)寫(xiě) WREN 寫(xiě) 使能
instr=0x06;
for(i=0;i<8;i++)
{
SCK=0;
SI=instr&0x80;;
SCK=1;
instr<<=1;
}
cs_feed=1;
_nop_();
cs_feed=0; //用來(lái)寫(xiě)狀態(tài)寄存器指令
instr=0x01;
for(i=0;i<8;i++)
{
SCK=0;
SI=instr&0x80;;
SCK=1;
instr<<=1;
}
instr=0x10; //寫(xiě)狀態(tài)寄存器
for(i=0;i<8;i++)
{
SCK=0;
SI=instr&0x80;;
SCK=1;
instr<<=1;
}
}
//喂狗
void feed_WTD()
{
cs_feed=1;
_nop_(); _nop_();
cs_feed=0;
_nop_(); _nop_();
}
// 超聲波返回中斷 讀取計(jì)數(shù)器中的值
void plus_count (void ) interrupt 0 using 0
{
TR0=0;
plus_data=TH0;
plus_data<<=8;
plus_data|=TL0;
}
//
void init_RT()
{
uchar data k,w;
cmd(0x30);//使用基本指令集
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x0c); //顯示狀態(tài)開(kāi)關(guān) 整體,游標(biāo),游標(biāo)位置
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x01); //清除顯示,地址計(jì)數(shù)器AC到零
for(k=0;k<250;k++)
for(w=0;w<200;w++);//延時(shí)大約500ms
cmd(0x81); //位置
for(k=0;k<10;k++); //延時(shí)大約100us
dat(init,12); //超聲波液位儀
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x90); //位置
for(k=0;k<10;k++); //延時(shí)大約100us
dat(work_temp,16); //溫度
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x88); //位置
for(k=0;k<10;k++); //延時(shí)大約100us
dat(chao_v,16); //超聲波速度
for(k=0;k<10;k++); //延時(shí)大約100us
cmd(0x98); //位置
for(k=0;k<10;k++); //延時(shí)大約100us
dat(test,16); //距離
}
//主函數(shù)
void main()
{
uchar data tempt;//當(dāng)前溫度
unsigned int i;
unsigned int j;
TMOD=0x01; //計(jì)數(shù)器0工作在16位定時(shí)器狀態(tài)
EA=1;
PX0=1; //外部中斷0優(yōu)先級(jí)高
IT0=1; //邊沿觸發(fā) 自動(dòng)清零
// WTD_init(); //看門(mén)狗初始化
//init_RT();
START=0;//開(kāi)始發(fā)送超聲波
while(1)
{ /*
// read_temp();
//tempt=deal_dis(); //取回溫度值
send_wave();
while(TF0==0);
math(tempt);//計(jì)算距離
TF0=0;
feed_WTD(); //喂狗
*/
for(i=0;i<900;i++);
START=~START;
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -