}
/**************************************************************
//定时器1中断,用做超声波测距无回波
voidtimer1()interrupt3
{
TR1=0;
ET1=0;
EX1=0;
TH1=0;
TL1=0;
}
/***********************显示程序*********************/
voidLed(intdate)//显示函数
{inti;
table[0]=date/1000;
table[1]=date/100%10;
table[2]=date/10%10;
table[3]=date%10;
date=0;
for(i=0;i<120;i++)
P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器
P0=seg7code[table[i%4]];//取出千位数,查表,输出。
ledDelay(15);
}
}
/*******************************************************************/
//外部中断1,用做判断超声波回波电平说明测试成功
voidint1()interrupt2//外部中断1是0号
{
EX1=0;//关闭外部中断1
TR1=0;
ET1=0;
succeed_flag=1;//测试成功标志
}
**************************
超声波测路子函数***********************/
voidsound()
{ET0=1;TR0=1;〃开38K超声波输入端
while(tt!
=1);//发送几个脉冲的超声
tt=0;//清零重新计数
ET0=0;TR0=0;
tt=0;//清零重新计数
TF1=0;//计数溢出标志
TH1=0;//定时器1清零
TL1=0;//定时器1清零
ET1=1;//开定时器1
TR1=1;//启动定时器1
EX1=1;//打开外部中断1
succeed_flag=0;
while(EX1==1);//等待回波标志
if(succeed_flag==1)〃测试成功
{time=TH1*256+TL1;//回波响应时间
distance=time*1.72/100;〃换算成路程
Led(distance);〃显示测到的距离
EX1=1;//开中断1
}
if(succeed_flag==0)//测试不成功或超出时间
{
Led(3333);〃表示测不到回波
}
}
红外解码
中断0解码服务子程序
voidint0(void)interrupt0using2
{
EA=0;//?
?
?
可以这样,
跳入中断,但仍可对P3.2(INT0)进行电平变化的
读取
for(k=0;k<10;k++)
{
Delay0_9ms();
if(IRsignal==1)
{
//如果0.9ms后IRsignal=1,说明不是引导码
k=10;break;
}
elseif(k==9)
//如果持续了10X0.9ms=9ms的低电平,说明是
引导码
{
while(IRsignal==0);
Delay4_5ms();
//跳过持续4.5ms的高电平
for(i=0;i<4;i++)//分别读取4个字节
{
for(j=1;j<=8;j++)
//每个字节8个bit的判断
{
while(IRsignal==0);//等待上升沿此处用得很好:
因为0.56ms的低电平(接收时)是代码0与1的相同部分
Delay0_9ms();//从上升沿那一时刻开始延时0.9ms(因为
0.9介于0.56(=1.125-0.56)与1.69(=2.25-0.56)之间),再判断IRsignal
if(IRsignal==1)//如果IRsignal是"1",高位置"1",并向右移一
位
{
Delay1ms();//为什么要延时1ms呢?
因为要使IRsignal跳至
低电平(即0.56ms的0与1相同部分上)
CodeTemp=CodeTemp|0x80;//此处的算法很好
if(j<8)CodeTemp=CodeTemp>>1;
}
elseif(j<8)
{CodeTemp=CodeTemp>>1;}〃如果IRsignal是"0",则直接向右移一位,自动补"0"
}
IRcode[i]=CodeTemp;
CodeTemp=0;
}
for(i=0;i<4;i++)//通过串口将代码发出
{
SBUF=IRcode[i];//引导码地址码数据码数据反码while(!
TI);//等待一个字节发送完毕
TI=0;
Delay();
}
}
switch(IRcode[2])//数据位
{
case69:
m=0xfe;break;/电机上升
case70:
m=0xff;break;〃电机停止
case71:
m=0xfc;break;/电机下降
case22:
a=0;break;
case25:
key=1;break;/功能键
case12:
a=1;;break;
case24:
a=2;;break;
case94:
a=3;;break;
case8:
a=4;;break;
case28:
a=5;;break;
case90:
a=6;;break;
case66:
a=7;;break;
case82:
a=8;;break;
case74:
a=9;;break;
EA=1;//开总中断
}
初始化程序
voidinitUart(void)
{
TMOD|=0x11;//定时器T1,T0都用方式1,16位PCON|=0x80;
TH1=0;//定时器T1高位初始化
TL1=0;//定时器T1低位初始化
ET1=1;//开定时器1
TR1=1;//用时才启动//TMOD=0x01;
TH0=(65536-count)/256;//定时器T0初值TL0=(65536-count)%256;//
EA=1;//开总中断
ET0=0;//先关上38KHz,用到的时候再开
TR0=0;//先关上38KHz,用到的时候再开}
I*****************************************************************
//设置电机到达的高度
voidscankey()
{
while(IRcode[2]==25)
{Led(1111);//显示1111表示进入了功能菜单
while(IRcode[2]!
=25)
{BZ=1;//开掉蜂鸣器
h1=10*a;//设置10位
IRcode[2]=1;//进入个位标志
Led(h1);//显示设置多少十
while(IRcode[2]!
=1)
{h=h1+a;//十位加个位
Led(h);//显示设置到达的高度
key1=1;//作用用于退出死循环
if(IRcode[2]==25)//再次按功能键则完成设置
{break;}
}
}
if(key1==1)//退出死循环
{key1=0;
IRcode[2]=0;
break;
}
高度判断函数
voidhigh()
{
if(95<=distance||((h-5)<=distance&&distance<=(h+5)))//提前停电机
{
IRcode[2]=0;//清零红外接收的数据
m=0xff;//关电机
BZ=0;//开蜂鸣器
Delay();
BZ=1;//关
}
}
主程序
voidmain()
{
P2=0xFF;//数码管测试ledDelay
(1);
P2=0xff;
initUart();
IT1=1;
IT0=1;//INT0为负边沿触发,(1:
负边沿触发,0:
低电平触发)
EX0=1;//外部中断INT0开,(1:
开,0:
关)
EA=1;//开所有中断
CodeTemp=0;//初始化红外编码字节缓存变量
temp=0;
tt=0;
m=0xff;
h=1;
while
(1)
{sound();//调超声测距函数测距
SBUF=P3;//P3口信息返回
if(!
TI)
{TI=0;
}
high();//高度判断
scankey();//如果按的功能键则进入此函数
}
}
程序二:
//超声波模块程序
//超声波模块程序
//Trig=P2A0
//Echo=卩3八2
#include
#defineucharunsignedchar
#defineuintunsignedint
//
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)for(y=110;y>0;y--);
}
//
voiddelay_20us()
{
uchara;for(a=0;a<100;a++);
}
//显示数据转换程序
voiddisplay(uinttemp)
{
ucharge,shi,bai;
bai=temp/100;
shi=(temp%100)/10;
ge=temp%10;
wela=1;
P0=0xf7;
wela=0;
dula=1;
P0=table[bai];
dula=0;
delay
(1);
dula=1;
P0=0x00;//关位码
dula=0;
wela=1;
P0=0xef;
wela=0;
dula=1;
P0=table[shi];
dula=0;
delay
(1);
dula=1;
P0=0x00;//关位码
dula=0;
dula=1;
P0=table[ge];
dula=0;
wela=1;
P0=0xdf;
wela=0;
delay
(1);
dula=1;
P0=0x00;//关位码
dula=0;
}
//***************************************************************
voidmain()
{
uintdistance;
test=0;
Trig=0;//首先拉低脉冲输入引脚
EA=1;//打开总中断0
TMOD=0x10;
//定时器1,16位工作方式
while
(1)
{
EA=0;
//关总中断
Trig=1;
//超声波输入端
delay_20us();//延时20us
Trig=O;//产生一个20us的脉冲
while(Echo==0);//等待Echo回波引脚变高电平succeed_flag=0;//清测量成功标志
EA=1;
EX0=1;
//打开外部中断0
TH1=0;
//定时器1清零
TL1=0;
//定时器1清零
TF1=0;
//计数溢出标志
TR1=1;
//启动定时器1
delay(20);
//等待测量的结果
TR1=0;
//关闭定时器1
EX0=0;
//关闭外部中断0
if(succeed_flag==1)
time=timeH*256+timeL;
distance=time*0.172;//厘米display(distance);
}
if(succeed_flag==0)
{
distance=0;//没有回波则清零
test=!
test;//测试灯变化
}
}
}
//***************************************************************
//外部中断0,用做判断回波电平
voidexter()interrupt0//外部中断0是0号
{
timeH=TH1;//取出定时器的值
timeL=TL1;//取出定时器的值
succeed_flag=1;〃至成功测量的标志
EX0=0;//关闭外部中断
}
//定时器1中断,用做超声波测距计时voidtimer1()interrupt3//
{
TH1=0;
TL1=0;
}
程序三:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
unsignedinttime;
unsignedintS,s_false;
unsignedlongnum1;
bitflag;
sbitTrig=P3A6;//定义引脚
(zlu'5)Aea)ppo>
LnvedHPQ七qs揺注CXIvCXIdgpo七qsMM注LVCXIdHMJPo七qsif報令&注ovCMdus」po一七qszvcoduolp山七qs
Osno0IAea)ppo?
、
亍aoaaollha)」04
(}xoaxnhx)」04
-Axlu'5
uchara;
for(a=0;a<100;a++);
}
*/
//***************************************************************
voidwrite_com(unsignedcharcom)
{
lcdrs=0;
P0=com;
delay(5);
lcde=1;
delay(5);
lcde=0;
}
voidwrite_data(unsignedcharzifu)
lcdrs=1;
P0=zifu;
delay(5);
lcde=1;
delay(5);
lcde=0;
}
voidwrite_temp(uintt_emp)
{
ucharqian,bai,shi,ge;
qian=t_emp/1000;
bai=(t_emp%1000)/100;
shi=(t_emp%100)/10;
ge=t_emp%10;
write_com(0x80);
write_data(0x30+qian);
delay
(1);
write_data(0x30+bai);
delay
(1);
write_data(0x30+shi);
delay
(1);
write_data(0x30+ge);
delay
(1);
delay(100);
}
/********************************************************/
voidT0_time()interrupt1//T0中断用来计数器溢出,超过测距范围
{
flag=0;//中断溢出标志,失败
TH0=0;
TL0=0;
TR0=0;//关闭计数
}
/********************************************************/
voidT1_timer()interrupt3//中断
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
num1++;
if(num1==20)
{
num1=0;
led=~led;
}
voidStartModule()//启动模块
//启动一次模块
{
Trig=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Trig=0;
}
/*******************************************************
voidCount(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100;//算出来是CM
if(((S<8)||(S>=600))||flag==0)//超出测量范围显示“-”失败{
//flag=1;
s_false=1000;write_com(0x80);
write_data('e');
delay(5);
write_data('r');
delay(5);
write_data('r');
delay(5);
write_data('o');
delay(5);
write_data('r');
delay(5);
//write_temp(s_false);
}
else
{
write_temp(S);
*/
*/
voidinit()
lcde=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
lcdrw=0;
//***************************************************************voidmain()
{
//unsignedcharTempCyc;
delay(500);//启动等待,等LCM讲入工作状态
lcdrw=0;
init();//LCM初始化
delay(500);//延时片刻(可不要)while
(1)
{
TMOD=0x11;//设T0为方式1,GATE=1;
TH0=0;
TL0=0;
ET0=1;//允许T0中断
ET1=1;
TR1=1;
EA=1;//开启总中断
Trig=0;
Echo=0;
while
(1)
{
StartModule();
flag=1;
//while(!
Echo);
while((!
Echo)&&flag);
跳出等待
TR0=1;
while(Echo&&flag);
TR0=0;
Count();
delay(120);
}
}
}
程序四:
#include
//当echo为零时等待
//当echo为零时等待,中断flag
//开启计数
//当echo为1计数并等待
//关闭计数
//计算
//80MS
#include#defineucharunsignedchar
#defineuintunsignedintunsignedinttime;unsignedintS,s_false;unsignedlongnum1;
bitflag;
sbitTrig=P3A6;//定义引脚
sbitEcho=P3A7;
sbitlcdrs=P2A0;//命令数据sbitlcdrw=P2A1;//读写sbitlcde=P2A2;〃能
sbitled=P3A5;
voiddelay