通信協(xié)議是數(shù)字電子和嵌入式系統(tǒng)的組成部分。只要有多個微控制器和外圍設(shè)備的接口,就必須使用通信協(xié)議來交換大量數(shù)據(jù)。有多種類型的串行通信協(xié)議可用。RS485 是串行通信協(xié)議之一,用于工業(yè)項目和重型機(jī)械。
本教程是關(guān)于在 STM32F103C8 微控制器中使用RS-485 串行通信。
在本教程中,Master STM32F103C8 具有三個按鈕,用于通過使用 RS-485 串行通信來控制 Slave Arduino Uno 上的三個 LED 的狀態(tài)。
RS-485 串行通訊
RS-485 是一種不需要時鐘的異步串行通信協(xié)議。它使用一種稱為差分信號的技術(shù)將二進(jìn)制數(shù)據(jù)從一個設(shè)備傳輸?shù)搅硪粋€設(shè)備。
那么這種差分信號傳輸方法是什么?
差分信號方法通過使用正負(fù) 5V產(chǎn)生差分電壓來工作。它在使用兩線時提供半雙工通信,在使用四線時提供全雙工通信。
通過使用這種方法:
RS-485 支持最高 30Mbps 的更高數(shù)據(jù)傳輸率。
與RS-232 協(xié)議相比,它還提供最大的數(shù)據(jù)傳輸距離。它傳輸?shù)臄?shù)據(jù)最大可達(dá) 1200 米。
RS-485 相對于 RS-232 的主要優(yōu)點是具有單個主控的多個從站,而 RS-232 僅支持單個從站。
最多可以有 32 臺設(shè)備連接到 RS-485 協(xié)議。
RS-485的另一個優(yōu)點是不受噪聲影響,因為它們使用差分信號方法進(jìn)行傳輸。
RS-485 比 I2C 協(xié)議更快。
RS-485 模塊可以連接到任何具有串行端口的微控制器。為了將 RS-485 模塊與微控制器一起使用,需要一個名為5V MAX485 TTL 到 RS485 的模塊,該模塊基于 Maxim MAX485 IC,因為它允許在 1200 米的長距離上進(jìn)行串行通信,并且它是雙向的,半雙工的數(shù)據(jù)傳輸速率為 2.5 Mbps。該模塊需要 5V 的電壓。
RS-485 引腳說明:
RS485模塊具有以下特點:
工作電壓:5V
板載MAX485芯片
RS485通信的低功耗
轉(zhuǎn)換速率受限收發(fā)器
5.08mm間距2P端子
方便的 RS-485 通訊接線
芯片的所有引腳均已引出,可通過微控制器進(jìn)行控制
板尺寸:44 x 14mm
將此模塊與 STM32F103C8 和 Arduino UNO 一起使用非常容易。使用微控制器的硬件串行端口。STM32 和 arduino UNO 中的硬件串行引腳如下所示。
在 STM32F103C8 中:引腳 PA9 (TX) & PA10 (RX)
在 Arduino Uno 中:引腳 0 (RX) & 1 (TX)
編程也很簡單,只需使用Serial.print()寫入 RS-485 并使用 Serial.Read()從 RS-485 讀取,并將 RS-485 的 DE 和 RE 引腳設(shè)為低電平以接收數(shù)據(jù)并設(shè)為高電平以將數(shù)據(jù)寫入RS-485 總線。
所需組件
STM32F103C8
Arduino UNO
MAX485 TTL 到 RS485 轉(zhuǎn)換器模塊 - (2)
10K電位器
按鈕 - 3
LED - 3
面包板
連接電線
電路原理圖
在本教程中,STM32F103C8 用作帶有一個 RS-485 模塊的 Master,而 Arduino UNO 用作帶有另一個 RS-485 模塊的 Slave。
RS-485 和 STM32F103C8 (Master) 之間的電路連接:
STM32F103C8 帶三個按鈕:
三個帶有三個 10k 下拉電阻的按鈕連接到 STM32F103C8 的引腳 PA0、PA1、PA2。
RS-485 和 Arduino UNO (Slave) 之間的電路連接:
使用三個 LED,其中電阻為 330 歐姆的 LED 的陽極連接到 Arduino UNO 的引腳 4、7、8,LED 的陰極連接到 GND。
為 RS485 串行通信編程 STM32F103C8 和 Arduino UNO
Arduino IDE 用于開發(fā)和編程兩個板,即 STM32 和 Arduino UNO。但請確保您已從Tools-》Port和 Board 從Tools-》Board中選擇了相應(yīng)的 PORT 。如果您發(fā)現(xiàn)任何困難或疑問,請參考在 ARDUINO IDE 中對您的 STM32 進(jìn)行編程。本教程的編程包括兩部分,第一部分用于 STM32F103C8(主),另一部分用于 Arduino UNO(從)。下面將一一解釋這兩個代碼。
STM32F103C8 作為主控
在主端,讀取按鈕的狀態(tài),然后通過 STM32F103C8 的硬件串行端口 1(PA9、PA10)將這些值串行寫入 RS-485 總線。到目前為止,也不需要外部庫。Arduino 具有串行通信所需的所有庫。
使用硬件串行引腳(PA9、PA10)以 9600 的 buadrate 開始串行通信。
?
Serial1.開始(9600);
?
讀取 STM32F103C8 的 PA0、PA1、PA2 引腳上的按鈕狀態(tài),并將它們存儲在變量 button1val、button2val、button3val 中。如果按下按鈕,則值為 HIGH,未按下時值為 LOW。
?
int button1val = digitalRead(button1); int button2val = digitalRead(button2); int button3val = digitalRead(button3);
?
在將按鈕值發(fā)送到串口之前,RS-485 的 DE 和 RE 引腳應(yīng)為高電平,連接到 STM32F103C8 的引腳 PA3(使引腳 PA3 為高電平):
?
數(shù)字寫入(啟用引腳,高);
?
接下來將這些值放入串行端口并根據(jù)按下哪個按鈕發(fā)送值,使用 if else 語句并在按下按鈕時發(fā)送相應(yīng)的值。
如果按下第一個按鈕,則條件匹配并將值“1”發(fā)送到連接 Arduino UNO 的串行端口。
?
if (button1val == HIGH) { int num1 = 1; Serial1.println(num1); }
?
類似地,當(dāng)按下按鈕 2 時,值 2 通過串行端口發(fā)送,當(dāng)按下按鈕 3 時,值 3 通過串行端口發(fā)送。
?
否則 if (button2val == HIGH) { int num2 =2; Serial1.println(num2); } else if (button3val == HIGH) { int num3 =3; Serial1.println(num3); }
?
當(dāng)沒有按下按鈕時,值 0 被發(fā)送到 Arduino Uno。
?
否則 { int num = 0; Serial1.println(num); }
?
這樣就完成了將 STM32 配置為主設(shè)備的編程。?
Arduino UNO 作為奴隸
在從端,Arduino UNO 接收從主 STM32F103C8 發(fā)送的整數(shù)值,該整數(shù)值可在連接 RS-485 模塊的 Arduino UNO (P0, 1) 的硬件串行端口獲得。
只需讀取值并存儲在變量中。根據(jù)接收到的值,連接到 Arduino GPIO 的相應(yīng) LED 會打開或關(guān)閉。
要從主機(jī)接收值,只需將 RS-485 模塊的 DE 和 RE 引腳設(shè)為LOW。所以 Arduino UNO 的 pin-2 (enablePin) 被設(shè)為低電平。
?
數(shù)字寫入(啟用引腳,低);
?
現(xiàn)在只需讀取串行端口上可用的整數(shù)數(shù)據(jù)并將它們存儲在一個變量中。
?
int 接收 = Serial.parseInt();
?
根據(jù)接收到的值,即 (0, 1, 2, 3),三個 LED 中的相應(yīng)一個被打開。
?
if (receive == 1) //根據(jù)收到的值相應(yīng)的 LED 打開或關(guān)閉 { digitalWrite(ledpin1,HIGH); } else if (receive == 2) { digitalWrite(ledpin2,HIGH); } else if (receive == 3) { digitalWrite(ledpin3,HIGH); } else { digitalWrite(ledpin1,LOW); 數(shù)字寫入(ledpin2,低); 數(shù)字寫入(ledpin3,低); }
?
這樣就完成了將 Arduino UNO 編程和配置為從設(shè)備。這也完成了 Arduino UNO 和 STM32 的完整配置。本教程末尾附有工作視頻和所有代碼。
測試 STM32F103C8 和 Arduino UNO 之間的 RS485 通信:
1. 當(dāng)按下連接到 Master STM32 的 Push button-1 時,連接到 Slave Arduino 的 LED 1 亮起。
2. 按下連接到 Master STM32 的 Push button-2 時,連接到 Slave Arduino 的 LED 2 亮起。
3. 同樣,當(dāng)按下按鈕 3 時,LED 3 打開連接到從 Arduino。
主碼:STM32F103C8
//STM32F103C8和Arduino Uno之間的RS-485串行通信
#define button1 PA0
#define button2 PA1
#define button3 PA2
#define enablePin PA3
void setup()
{
Serial1.begin(9600); // 在串行 1 端口 PA9、PA10 以波特率 9600 開始串行通信
pinMode(enablePin, OUTPUT);
pinMode(按鈕1,輸入);
pinMode(按鈕2,輸入);
pinMode(按鈕3,輸入);
延遲(10);
數(shù)字寫入(啟用引腳,高);//(總是高,因為 Master 向 Slave 寫入數(shù)據(jù))
}
無效循環(huán)()
{
int button1val = digitalRead(button1);//讀取Push Button的狀態(tài)
int button2val = digitalRead(button2);
int button3val = digitalRead(button3);
if (button1val == HIGH)
{
int num1 = 1;
Serial1.println(num1); //發(fā)送按鈕值 1 if HIGH (Pressed)
}
else if (button2val == HIGH)
{
int num2 =2;
Serial1.println(num2); //發(fā)送按鈕值 2 if HIGH (Pressed)
}
else if (button3val == HIGH)
{
int num3 =3;
Serial1.println(num3); //發(fā)送按鈕值 3 if HIGH (Pressed)
}
else
{
int num = 0;
Serial1.println(num); //如果沒有按下任何按鈕,則發(fā)送 0
}
delay(50);
}
從機(jī)代碼:Arduino UNO:
//STM32F103C8 和 Arduino Uno 之間的 RS-485 串行通信
#define enablePin 2
#define ledpin1 4
#define ledpin2 7
#define ledpin3 8
無效設(shè)置()
{
序列.開始(9600);// 以波特率 9600 開始串行通信
pinMode(ledpin1,OUTPUT);
pinMode(ledpin2,輸出);
pinMode(ledpin3,輸出);
pinMode(enablePin, 輸出);
延遲(10);
數(shù)字寫入(啟用引腳,低);//(引腳 8 始終為低電平以接收來自主機(jī)的值)
}
無效循環(huán)()
{
while (Serial.available()) //當(dāng)串口有數(shù)據(jù)時,這個循環(huán)執(zhí)行
{
int receive = Serial.parseInt(); // 讀取從 STM32 發(fā)送的整數(shù)值
if (receive == 1) //根據(jù)接收到的值相應(yīng)的 LED 打開或關(guān)閉
{
digitalWrite(ledpin1,HIGH);
}
else if (receive == 2)
{
digitalWrite(ledpin2,HIGH);
}
else if (receive == 3)
{
digitalWrite(ledpin3,HIGH);
}
else
{
digitalWrite(ledpin1,LOW);
數(shù)字寫入(ledpin2,低);
數(shù)字寫入(ledpin3,低);
}
}
}
評論
查看更多