最近我想利用超声波传感器做一个俯卧撑计数的装置。但是遇到了种种问题,经过长时间的调试仍未好转,诚心求大大侠解答!
项目具体描述如下:stc15单片机与两个HC-SR04超声波连接,通电后超声波测距并在12864液晶上实时显示,通过监测超声波返回的距离变化来统计做了俯卧撑的个数。当距离超出一定范围时蜂鸣器就会报警,提示别人姿势错误。测量的距离同时通过串口返回给电脑。
遇到的问题:目前给单片机上电后在绝大多数情况下单片机无法正常工作,液晶只亮不显示,串口助手无数据返回,蜂鸣器不响。像是没有进入到主函数中,单片机像是“僵死”了。楼主不知道是代码的问题还是硬件焊接的问题实物图如下:
我的源码可以参考如下:
#include<stc15w.h>
#include<intrins.h>
#include<stdio.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
#define Part P1 //P0接8位数据线
sbit LCD_RS=P2^6; //定义12864液晶RS端,寄存器选择信号 H:数据寄存器 L:指令寄存器
sbit LCD_RW=P2^5; //定义12864液晶RW端,读/写信号 H:读 L:写
sbit LCD_EN=P2^4; //定义12864液晶LCDEN端, 片选信号 下降沿触发,锁存数据
sbit LCD_PSB=P2^3; //定义12864液晶PSB端, H:并行 L:串行
sbit Echo1=P0^0;//超声波测距模块Echo1连接的IO
sbit Trig1=P0^1;//超声波测距模块Trig1连接的IO
sbit Echo2=P0^2;//超声波测距模块Echo2连接的IO
sbit Trig2=P0^3;//超声波测距模块Trig2连接的IO
sbit Beep=P2^7;//蜂鸣器连接的IO口
uchar show1[]="chest:0000mm";
uchar show2[]="waist:0000mm";
uchar show3[]="gap:000mm";
uchar show4[]="times:000";
uint xdata distance1=600,distance2=600,time,num=0;
uchar xdata urdat,k=1;
float xdata ratio;
char xdata m=1;
int xdata gap;
void SendData(unsigned char dat);
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void Delay20us() //@11.0592MHz
{
unsigned char i;
_nop_();
_nop_();
_nop_();
i = 52;
while (--i);
}
//====================================
//LCD忙检测函数
bit lcd_busy()
{
bit result;
LCD_RS=0;
LCD_RW=1;
LCD_EN= 1;
result=(bit)(Part & 0x80);
LCD_EN=0;
return result;
}
//=====================================
//液晶写命令函数
void lcd_write_cmd(uchar com)
{
while(lcd_busy());
LCD_RS=0; //选择指令寄存器
LCD_RW=0; //写
LCD_EN=0;
Part=com; //指令值赋给P1口
delayms(5);
LCD_EN=1;
delayms(5);
LCD_EN=0;
}
//=====================================
//液晶写一个字符数据函数
void lcd_write_dat(uchar date)
{
while(lcd_busy());
LCD_RS=1; //选择数据寄存器
LCD_RW=0; //写
LCD_EN=0;
P1=date; //数据值赋给P1口
delayms(5);
LCD_EN=1;
delayms(5);
LCD_EN=0;
}
//=====================================
//液晶写一个字符串函数
//void lcd_write_string(uchar *str)
//{
//while(*str!='\0') //未结束
// {
// lcd_write_dat(*str++);
// delayms(5);
// }
//}
//=====================================
//液晶显示位置函数
void lcd_pos(uchar x,uchar y) //从第X行的第Y位置开始显示
{
uchar pos;
if(x==1) //第一行
{ x=0x80;}
else if(x==2) //第二行
{ x=0x90;}
else if(x==3) //第三行
{ x=0x88;}
else if(x==4) //第四行
{ x=0x98;}
pos=x+y-1; //首地址为0X80
lcd_write_cmd(pos);
}
//=====================================
//液晶初始化函数
void lcd_init()
{
LCD_PSB=1; //并行方式
lcd_write_cmd(0x30);
delayms(5);
lcd_write_cmd(0x0c); //开显示,不显示光标
delayms(5);
lcd_write_cmd(0x06); //写一个字符后地址指针自动加1
delayms(5);
lcd_write_cmd(0x01); //清屏
delayms(5);
}
//=====================================
void Display1()
{
uint xdata i;
lcd_pos(1,1);
for(i=0;i<13;i++)
{lcd_write_dat(show1[i]); }
}
void Display2()
{
uint xdata i;
lcd_pos(2,1);
for(i=0;i<13;i++)
{lcd_write_dat(show2[i]); }
}
void Display3()
{
uint xdata i;
lcd_pos(3,1);
for(i=0;i<10;i++)
{lcd_write_dat(show3[i]); }
}
void Display4()
{
uint xdata i;
lcd_pos(4,1);
for(i=0;i<9;i++)
{lcd_write_dat(show4[i]); }
}
void UartInit(void)
{
SCON=0x50;//工作方式选择:8位UART波特率可变
AUXR&=0x80;
TMOD=0x00;
TL1=0xe8;
TH1=0xff;
TR1=1;
ES=1;
EA=1;
}//配置波特率,对数据采样
void Uart() interrupt 4 using 1//定时器1,16位自动重装模式
{
if(RI)
{
urdat=SBUF;//从缓冲区读取数据
RI=0;//响应中断请求后清零
SendData(urdat);
}
}
void SendData(unsigned char dat)
{
SBUF=dat;//将数据传入PC机
while(TI==0);//等待发送中断请求
TI=0;//响应中断后TI清零
}
char putchar(char c)
{
SendData(c);
return c;
}//输出成对象
void INT_init1 (void)
{
TMOD&=0x01;//定时器0,16位不可重装载工作方式
TH0=0;//定时器0清零
TL0=0;//定时器0清零
EA = 1;//总中断开
Trig1=0;//拉低为下次触发做准备
Trig2=0;
}
void dist (void)//测量距离程序
{
if(m==1)
{
Trig1=1;
Delay20us(); //延时20us
Trig1=0; //Trig输出20us高电平触发测距
while(Echo1==0); //等待Echo回波引脚变高电平
TR0=1;//程序运行到此处时说明Echo脚变成了高电平,此时启动T0开始计时
while(Echo1==1); //等待Echo回波引脚高电平结束
TR0=0;//程序运行到此处时说明Echo脚变成了低电平,此时T0停止计时
time=TH0*256+TL0;
distance1=time*0.272; //测量距离
TH0 = 0; //重置计时器
TL0 = 0;
}
if(m==-1)
{
Trig2=1;
Delay20us(); //延时20us
Trig2=0; //Trig输出20us高电平触发测距
while(Echo2==0); //等待Echo回波引脚变高电平
TR0=1;//程序运行到此处时说明Echo脚变成了高电平,此时启动T0开始计时
while(Echo2==1); //等待Echo回波引脚高电平结束
TR0=0;//程序运行到此处时说明Echo脚变成了低电平,此时T0停止计时
time=TH0*256+TL0;
distance2=time*0.24; //测量距离
TH0 = 0; //重置计时器
TL0 = 0;
}
m=-m;//轮流测量距离12
}
void main()//主函数
{
P0M0=0x00;P0M1=0x00;
P1M0=0x00;P1M1=0x00;
P2M0=0x00;P2M1=0x00;
P3M0=0x00;P3M1=0x00;//单片机IO口工作方式初始化
INT_init1();//T0初始化
UartInit();//串口初始化
lcd_init();//液晶初始化
while(1)
{
dist();//定时器测量距离
printf("dis1=%d\n",distance1);
printf("dis2=%d\n",distance2);
gap=distance1-distance2;
gap=abs(gap);
ratio=distance1/distance2;
printf("gap=%d",gap);
if(gap<=200)
{
if(distance1<190&&distance2<180)
{
k=0;
Beep=0;
delayms(50);
Beep=1;
}
else if(distance1>200&&distance2>250&&k==0)
{
k=1;
Beep=0;
delayms(50);
Beep=1;
num++;
}
// else continue;
}
else if(gap>200&&gap<400)
{
Beep=0;
delayms(120);
Beep=1;
}
// else
// {
// continue;
// }
printf("times=%d\n",num);
printf(" ");
show1[6]=distance1/1000+0x30;
show1[7]=distance1%1000/100+0x30;
show1[8]=distance1%1000%100/10+0x30;
show1[9]=distance1%10+0x30;
show2[6]=distance2/1000+0x30;
show2[7]=distance2%1000/100+0x30;
show2[8]=distance2%1000%100/10+0x30;
show2[9]=distance2%10+0x30;
show3[4]=abs(gap)/100+0x30;
show3[5]=abs(gap)%100/10+0x30;
show3[6]=abs(gap)%10+0x30;
show4[7]=num/100+0x30;
show4[8]=num%100/10+0x30;
show4[9]=num%10+0x30;
Display1();
Display2();
Display3();
Display4();
}
}
楼主我立志做一名工程师,努力学习电子制作,虽然在项目的制作中屡屡受挫,但是仍不气馁,我相信总有好心人为我指点迷津,是否可以大致指出我的项目哪里有什么硬伤?出现上述问题的可能原因是什么?如有则不胜感激!