在STM32F103C8微控制器中使用RS-485串行通信

发布时间:2023-09-27  

  通信协议是数字电子和嵌入式系统的组成部分。只要有多个微控制器和外围设备的接口,就必须使用通信协议来交换大量数据。有多种类型的串行通信协议可用。RS485 是串行通信协议之一,用于工业项目和重型机械。


  本教程是关于在 STM32F103C8 微控制器中使用RS-485 串行通信。


  在本教程中,Master STM32F103C8 具有三个按钮,用于通过使用 RS-485 串行通信来控制 Slave Arduino Uno 上的三个 LED 的状态。

  RS-485 串行通讯

  RS-485 是一种不需要时钟的异步串行通信协议。它使用一种称为差分信号的技术将二进制数据从一个设备传输到另一个设备。

  那么这种差分信号传输方法是什么?

  差分信号方法通过使用正负 5V产生差分电压来工作。它在使用两线时提供半双工通信,在使用四线时提供全双工通信。

  通过使用这种方法:

  RS-485 支持最高 30Mbps 的更高数据传输率。

  与RS-232 协议相比,它还提供最大的数据传输距离。它传输的数据最大可达 1200 米。

  RS-485 相对于 RS-232 的主要优点是具有单个主控的多个从站,而 RS-232 仅支持单个从站。

  最多可以有 32 台设备连接到 RS-485 协议。

  RS-485的另一个优点是不受噪声影响,因为它们使用差分信号方法进行传输。

  RS-485 比 I2C 协议更快。

  RS-485 模块可以连接到任何具有串行端口的微控制器。为了将 RS-485 模块与微控制器一起使用,需要一个名为5V MAX485 TTL 到 RS485 的模块,该模块基于 Maxim MAX485 IC,因为它允许在 1200 米的长距离上进行串行通信,并且它是双向的,半双工的数据传输速率为 2.5 Mbps。该模块需要 5V 的电压。

  RS-485 引脚说明:

poYBAGMW9q6AV_QMAALxptpPsDI695.png

pYYBAGMW9qqAPHmQAAAi8kHSx4M283.png

  RS485模块具有以下特点:

  工作电压:5V

  板载MAX485芯片

  RS485通信的低功耗

  转换速率受限收发器

  5.08mm间距2P端子

  方便的 RS-485 通讯接线

  芯片的所有引脚均已引出,可通过微控制器进行控制

  板尺寸: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 引脚设为低电平以接收数据并设为高电平以将数据写入RS-485 总线。

  所需组件

  STM32F103C8

  Arduino UNO

  MAX485 TTL 到 RS485 转换器模块 - (2)

  10K电位器

  按钮 - 3

  LED - 3

  电阻器

  面包板

  连接电线

  电路原理图

pYYBAGMW9qSALKzFAALG_pKrTTk939.png

  在本教程中,STM32F103C8 用作带有一个 RS-485 模块的 Master,而 Arduino UNO 用作带有另一个 RS-485 模块的 Slave。

  RS-485 和 STM32F103C8 (Master) 之间的电路连接:

poYBAGMW9qCAWszFAAAVuhEXzkk201.png

  STM32F103C8 带三个按钮:

  三个带有三个 10k 下拉电阻的按钮连接到 STM32F103C8 的引脚 PA0、PA1、PA2。

  RS-485 和 Arduino UNO (Slave) 之间的电路连接:

pYYBAGMW9pyAGgkGAAAVb1UorT0962.png

  使用三个 LED,其中电阻为 330 欧姆的 LED 的阳极连接到 Arduino UNO 的引脚 4、7、8,LED 的阴极连接到 GND。

  为 RS485 串行通信编程 STM32F103C8 和 Arduino UNO

  Arduino IDE 用于开发和编程两个板,即 STM32 和 Arduino UNO。但请确保您已从Tools-》Port和 Board 从Tools-》Board中选择了相应的 PORT 。如果您发现任何困难或疑问,请参考在 ARDUINO IDE 中对您的 STM32 进行编程。本教程的编程包括两部分,第一部分用于 STM32F103C8(主),另一部分用于 Arduino UNO(从)。下面将一一解释这两个代码。

  STM32F103C8 作为主控

在主端,读取按钮的状态,然后通过 STM32F103C8 的硬件串行端口 1(PA9、PA10)将这些值串行写入 RS-485 总线。到目前为止,也不需要外部库。Arduino 具有串行通信所需的所有库。

使用硬件串行引脚(PA9、PA10)以 9600 的 buadrate 开始串行通信。

 

Serial1.开始(9600);

 

读取 STM32F103C8 的 PA0、PA1、PA2 引脚上的按钮状态,并将它们存储在变量 button1val、button2val、button3val 中。如果按下按钮,则值为 HIGH,未按下时值为 LOW。

 

int button1val = digitalRead(button1); 
int button2val = digitalRead(button2); 
int button3val = digitalRead(button3);

 

在将按钮值发送到串口之前,RS-485 的 DE 和 RE 引脚应为高电平,连接到 STM32F103C8 的引脚 PA3(使引脚 PA3 为高电平):

 

数字写入(启用引脚,高);

 

