楼主单片机小白一名。正在学习stc15w4k32s4这一款单片机。目前想利用超声波传感器做一个俯卧撑计数的装置。但是遇到了种种问题,经过长时间的调试仍未好转,诚心求大佬解答!
项目具体描述如下: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();
- }
- }
复制代码
楼主立志做一名工程师,努力学习电子制作,虽然在项目的制作中屡屡受挫,但是仍不气馁,我相信总有好心人为我指点迷津,是否可以大致指出我的项目哪里有什么硬伤?出现上述问题的可能原因是什么?如有则不胜感激!
|