小白轉行入門STM32----手機藍芽控制STM32微控制器點亮LED

2022-10-15 21:01:14

@

引言導讀

  1. 本文適合小白簡單入門,大神請繞行。想講的儘量透徹,所以篇幅囉嗦,介意的繞行。

  2. 藍芽模組基本是通用的,所以看這一篇教學,如果你的藍芽模組與我的不一樣,也不要擔心,原理是通的。

  3. 藍芽是通訊的一種,故想要學好STM32與藍芽連線,掌握一點點基本通訊知識是需要的。

  4. 本次涉及到的硬體包括STM32F103C8T6最小系統板(其實其他版本都是可以的)和藍芽模組買的是集芯微的BLE5.0(這家挺便宜,就是資料少,JDY-31,HC-06等都可以),此外還需要麵包板和杜邦線若干。

  5. 買的藍芽模組沒有焊接排針,而且竟然是小號排針,又手殘焊接不好。最後,買了錫膏和熱風機焊接,小號排針用網線代替了(網線也可以當作杜邦線用)。不過錫膏有毒,所以焊接時候注意通風,使用時最好帶手套或者之類的,具體自動百度或者bilibili。

一、通訊基礎知識

1.1 通訊到底傳輸的是什麼?

在邏輯層面,通訊傳輸的是位元也就是二進位制數。在物理層面上,當線路為電路時,傳送方傳送一個個持續小段時間的電壓訊號來表示這些二進位制數,比如雙方約定一個0.001秒的0V代表數位0,5V代表數位1,傳送方傳送先後傳送兩個持續0.001秒的0V和一個0.001秒的5V,就是相當於傳送了001。這種持續一段時間的電壓訊號就是碼元。當線路為無線電波時,碼元就是一份份的電波了。由於電訊號是一種波,所以可以認為我們線上路上傳輸了一個個波。

1.2 位元率和波特率

通訊速度有多快呢?在邏輯層面上,用位元率(Bitrate)來衡量,它代表單位時間內傳輸的bit數量,單位是bit/s。在物理層面上,使用波特率(Baudrate),它表示單位時間內傳輸的碼元(即,波)數量,碼元就是上面的提到的電平訊號,所以叫做波特率。通常下一個碼元代表一個二進位制數,這時位元率和波特率是相等。也有不等的時候,比如用0V表示0,2V表示1,4V表示2,6V表示3,這時候一個碼元代表一個四進位制數,則位元率是波特率的二倍。

習題

開放題目,言之成理即可,只考慮一般情形,不考慮特殊情況。

  1. 位元率和波特率的區別和聯絡?

1.1 雙工和單工

通訊類似於AB市通車,碼元類似於一輛輛汽車。

名詞 定義 例子
單工通訊 通訊線路是單向,從始至終都是傳送方和接收方是固定的 車子只能從A市到B市,B市的車子不能開往A市。
雙工通訊 線路是雙向,資料可以從A流向B,也可以從B流向A,即通訊雙方都可以發資訊給對方,又可以分為半雙工和全雙工 A市的車可以開到B市,B市的車子也可以到A市。
全雙工 線路全時段對雙方開放,任何時間任何一方都可以傳送資訊給對方 AB市之間路很寬,兩市間車子可以自由來往
半雙工 線路只能在某段時間內對某方開放,雙方輪流使用線路,即指某時間內,只能一方傳送一方接受。 AB兩個城市間公路很窄,只能容納一輛車通行,AB兩方約定8點-9點是車子只能從A市到B,9-10點是B市到A市,這樣輪流交替。

單工和雙工是對應的,按照線路是雙向的還是單向的進行劃分。
全雙工和半雙工是成對,他們是按照線路是否全時間段對雙方開放使用。

全雙工比半雙工要複雜,效率高,傳送資料多,成本更高。半雙工要簡單,雙方需要約定好時間,不然會撞車

習題

開放題目,言之成理即可,只考慮一般情形,不考慮特殊情況。

  1. 兩人交談屬於哪種通訊?
  2. 校會上,校長髮言屬於哪種通訊?
  3. 兩人吵架屬於哪種通訊?
  4. 上課傳紙條屬於哪種通訊?

1.2 序列和並行

並行通訊指雙方之間通過多根資訊線(8根以上)傳輸資料,資料可以並行傳輸,即公路很寬能夠容納多輛車並行行駛。
序列通訊指雙方之間通過很少根資訊線(8根及以下)傳輸資料,資料猶如被一根線串起來的珍珠,所以叫做序列。