接下来将这些值放入串行端口并根据按下哪个按钮发送值,使用 if else 语句并在按下按钮时发送相应的值。

如果按下第一个按钮,则条件匹配并将值“1”发送到连接 Arduino UNO 的串行端口。

 

if (button1val == HIGH) 
    { 
      int num1 = 1; 
      Serial1.println(num1); 
    }

 

类似地,当按下按钮 2 时,值 2 通过串行端口发送,当按下按钮 3 时,值 3 通过串行端口发送。

 

否则 if (button2val == HIGH) 
    { 
      int num2 =2; 
      Serial1.println(num2); 
    } 
                else if (button3val == HIGH) 
    { 
      int num3 =3; 
      Serial1.println(num3); 
    }

 

当没有按下按钮时,值 0 被发送到 Arduino Uno。

 

   否则
   { 
     int num = 0; 
     Serial1.println(num); 
     }

 

这样就完成了将 STM32 配置为主设备的编程。 

Arduino UNO 作为奴隶

在从端,Arduino UNO 接收从主 STM32F103C8 发送的整数值,该整数值可在连接 RS-485 模块的 Arduino UNO (P0, 1) 的硬件串行端口获得。

只需读取值并存储在变量中。根据接收到的值,连接到 Arduino GPIO 的相应 LED 会打开或关闭。

要从主机接收值,只需将 RS-485 模块的 DE 和 RE 引脚设为LOW。所以 Arduino UNO 的 pin-2 (enablePin) 被设为低电平。

 

数字写入(启用引脚,低);

 

现在只需读取串行端口上可用的整数数据并将它们存储在一个变量中。

 

int 接收 = Serial.parseInt();

 

根据接收到的值,即 (0, 1, 2, 3),三个 LED 中的相应一个被打开。

 

if (receive == 1) //根据收到的值相应的 LED 打开或关闭
        { 
          digitalWrite(ledpin1,HIGH); 
        } 
        else if (receive == 2) 
        { 
          digitalWrite(ledpin2,HIGH); 
        } 
        else if (receive == 3) 
        { 
          digitalWrite(ledpin3,HIGH); 
        } 
        else 
        { 
         digitalWrite(ledpin1,LOW); 
         数字写入(ledpin2,低);
         数字写入(ledpin3,低);
        }

 

  这样就完成了将 Arduino UNO 编程和配置为从设备。这也完成了 Arduino UNO 和 STM32 的完整配置。本教程末尾附有工作视频和所有代码。

  测试 STM32F103C8 和 Arduino UNO 之间的 RS485 通信:

  1. 当按下连接到 Master STM32 的 Push button-1 时,连接到 Slave Arduino 的 LED 1 亮起。

poYBAGMW9pSAeCaTAAdn-F1KZlY528.png

  2. 按下连接到 Master STM32 的 Push button-2 时,连接到 Slave Arduino 的 LED 2 亮起。

poYBAGMW9pCAdH-cAAel0TGy5as924.png

  3. 同样,当按下按钮 3 时,LED 3 打开连接到从 Arduino。

poYBAGMW9oyAI4PeAAhrR6tmUjs239.png
主码: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);

数字写入(启用引脚,高);//(总是高,因为 Master 向 Slave 写入数据)

}


无效循环()

{

int button1val = digitalRead(button1);//读取Push Button的状态

int button2val = digitalRead(button2);

int button3val = digitalRead(button3);



if (button1val == HIGH)

{

int num1 = 1;

Serial1.println(num1); //发送按钮值 1 if HIGH (Pressed)

}

else if (button2val == HIGH)

{

int num2 =2;

Serial1.println(num2); //发送按钮值 2 if HIGH (Pressed)

}

else if (button3val == HIGH)

{

int num3 =3;

Serial1.println(num3); //发送按钮值 3 if HIGH (Pressed)

}

else

{

int num = 0;

Serial1.println(num); //如果没有按下任何按钮,则发送 0

}

delay(50);

}





从机代码:Arduino UNO:

//STM32F103C8 和 Arduino Uno 之间的 RS-485 串行通信


#define enablePin 2

#define ledpin1 4

#define ledpin2 7

#define ledpin3 8


无效设置()

{

序列.开始(9600);// 以波特率 9600 开始串行通信

pinMode(ledpin1,OUTPUT);

pinMode(ledpin2,输出);

pinMode(ledpin3,输出);

pinMode(enablePin, 输出);

延迟(10);

数字写入(启用引脚,低);//(引脚 8 始终为低电平以接收来自主机的值)

}


无效循环()


{

while (Serial.available()) //当串口有数据时,这个循环执行

{

int receive = Serial.parseInt(); // 读取从 STM32 发送的整数值



if (receive == 1) //根据接收到的值相应的 LED 打开或关闭

{

digitalWrite(ledpin1,HIGH);

}

else if (receive == 2)

{

digitalWrite(ledpin2,HIGH);

}

else if (receive == 3)

{

digitalWrite(ledpin3,HIGH);

}

else

{

digitalWrite(ledpin1,LOW);

数字写入(ledpin2,低);

数字写入(ledpin3,低);

}

}

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>