功能:蓝牙遥控超声波避障oled屏幕显示
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include<AT89x52.H>
- #include <intrins.h>
- #include "oled.h"
- #define Left_moto_go {P1_2=1,P1_3=0;} //左边两个电机向前走
- #define Left_moto_back {P1_2=0,P1_3=1;} //左边两个电机向后转
- #define Left_moto_Stop {P1_2=0,P1_3=0;} //左边两个电机停转
- #define Right_moto_go {P1_6=1,P1_7=0;} //右边两个电机向前走
- #define Right_moto_back {P1_6=0,P1_7=1;} //右边两个电机向前走
- #define Right_moto_Stop {P1_6=0,P1_7=0;} //右边两个电机停转
- #define ECHO P2_0 //超声波接口定义
- #define TRIG P2_1 //超声波接口定义
- #define Sevro_moto_pwm P2_2 //接舵机信号端输入PWM信号调节速度
- #define BEEP P2_3
- #define left 'C'
- #define right 'D'
- #define up 'A'
- #define down 'B'
- #define stop 'F'
- #define Car1 '2' //手机软件1号键
- #define Beep '5' //手机软件5号键
- unsigned char disbuff[4] ={ 0,0,0,0,};
- unsigned char pwm_val_left = 0;//变量定义
- unsigned char push_val_left =15;//舵机归中,产生约,1.5MS 信号
- unsigned int time=0; //时间变量
- unsigned int timer=0; //延时基准变量
- unsigned long S=0; //计算出超声波距离值
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned long S4=0;
- bit flag_REC=0; //串行接收标去位
- bit flag =0;
- bit flag_xj =0;
- bit flag_bj =0;
-
- unsigned char i=0;
- unsigned char dat=0;
- unsigned char buff[5]=0; //接收缓冲字节
- /************************************************************************/
- //延时函数
- void delay(unsigned int k)
- {
- unsigned int x,y;
- for(x=0;x<k;x++)
- for(y=0;y<2000;y++);
- }
- /************************************************************************/
- //前速前进
- void run(void)
- {
- Left_moto_go ; //左电机往前走
- Right_moto_go ; //右电机往前走
- }
- //前速后退
- void backrun(void)
- {
- Left_moto_back ; //左电机往前走
- Right_moto_back ; //右电机往前走
- }
- //左转
- void leftrun(void)
- {
- Left_moto_back ; //左电机往前走
- Right_moto_go ; //右电机往前走
- }
- //右转
- void rightrun(void)
- {
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往前走
- }
- //STOP
- void stoprun(void)
- {
- Left_moto_Stop ; //左电机往前走
- Right_moto_Stop ; //右电机往前走
- }
- void whistle(void)
- {
- BEEP=0;
- }
- /************************************************************************/
- void StartModule() //启动测距信号
- {
- 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;
- }
- /***************************************************/
- void Conut(void) //计算距离
- {
- while(!ECHO); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S=(time*1.7)/100; //算出来是CM
- OLED_ShowNum(103,4,S,3,16);//距离
- }
-
- /************************************************************************/
- void COMM( void )
- {
- push_val_left=10; //舵机向左转90度
- timer=0;
- while(timer<=4000); //延时400MS让舵机转到其位置
- StartModule(); //启动超声波测距
- Conut(); //计算距离
- S2=S;
- OLED_ShowNum(103,2,S2,3,16);//左侧距离
- push_val_left=20; //舵机向右转90度
- timer=0;
- while(timer<=4000); //延时400MS让舵机转到其位置
- StartModule(); //启动超声波测距
- Conut(); //计算距离
- S4=S;
- OLED_ShowNum(103,6,S4,3,16);//右侧距离
- push_val_left=15; //舵机归中
- timer=0;
- while(timer<=4000); //延时400MS让舵机转到其位置
- StartModule(); //启动超声波测距
- Conut(); //计算距离
- S1=S;
- if((S2<20)||(S4<20)) //只要左右各有距离小于,20CM小车后退
- {
- backrun(); //后退
- timer=0;
- while(timer<=4000);
- }
-
- if(S2>S4)
- {
- rightrun(); //车的左边比车的右边距离小 右转
- timer=0;
- while(timer<=400);
- }
- else
- {
- leftrun(); //车的左边比车的右边距离大 左转
- timer=0;
- while(timer<=400);
- }
-
- }
- /************************************************************************/
- /* PWM调制舵机信号 */
- /************************************************************************/
- /* 左电机调速 */
- /*调节push_val_left的值改变电机转速,占空比 */
- void pwm_Servomoto(void)
- {
- if(pwm_val_left<=push_val_left)
- Sevro_moto_pwm=1;
- else
- Sevro_moto_pwm=0;
- if(pwm_val_left>=200)
- pwm_val_left=0;
- }
- /***************************************************/
- ///*TIMER1中断服务子函数产生PWM信号*/
- void time1()interrupt 3 using 2
- {
- TH1=(65536-100)/256; //100US定时
- TL1=(65536-100)%256;
- timer++; //定时器100US为准。在这个基础上延时
- pwm_val_left++;
- pwm_Servomoto();
- }
- /************************************************************************/
- void sint() interrupt 4 //中断接收3个字节
- {
- if(RI) //是否接收中断
- {
- RI=0;
- dat=SBUF;
- if(dat=='O'&&(i==0)) //接收数据第一帧
- {
- buff[i]=dat;
- flag=1; //开始接收数据
- }
- else
- if(flag==1)
- {
- i++;
- buff[i]=dat;
- if(i>=2)
- {i=0;flag=0;flag_REC=1 ;} // 停止接收
- }
- }
- }
- /*********************************************************************/
- /*--主函数--*/
- void main(void)
- {
- TMOD=0x11;
- TH1=(65536-100)/256; //100US定时
- TL1=(65536-100)%256;
- TH0=0;
- TL0=0;
- T2CON=0x34;
- T2MOD=0x00;
- RCAP2H=0xFF;
- RCAP2L=0xDC;
- SCON=0x50;
- PCON=0x00;
- PS=1;
- TR1=1;
- ET1=1;
- ES=1;
- EA=1;
-
- delay(100);
- OLED_Init(); //初始化OLED
- OLED_Clear();
- BEEP=1;
- push_val_left=15; //舵机归中
- OLED_ShowCHinese(0,0,0);//信
- OLED_ShowCHinese(16,0,1);//息
- OLED_ShowString(32,0,"1902",16);
- OLED_ShowCHinese(64,0,2);//王
- OLED_ShowCHinese(80,0,3);//晨
- OLED_ShowCHinese(0,2,6);//左
- OLED_ShowCHinese(16,2,9);//侧
- OLED_ShowCHinese(32,2,4);//距
- OLED_ShowCHinese(48,2,5);//离
- OLED_ShowCHinese(64,2,10);//:
-
- OLED_ShowCHinese(32,4,4);//距
- OLED_ShowCHinese(48,4,5);//离
- OLED_ShowCHinese(64,4,10);//:
-
- OLED_ShowCHinese(0,6,7);//右
- OLED_ShowCHinese(16,6,9);//侧
- OLED_ShowCHinese(32,6,4);//距
- OLED_ShowCHinese(48,6,5);//离
- OLED_ShowCHinese(64,6,10);//:
- while(1) /*无限循环*/
- {
- while(flag_bj) /*无限循环*/
- {
- if(timer>=1000) //100MS检测启动检测一次
- {
- timer=0;
- StartModule(); //启动检测
- Conut(); //计算距离
- if(S<20) //距离小于20CM
- {
- stoprun(); //小车停止
- COMM(); //方向函数
- }
- else
- if(S>30) //距离大于,30CM往前走
- run();
- }
- if(flag_REC==1)
- {
- push_val_left=15; //舵机归中
- stoprun();
- break;
- }
- }
- if(flag_REC==1) //
- {
- flag_REC=0;
- if(buff[0]=='O'&&buff[1]=='N') //第一个字节为O,第二个字节为N,第三个字节为控制码
- BEEP=1;
- switch(buff[2])
- {
- case up : // 前进
- flag_xj=0;
- flag_bj=0;
- run();
- break;
- case down: // 后退
- flag_xj=0;
- flag_bj=0;
- backrun();
- break;
- case left: // 左转
- flag_xj=0;
- flag_bj=0;
- leftrun();
- break;
- case right: // 右转
- flag_bj=0;
- rightrun();
- break;
- case stop: // 停止
- flag_bj=0;
- stoprun();
- break;
- case Car1: //
- flag_bj=1;
- break;
-
- case Beep:
- flag_bj=0;
- whistle();
- break;
- }
- }
- }
- }
-
复制代码 原理图和pcb下载:
原理图和PCB.7z
(15.05 MB, 下载次数: 269)
|