[C语言]51单片机蓝牙通信收发字符串完整源码

2019-12-28  11:27:55   WideMouth

  我的第二篇博客,其实我是一个纯物理专业的本科生,学习的是物理主流的力热电光原,阴差阳错的玩起了电子和编程(当然,也是兴趣所驱),考虑过转专业,但是迫于学校各种各样的因素,还是免了吧,就这样写写属于自己的博客,觉得挺好的。

  一开始做蓝牙通信是在上一学期(大一下学期),那时对电子特别感兴趣,刚上手了51单片机,想玩点高级点的,想到了蓝牙和语音,然后去问电信专业的一个学长(现在是我的好哥们啦),貌似电信专业的都没玩过这个,很惊讶,那就只能自己玩啦,问了一个挺牛的大三学姐,她也没做过,然后给我讲了一些特别复杂懵逼的原理,不过给了我几篇博客,那我就带着这几篇博客自主搞啦,那时学姐那刚好有一块HC-06模块,说是捡的,还不知道能不能用,那就随便玩玩啦。嘻嘻!!!还是能玩的,虽然出了各种各样的状况,不过还是基本实现了蓝牙通信啦,那是还只能单字符(其实那时也用不到字符串),后来就自己买模块玩,HC-08、HC-12、LD3320语音模块。都上手成功啦。不过后来由于焊工不太好,烧了一块语音芯片(好几十块,心疼),加上玩电子实战要焊板子,一来二去不如编程来得方便,就改手编程了。一台笔记本电脑即可,无任何成本,实战快,不过电脑是初中买的Lenovo G40-70m(2900块),自己加了块内存条和固态,嘻嘻!!!就喜欢搞这些。由于自己对电脑比较熟悉,感觉自己电脑比同学花好几千新买的高配置电脑还好用。自豪!!!

  好啦,下面开始分享啦!!!

  先上完整代码:

 

  1                      
  2 /*-----------------------------------------------------------------------------
  3 * 实 验 名    : WideMouth 51单片机字符串收发
  4 * 实验说明  : 单片机串口收发数据控制灯亮灭
  5 * 实验模块  : STC89C52RC单片机最小系统、HC-06蓝牙模块
  6 * 连接方式  :蓝牙模块RXD、TXD端分别连接单片机TXD、RXD端,蓝牙正负极连接单片机正负极
  7 * 注    意  : 单片机晶振使用的是11.0592
  8 *******************************************************************************/
  9 
 10 #include<reg52.h>
 11 #include<string.h>        //字符串处理函数包
 12 #include<intrins.h>
 13 
 14 #define uchar unsigned char    // 宏定义  51单片机内存资源有限
 15 #define uint  unsigned int    //需考虑内存资源问题,故使用无符号类型
 16     
 17  18 uchar receive_data[8];
 19 uint  bytes=0;
 20 uint bytes_old;
 21 
 22 //--定义使用的IO--//
 23 
 24 sbit Led301=P2^0;
 25 sbit Led302=P2^3;
 26 
 27 //--声明全局函数--//   
 28 void uart_init();
 29 void Delay_1ms(uint i);
 30 void SendChar(uchar character);
 31 void SendString(uchar *p); 
 32 
 33 /********************************************************************
 34 * 名称 : Com_Int()
 35 * 功能 : 串口中断函数(接受和发送数据时都会调回此函数)
 36 ***********************************************************************/
 37 void Com_Int(void) interrupt 4
 38 {
 39     EA = 0;
 40     if(RI==1)     //此句判断不能省略,否则发送数据时也会执行此语句,造成字符串错误!!!(RI为接收数据标志,当接收到数据自动置为1)
 41     {
 42         RI=0;
 43         receive_data[bytes] = SBUF;//接收到的数据
 44         bytes++;
 45     }    
 46     EA = 1;
 47 }
 48 
 49 /*******************************************************************************
 50 * 函 数 名      : main
 51 * 函数功能        : 主函数(程序入口)
 52 *******************************************************************************/
 53 
 54 void main()
 55 {
 56     bytes_old=0;
 57     uart_init();//初始化串口
 58     while(1)
 59     {
 60         while(1)
 61         {
 62                  bytes_old=bytes;
 63 
 64                 Delay_1ms(30);                 //如果单片机接收来自蓝牙模块不少于1字节的串口数据,一定要加延时后再判断是否,延时时间自己可按情况而定
 65                                              //接收数据中断一定发生在这30ms内 
 66                 if(bytes_old==bytes)         //如果在这30ms内无数据接收,说明字符串已接收完毕,这样才能完整的接收一帧串口数据 
 67                 {
 68                     receive_data[bytes]=0;     //字符串末尾加结尾标志0(对应/0)
 69                       if(bytes) break;         //跳出循环,执行相应逻辑操作
 70                 }
 71           }
 72    
 73          SendString(receive_data);             //将接收到的完整数据返回给发送端
 74 
 75         //想干啥干啥吧
 76          if(strcmp(receive_data,"3011")==0)  //strcmp(str1,str2)字符串比较函数.    参数 str1 和 str2 是参与比较的两个字符串。
 77          {                                     //若str1=str2,则返回零;
 78              Led301=0;                         //若str1<str2,则返回负数;
 79          }                                     //若str1>str2,则返回正数。
 80          if(strcmp(receive_data,"3010")==0)
 81          {
 82              Led301=1;    
 83          }
 84          if(strcmp(receive_data,"3021")==0)
 85          {
 86              Led302=0;    
 87          }
 88          if(strcmp(receive_data,"3020")==0)
 89          {
 90              Led302=1;    
 91          }
 92          bytes_old=0; //将bytes_old、bytes置为初始化值,等待接收下一字符串
 93          bytes=0;
 94     }
 95       
 96     
 97 }
 98     
 99 /*******************************************************************************
100 * 函 数 名       : uart_init()
101 * 函数功能         : 初始化配置串口
102 * 备注          :可直接复制
103 *******************************************************************************/
104 
105 void uart_init()                        //直接复制即可
106 {    
107     SCON=0X50;        //设置为工作方式1,8位数据,可变波特率
108     TMOD=0X20;        //设置计数器工作方式2
109     PCON=0X00;        //波特率不加倍
110     TH1=0XFd;        //计数器初始值设置,9600@11.0592MHz
111     TL1=0XFd;
112     TR1=1;            //打开计数器
113     ES = 1;                 //开串口中断
114     EA = 1;                 //开总中断
115 }
116 
117 /********************************************************************
118 * 名称 : Delay_1ms()
119 * 功能 : 延时子程序,延时时间为 1ms
120 * x * 输入 : x (单位为毫秒)
121 ***********************************************************************/
122 void Delay_1ms(uint i)    //1ms延时,直接复制即可
123 {
124   uint x,j;
125   for(j=0;j<i;j++)
126     for(x=0;x<=148;x++);
127 }
128 
129 /********************************************************************
130 * 名称 : SendChar(uchar character)
131 * 输入 :单个字符
132 * 功能 : 发送单个字符
133 ***********************************************************************/
134 
135 void SendChar(uchar character)  
136 {     
137      SBUF=character;   //发送单个字符
138      while(!TI);TI=0; //发送完成标志 
139 }
140 
141 /********************************************************************
142 * 名称 : SendString(uchar String[]) 
143 * 功能 : 发送字符串
144 * 输入 :字符串
145 ***********************************************************************/
146 
147 void  SendString(uchar String[]) 
148  { 
149       uchar *p=String;      
150       while(*p)               //若指针指向的地址为空,则跳出循环
151     {                            
152            SendChar(*p); //指针第一次默认指向首地址        
153         Delay_1ms(2);  //延时,作用为提高发送准确度         
154          p++;       
155     }    
156 }

 

  用的工具都是最简单的,编译软件是Keil C51,单片机是STC89C52RC,一块HC06蓝牙模块,很容易上手。程序中,uart_init()和Delay_1ms(uint i) 对于51单片机蓝牙通信都是通用的,复制即可,然后最后两个发送数据函数,第一个发送字符比较简单,第二个需要一点C语言基础,但逻辑很简单。程序最核心的是中断函数Com_Int(void)和主函数main(),中断函数比较简单,就是把接收的字符赋值给字符串,但是要注意的是必须要加上if(RI==1)判断,否则发送数据时也会执行赋值语句,造成字符串错误(RI为接收数据标志,当接收到数据自动置为1)!!!之前就是省了这一句,导致字符串老是重复,大家好奇的可以试一试,便于理解。然后最核心的是main函数中关于接收字符串的整理逻辑,从而得到一个完整的字符串数据,处理的巧妙之在于加了一行延时语句Delay_1ms(30); 函数里的时间可按情况设定,大家在这里需要花点时间好好理解一下里面的循环语句,弄明白他的处理机制,代码中有详细的备注便于你去理解。

  现在单片机程序部分就完结了哦,现在需要你动手去实战啦!!!这时还需要最后一步,来生成单片机烧录的Hex文件。点击工具栏的“魔法棒”,在Target栏修改晶振频率为11.0592,Output栏勾选Creat Hex File,然后在主界面点击ReBuild编译生成Hex文件。在Build窗口出现creating hex file from "    "...说明生成Hex文件成功啦!

  附图:

    

  现在轮到你去烧录啦,这里就不展示啦,需要你自己动手完成。加油,好运哦!!!大家如果需要源文件,可在评论区留言。

  大功告成!!! @WideMouth

  推荐:一款美观实用的蓝牙串口通信APP,内含多种自定义扩展按钮,需要的朋友可前往下载(附链接):https://www.coolapk.com/apk/com.WideMouth.bluetooth20

 

  

posted @ 2019-12-28 14:19  WideMouth  阅读(7578)  评论(0编辑  收藏  举报