[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

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM