找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2653|回复: 3
打印 上一主题 下一主题
收起左侧

SLH89F5162单片机的蓝牙控制小车程序+PCB设计

[复制链接]
跳转到指定楼层
楼主
  主控芯片为深联华SLH89F5162,开发环境为Keil 4;测距方式为超声波回声测距,使用模块HC-SR04完成;通讯方式为蓝牙2.0,车体使用HC-05蓝牙串口模块,PC使用自带蓝牙适配器;总电源使用2节3500mAh/3.7V的UltraFire锂离子充电电池串联供电;MCU电源则由LM7805稳压芯片对7.4V总电源进行处理后供给;车体驱动电机使用2个减速比为1:48的6~9V直流有刷电机,驱动使用TOSHIBA-ULN2003APG芯片;

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


单片机源程序如下:
  1. #include "SLH89F5162.h"
  2. #include "system.h"
  3. #include "car.h"
  4. #include "hc05_slh.h"
  5. #include "command.h"
  6. #include "ds18b20.h"
  7. #include "usart.h"

  8. /*超声波模块*/
  9. #define MAXTIME  65535 //最大计时时间
  10. #define TICKTIME 55295//一次中断5ms 11.0592 1T
  11. #define ECHOF P0_1
  12. #define FRONT P3_6

  13. /*PWM模块*/

  14. /*全局变量*/
  15. extern u8 totalengine;
  16. DataSet mydata;//距离+温度数据
  17. static u8 car_order;
  18. u8 buf[3];//串口1输入缓存
  19. static u16 SoundSpeed=331;//声速 单位m/s
  20. static u8 rangeflag=0,timecnt=0; //距离标志位

  21. /*获取前方的距离*/
  22. void GetFrtDist()
  23. {
  24.         SoundSpeed=331+(u16)(0.61*mydata.temp.temp_f);//更新声速

  25.         FRONT=1;delay_us(30);FRONT=0;
  26.         while(ECHOF==0)//等待高电平到来
  27.         {
  28.                 TH0=(65535-MAXTIME)/256;
  29.                 TL0=(65535-MAXTIME)%256;
  30.                 TR0=1;
  31.                 if(timecnt==1) {timecnt=0;mydata.dist[2]=255;return;}        //超时设置为255
  32.         }
  33.         TR0=0;
  34.         TH0=(65535-MAXTIME)/256;
  35.         TL0=(65535-MAXTIME)%256;
  36.         TR0=1;
  37.         while(ECHOF==1);TR0=0;//直到高电平结束停止计数        
  38.         if(rangeflag==1) {mydata.dist[2]=255;rangeflag=0;}
  39.         else mydata.dist[2]=(u8)(SoundSpeed*(65535L*timecnt+TH0*256+TL0+MAXTIME-65535)/11/10000)/2;//单位厘米
  40.         

  41. }


  42. void main()
  43. {
  44.         /*系统引脚设置*/
  45.         EA=1;//打开所有中断

  46.         /*初始化蓝牙波特率9600*/
  47.         HC05_Init(96);
  48.         /*定时器T0中断设置*/
  49.         TMOD=0;
  50.         TMOD|=0x01;                   //设T0为方式1,GATE=0,用于测距
  51.         TH0=(65535-MAXTIME)/256;
  52.         TL0=(65535-MAXTIME)%256;
  53.         IPL0=0;IPH0=0;
  54.         ET0=1;//T0允许中断

  55.         /*定时器T2中断设置*/
  56.         T2MOD=0x00;                   //设T2引脚为普通方式,递增计数,用于小车转弯,优先级次高
  57.         T2CON=0;
  58.         TH2=(65535-TICKTIME/5)/256;
  59.         TL2=(65535-TICKTIME/5)%256;
  60.         RCAP2H=(65535-TICKTIME/5)/256;
  61.         RCAP2L=(65535-TICKTIME/5)%256;//重载值 每次重载1ms
  62.         ET2=1;//T1允许中断        中断服务程序在system.c中
  63.         /*PWM设置 使用PWM0:P4.6 PWM1:P2.7*/
  64.         PWM0CON=0;
  65.         PWM0CON|=0x31;//打开PWM0引脚功能 16分频 BIT4_5控制分频系数
  66.         PWM0P=0xff;//256×时钟周期 12MHZ 16分频 对应于12khz/16=750hz
  67.         PWM0D=0;
  68.         PWM1CON=0;
  69.         PWM1CON|=0x31;//打开PWM1引脚功能
  70.         PWM1P=0xff;
  71.         PWM1D=0;

  72.         
  73.         /*初始化后部距离数据为0*/
  74.         mydata.dist[0]=0;
  75.         mydata.dist[1]=0;
  76.         mydata.dist[2]=0;
  77.         mydata.dist[3]=0;
  78.         

  79.     DS18B20_GetData(&mydata);//仅在开机时启动18B20一次获取温度
  80.         delay_ms(200);
  81.         delay_ms(200);
  82.         DS18B20_GetData(&mydata);//必须读2次才能读到正确值
  83.         if(mydata.temp.temp_f>40.0||mydata.temp.temp_f<-20.0) mydata.temp.temp_f=15.0;

  84.         while(1)
  85.         {
  86.                 /*温度信息*/
  87.                 DS18B20_GetData(&mydata);
  88.                 if(mydata.temp.temp_f>40.0||mydata.temp.temp_f<-20.0) mydata.temp.temp_f=15.0;                                                
  89.                
  90.                 /*避障信息*/
  91.                 GetFrtDist();
  92.                 if(mydata.dist[2]<=50&&car_order==GOAHEAD)
  93.                 {
  94.                         Car_Stop();
  95.                         car_order=STOP;        
  96.                 }
  97.                 else
  98.                 {
  99.                         Car_Move(car_order);
  100.                         if(car_order==GOAHEAD) delay_ms(100);
  101.                         else {delay_ms(25);car_order=STOP;}
  102.                 }
  103.                
  104.                 /*发送距离温度和位移方式*/
  105.                 Send_Data(mydata);
  106.                 Send_Stat(car_order);
  107.                                                         
  108.         }
  109.         
  110. }

  111. void T0_Interrupt() interrupt 1
  112. {
  113.         TH0=(65535-MAXTIME)/256;
  114.         TL0=(65535-MAXTIME)%256;
  115.         timecnt++;
  116.         if(timecnt==2) {timecnt=0;rangeflag=1;TR0=0;}//超时啦
  117.         
  118. }




  119. void Process_Input(u8 recdata)
  120. {
  121.         static u8 read_cnt=0;//需要读取的字节数
  122.         static u8 flag=0;//1为stat 2为data 3为mode


  123.         if(read_cnt==0 && recdata<=0x80) return;//丢弃首次无效数据
  124.         else if(read_cnt==0 && recdata>0x80 && recdata<0x8f)//read_cnt为0 收到有效起始字节
  125.         {
  126.                 read_cnt=recdata&0x0f; //记录要读取的字节数
  127.                 switch(recdata)//设置要读取的字节类型
  128.                 {
  129.                         case STAT:
  130.                                    flag=1;break;
  131.                         case MODE:
  132.                                    flag=3;break;
  133.                 }               
  134.         }
  135.         else if(read_cnt>0)//read_cnt不为0 正在接收数据
  136.         {
  137.                 /*根据flag值判断读取字节的类型*/
  138.                 if(flag==1)//stat
  139.                 {
  140.                         switch(recdata)
  141.                         {
  142.                                 case START:
  143.                                            car_order=START;break;
  144.                                 case GOAHEAD:
  145.                                            car_order=GOAHEAD;break;
  146.                                 case GORIGHT:
  147.                                            car_order=GORIGHT;break;
  148.                                 case GOLEFT:
  149.                                            car_order=GOLEFT;break;
  150.                                 case ACCEL:
  151.                                            totalengine=(totalengine>=0xff-0x20)?0xf0:(totalengine+0x20);break;
  152.                                 case SLOWD:
  153.                                            totalengine=(totalengine<=0x4f+0x20)?0xbf:(totalengine-0x20);break;
  154.                                 case STOP:
  155.                                            car_order=STOP;break;
  156.                                 default:
  157.                                                 flag=0;read_cnt=0;return;//如果第二个字节错误则清除所有标志位
  158.                         }
  159.                         read_cnt--;
  160.                         flag=(read_cnt==0)?0:flag;
  161.                 }
  162.                
  163.         }
  164. }
  165. //usart1中断服务程序
  166. //只处理接收数据
  167. void EUSART1_Interrupt() interrupt 9
  168. {        
  169.         u8 recdata=0;//串口1数据
  170.         recdata=SBUF1;
  171.         //EUSART1_SendByte(recdata);
  172.         Process_Input(recdata);        
  173.         RI1=0;
  174. ……………………

  175. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
01 基于安芯一号SLH89F5162的蓝牙控制小车.zip (4.26 MB, 下载次数: 14)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:510402 发表于 2019-4-12 12:40 | 只看该作者
这个厉害了
回复

使用道具 举报

板凳
ID:510402 发表于 2019-4-12 12:59 | 只看该作者
学习了
回复

使用道具 举报

地板
ID:510402 发表于 2019-4-12 13:10 | 只看该作者
本帖最后由 cc05142 于 2019-4-12 16:28 编辑

感谢楼主分享,楼主有成品吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表