序列通訊抗干擾能力強,線路鋪設費用低,速率低。

1.3 異同通訊和同步通訊

為什麼要有同步和非同步,或者它們是怎麼來的?要想回答這個問題,我們需要考慮一個場景:如何傳輸大量資料?這個問題是沒有完美解決方法的,但是最優方法是:當傳輸線路等硬體既定時,線上路滿負荷下可以最快完成資料傳輸,也就是說:傳送方馬不停蹄地傳送資料,接收方也及時接收資訊,同時為了儘可能保證資料傳輸安全性,接受方接受一個資訊後要給一個是否成功接收的狀態,傳送方在接受這個狀態後才能傳送下一個資訊。實現這種馬不停蹄,最簡單是雙方按同一套時間步調一致傳送、接收和檢驗資訊,就像生產線一樣,每個人在規定的時間內步調一致地完成各自的動作,以達到效率最高。這就是同步通訊過程。

非同步通訊則是為了完成小資料量傳輸,比如操控遙控車,這種場景下通常傳送方不定時地傳送少量資訊,接收方接收後無需回覆。相比於同步通訊這是不安全的,但是這無所謂,可以通過其他方式來修正這種不安全。比如:遙控汽車,因為某個因素,汽車沒有接受到轉向,那麼人會再次操作一遍轉向操作,問題不大。非同步通訊就不要求雙方在同一套時間下進行同步操作,只要它們是相近的時間就好。但是,雙方要有相同的波特率。

這裡的時間,其實就是時鐘週期,類似於人把時間分為年月週日時分秒,時鐘週期是把1秒分為很多份,是晶片裝置的時間。

習題

  1. 在非同步通訊中,為什麼通常情況下,雙方要保持一樣的波特率?

二、連線STM32微控制器

下面進入正題

2.1 程式設計環境

  1. CubeIDE
  2. 麵包板和連線線

2.2 硬體接線

下面給出了接線圖,

2.2.1 接線圖

2.2.1 硬體介紹和設定

買的藍芽模組如上圖,其VDD GND是接輸入電源的正負極,他要求輸入3.3V電壓,我用的STM32板子上的電源。RXD TXD是用於連線STM32板子的,RXDreceive external data引腳,用於接收來自微控制器的資訊,TXD引腳用於向微控制器傳送資訊。買的模組一般都附贈規格說明書,比如引腳、電壓、模組預設藍芽名字和波特率等。

STM32是通過USART連線藍芽模組,UART屬於非同步全雙工通訊,包含兩根線單向通訊線,分別接上述提到的兩個引腳。我用的是STM32F103C8T6晶片,它自帶有三組USART,這裡選用USART1,CubeIDE會自動選擇PA10和PA9兩個引腳與藍芽進行通訊。具體如下圖:


2.3 編碼

在這裡新增如下程式碼:

  uint8_t rx = 0; // 定義一個無符號整形數,用於接收藍芽傳送的資料。
  while (1)
  {
      /* USER CODE END WHILE */
      // 用於接受來自藍芽發來的資料。
      // &huart1 是一個封裝好的結構體,代表那兩個引腳,HAL_UART_Receive函數會自動識別使用PA10進行接受資料。
      // &rx,接收藍芽資訊放到rx中,由於rx是整形數位,直接傳遞給函數,傳過去的只是副本,所以要傳遞其參照。
      // 1,表示接受一個位元組(8個二進位制)。
      // HAL_MAX_DELAY 表示接受一個藍芽訊號後,微控制器就停下來死等下次接收藍芽資訊。
      HAL_UART_Receive(&huart1, &rx, 1, HAL_MAX_DELAY);

      // rx == '1', 藍芽傳輸過來的是一個字元1而不是數位。
	  if (rx == '1'){
	      HAL_GPIO_WritePin(GPIOA, LED_Pin, GPIO_PIN_SET); # 輸出高電平,燈亮
      }else{
	      HAL_GPIO_WritePin(GPIOA, LED_Pin, GPIO_PIN_RESET); # 輸出低電平,燈滅
	  }
    /* USER CODE BEGIN 3 */
  }

編譯程式碼並下載到微控制器上。

2.3 手機控制二極體

  1. 搜尋下載一款手機藍芽偵錯助手,我用的是BLE偵錯助手這款APP。
  2. 按照藍芽名字,搜尋並連線上藍芽,然後給藍芽傳送"1", 即可燈亮,傳送其他則燈滅。