485 實驗

485(一般稱作 RS485/EIA-485)隸屬于 OSI 模型物理層,是串行通訊的一種。電氣特性規定 為 2 線,半雙工,多點通信的類型。它的電氣特性和 RS-232 大不一樣。用纜線兩端的電壓差值 來表示傳遞信號。RS485 僅僅規定了接受端和發送端的電氣特性。它沒有規定或推薦任何數據 協議。?

RS485 的特點包括:

1, 接口電平低,不易損壞芯片。RS485 的電氣特性:邏輯“1”以兩線間的電壓差為+(2~6)V 表 示;邏輯“0”以兩線間的電壓差為-(2~6)V 表示。接口信號電平比 RS232 降低了,不易損 壞接口電路的芯片,且該電平與 TTL 電平兼容,可方便與 TTL 電路連接。

2, 傳輸速率高。10 米時,RS485 的數據最高傳輸速率可達 35Mbps,在 1200m 時,傳輸速度 可達 100Kbps。

3, 抗干擾能力強。RS485 接口是采用平衡驅動器和差分接收器的組合,抗共模干擾能力增強, 即抗噪聲干擾性好。

4, 傳輸距離遠,支持節點多。RS485 總線最長可以傳輸 1200m 左右,更遠的距離則需要中繼 傳輸設備支持但這時(速率≤100Kbps)才能穩定傳輸,一般最大支持 32 個節點,如果使 用特制的 485 芯片,可以達到 128 個或者 256 個節點,最大的可以支持到 400 個節點。

RS485 推薦使用在點對點網絡中,比如:線型,總線型網絡等,而不能是星型,環型網絡。 理想情況下 RS485 需要 2 個終端匹配電阻,其阻值要求等于傳輸電纜的特性阻抗(一般為 120 Ω)。沒有特性阻抗的話,當所有的設備都靜止或者沒有能量的時候就會產生噪聲,而且線移需 要雙端的電壓差。沒有終接電阻的話,會使得較快速的發送端產生多個數據信號的邊緣,導致 數據傳輸出錯。485 推薦的一主多從連接方式如圖 36.1.1 所示:

在上面的連接中,如果需要添加匹配電阻,我們一般在總線的起止端加入,也就是主機和 設備 4 上面各加一個 120Ω的匹配電阻。

由于 RS485 具有傳輸距離遠、傳輸速度快、支持節點多和抗干擾能力更強等特點,所以 RS485有很廣泛的應用。實際多設備時收發器有范圍為-7V到+12V的共模電壓,為了穩定傳輸, 也有使用 3 線的布線方式,即在原有的 A、B 兩線上多增加一條地線。(4 線制使用全雙工通訊 方式,這種也叫 RS422,由于布線的難度和通訊局限,相對使用得比較少)

TP8485E/SP3485 可作為 RS485 的收發器,該芯片支持 3.3V~5.5V 供電,最大傳輸速度可 達 250Kbps,支持多達 256 個節點(單位負載為 1/8 的條件下),并且支持輸出短路保護。該芯片的框圖如圖 36.1.2 所示:?圖中 A、B 總線接口,用于連接 485 總線。RO 是接收輸出端,DI 是發送數據收入端,RE 是接收使能信號(低電平有效),DE 是發送使能信號(高電平有效)。

代碼

rs485.h

#ifndef __RS485_H
#define __RS485_H#include "./SYSTEM/sys/sys.h"/******************************************************************************************/
/* RS485 引腳 和 串口 定義 */
#define RS485_RE_GPIO_PORT                  GPIOD
#define RS485_RE_GPIO_PIN                   GPIO_PIN_7
#define RS485_RE_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)   /* PD口時鐘使能 */#define RS485_TX_GPIO_PORT                  GPIOA
#define RS485_TX_GPIO_PIN                   GPIO_PIN_2
#define RS485_TX_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口時鐘使能 */#define RS485_RX_GPIO_PORT                  GPIOA
#define RS485_RX_GPIO_PIN                   GPIO_PIN_3
#define RS485_RX_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口時鐘使能 */#define RS485_UX                            USART2
#define RS485_UX_IRQn                       USART2_IRQn
#define RS485_UX_IRQHandler                 USART2_IRQHandler
#define RS485_UX_CLK_ENABLE()               do{ __HAL_RCC_USART2_CLK_ENABLE(); }while(0)  /* USART2 時鐘使能 *//******************************************************************************************//* 控制RS485_RE腳, 控制RS485發送/接收狀態* RS485_RE = 0, 進入接收模式* RS485_RE = 1, 進入發送模式*/
#define RS485_RE(x)   do{ x ? \HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(RS485_RE_GPIO_PORT, RS485_RE_GPIO_PIN, GPIO_PIN_RESET); \}while(0)#define RS485_REC_LEN               64          /* 定義最大接收字節數 64 */
#define RS485_EN_RX                 1           /* 使能(1)/禁止(0)RS485接收 */extern uint8_t g_RS485_rx_buf[RS485_REC_LEN];   /* 接收緩沖,最大RS485_REC_LEN個字節 */
extern uint8_t g_RS485_rx_cnt;                  /* 接收數據長度 */void rs485_init( uint32_t baudrate);  /* RS485初始化 */
void rs485_send_data(uint8_t *buf, uint8_t len);    /* RS485發送數據 */
void rs485_receive_data(uint8_t *buf, uint8_t *len);/* RS485接收數據 */#endif

rs485.c?

#include "./BSP/RS485/rs485.h"
#include "./SYSTEM/delay/delay.h"UART_HandleTypeDef g_rs458_handler;     /* RS485控制句柄(串口) */#ifdef RS485_EN_RX /* 如果使能了接收 */uint8_t g_RS485_rx_buf[RS485_REC_LEN]; /* 接收緩沖, 最大 RS485_REC_LEN 個字節. */
uint8_t g_RS485_rx_cnt = 0;            /* 接收到的數據長度 */void RS485_UX_IRQHandler(void)
{uint8_t res;if ((__HAL_UART_GET_FLAG(&g_rs458_handler, UART_FLAG_RXNE) != RESET)) /* 接收到數據 */{HAL_UART_Receive(&g_rs458_handler, &res, 1, 1000);if (g_RS485_rx_cnt < RS485_REC_LEN)         /* 緩沖區未滿 */{g_RS485_rx_buf[g_RS485_rx_cnt] = res;   /* 記錄接收到的值 */g_RS485_rx_cnt++;                       /* 接收數據增加1 */}}
}#endif/*** @brief       RS485初始化函數*   @note      該函數主要是初始化串口* @param       baudrate: 波特率, 根據自己需要設置波特率值* @retval      無*/
void rs485_init(uint32_t baudrate)
{/* IO 及 時鐘配置 */RS485_RE_GPIO_CLK_ENABLE(); /* 使能 RS485_RE 腳時鐘 */RS485_TX_GPIO_CLK_ENABLE(); /* 使能 串口TX腳 時鐘 */RS485_RX_GPIO_CLK_ENABLE(); /* 使能 串口RX腳 時鐘 */RS485_UX_CLK_ENABLE();      /* 使能 串口 時鐘 */GPIO_InitTypeDef gpio_initure;gpio_initure.Pin = RS485_TX_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_AF_PP;gpio_initure.Pull = GPIO_PULLUP;gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(RS485_TX_GPIO_PORT, &gpio_initure); /* 串口TX 腳 模式設置 */gpio_initure.Pin = RS485_RX_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_AF_INPUT;HAL_GPIO_Init(RS485_RX_GPIO_PORT, &gpio_initure); /* 串口RX 腳 必須設置成輸入模式 */gpio_initure.Pin = RS485_RE_GPIO_PIN;gpio_initure.Mode = GPIO_MODE_OUTPUT_PP;gpio_initure.Pull = GPIO_PULLUP;gpio_initure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(RS485_RE_GPIO_PORT, &gpio_initure); /* RS485_RE 腳 模式設置 *//* USART 初始化設置 */g_rs458_handler.Instance = RS485_UX;                  /* 選擇485對應的串口 */g_rs458_handler.Init.BaudRate = baudrate;             /* 波特率 */g_rs458_handler.Init.WordLength = UART_WORDLENGTH_8B; /* 字長為8位數據格式 */g_rs458_handler.Init.StopBits = UART_STOPBITS_1;      /* 一個停止位 */g_rs458_handler.Init.Parity = UART_PARITY_NONE;       /* 無奇偶校驗位 */g_rs458_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 無硬件流控 */g_rs458_handler.Init.Mode = UART_MODE_TX_RX;          /* 收發模式 */HAL_UART_Init(&g_rs458_handler);                      /* HAL_UART_Init()會使能UART2 */#if RS485_EN_RX /* 如果使能了接收 *//* 使能接收中斷 */__HAL_UART_ENABLE_IT(&g_rs458_handler, UART_IT_RXNE); /* 開啟接收中斷 */HAL_NVIC_EnableIRQ(RS485_UX_IRQn);                    /* 使能USART2中斷 */HAL_NVIC_SetPriority(RS485_UX_IRQn, 3, 3);            /* 搶占優先級3,子優先級3 */
#endifRS485_RE(0); /* 默認為接收模式 */
}/*** @brief       RS485發送len個字節* @param       buf     : 發送區首地址* @param       len     : 發送的字節數(為了和本代碼的接收匹配,這里建議不要超過 RS485_REC_LEN 個字節)* @retval      無*/
void rs485_send_data(uint8_t *buf, uint8_t len)
{RS485_RE(1);                                         /* 進入發送模式 */HAL_UART_Transmit(&g_rs458_handler, buf, len, 1000); /* 串口2發送數據 */g_RS485_rx_cnt = 0;RS485_RE(0); /* 進入接收模式 */
}/*** @brief       RS485查詢接收到的數據* @param       buf     : 接收緩沖區首地址* @param       len     : 接收到的數據長度*   @arg               0   , 表示沒有接收到任何數據*   @arg               其他, 表示接收到的數據長度* @retval      無*/
void rs485_receive_data(uint8_t *buf, uint8_t *len)
{uint8_t rxlen = g_RS485_rx_cnt;uint8_t i = 0;*len = 0;     /* 默認為0 */delay_ms(10); /* 等待10ms,連續超過10ms沒有接收到一個數據,則認為接收結束 */if (rxlen == g_RS485_rx_cnt && rxlen) /* 接收到了數據,且接收完成了 */{for (i = 0; i < rxlen; i++){buf[i] = g_RS485_rx_buf[i];}*len = g_RS485_rx_cnt; /* 記錄本次數據長度 */g_RS485_rx_cnt = 0;    /* 清零 */}
}

main.c?

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/RS485/rs485.h"int main(void)
{uint8_t key;uint8_t i = 0, t = 0;uint8_t cnt = 0;uint8_t rs485buf[5];HAL_Init();                                 /* 初始化HAL庫 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 設置時鐘, 72Mhz */delay_init(72);                             /* 延時初始化 */usart_init(115200);                         /* 串口初始化為115200 */led_init();                                 /* 初始化LED */lcd_init();                                 /* 初始化LCD */key_init();                                 /* 初始化按鍵 */rs485_init(9600);                           /* 初始化RS485 */lcd_show_string(30,  50, 200, 16, 16, "STM32", RED);lcd_show_string(30,  70, 200, 16, 16, "RS485 TEST", RED);lcd_show_string(30,  90, 200, 16, 16, "ATOM@ALIENTEK", RED);lcd_show_string(30, 110, 200, 16, 16, "KEY0:Send", RED);    /* 顯示提示信息 */lcd_show_string(30, 130, 200, 16, 16, "Count:", RED);       /* 顯示當前計數值 */lcd_show_string(30, 150, 200, 16, 16, "Send Data:", RED);   /* 提示發送的數據 */lcd_show_string(30, 190, 200, 16, 16, "Receive Data:", RED);/* 提示接收到的數據 */while (1){key = key_scan(0);if (key == KEY0_PRES)   /* KEY0按下,發送一次數據 */{for (i = 0; i < 5; i++){rs485buf[i] = cnt + i;      /* 填充發送緩沖區 */lcd_show_xnum(30 + i * 32, 170, rs485buf[i], 3, 16, 0X80, BLUE);    /* 顯示數據 */}rs485_send_data(rs485buf, 5);   /* 發送5個字節 */}rs485_receive_data(rs485buf, &key);if (key)    /* 接收到有數據 */{if (key > 5)key = 5;    /* 最大是5個數據. */for (i = 0; i < key; i++){lcd_show_xnum(30 + i * 32, 210, rs485buf[i], 3, 16, 0X80, BLUE);    /* 顯示數據 */}}t++;delay_ms(10);if (t == 20){LED0_TOGGLE();  /* LED0閃爍, 提示系統正在運行 */t = 0;cnt++;lcd_show_xnum(30 + 48, 130, cnt, 3, 16, 0X80, BLUE);    /* 顯示數據 */}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/161728.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161728.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161728.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python趣味編程-5分鐘實現一個太空大戰游戲(含源碼、步驟講解)

飛機戰爭游戲系統項目是使用Python編程語言開發的,是一個簡單的桌面應用程序。 Python 中的飛機戰爭游戲使用pygame導入和隨機導入。 Pygame 是一組跨平臺的 Python 模塊,專為編寫視頻游戲而設計。它包括設計用于 Python 編程語言的計算機圖形和聲音庫。

以jar包形式 部署Spring Boot項目

后端部署 當你將Spring Boot項目打包成JAR文件并上傳到服務器時&#xff0c;可以考慮在服務器上創建一些目錄來存放這個JAR文件以及相關的配置文件。以下是一些常見的目錄結構建議&#xff1a; /opt/your-project-name/&#xff1a; 在/opt目錄下創建一個與你的項目名稱相關的…

【word技巧】Word制作試卷,ABCD選項如何對齊?

使用word文件制作試卷&#xff0c;如何將ABCD選項全部設置對齊&#xff1f;除了一直按空格或者Tab鍵以外&#xff0c;還有其他方法嗎&#xff1f;今天分享如何將ABCD選項對齊。 首先&#xff0c;我們打開【替換和查找】&#xff0c;在查找內容輸入空格&#xff0c;然后點擊全部…

省市區編碼sql

CREATE TABLE area (id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主鍵,code varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 編碼,name varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 名稱,parent_code varchar(64) COLLATE utf8mb4_bin DEFAULT NULL CO…

20個CSS函數-釋放設計創造力和響應能力

20個CSS函數-釋放設計創造力和響應能力 CSS是網頁設計的核心&#xff0c;使開發者和設計者能夠制作出令人嘆為觀止和反應迅速的網頁布局。CSS函數通過引入動態性和多功能性提升了我們的設計能力。在本文中&#xff0c;我們將開始講解20個CSS函數。 1.rgba()&#xff1a;定義顏…

結構體打印

打印輸出 通過注解來派生Debug trait&#xff0c;才可以通過println!進行打印。默認的占位符是{}&#xff0c;底層是按照std::fmt::Display具體實現進行格式化輸出。 {}、{:?}、{#?}是格式化的幾種形式&#xff0c;{#?}是更加易讀的JSON話格式。 方法 結構體聲明方法&…

【應用前沿】索托斯平臺:個性化推薦變身SaaS 服務

隨著互聯網技術和人工智能的迅速發展&#xff0c;面對海量的數據和資源&#xff0c;如何快速準確地為每個用戶提供其感興趣的內容&#xff0c;成為我們亟待解決的問題。個性化推薦系統正是為了解決這一問題而誕生的&#xff0c;它能夠通過對用戶行為的分析和挖掘&#xff0c;為…

[Ubuntu]RT810xE--網線已拔出--問題解決

0 環境 ubuntu 22.04.3 LTSDell Inspiron 15 5547windows/ubuntu 雙系統 1 問題說明 Dell 筆記本安裝的 Ubutun 系統&#xff0c;有線網絡無法使用&#xff0c;一直顯示 “網線已拔出”。 網上一查&#xff0c;才了解到主要原因&#xff1a;網卡驅動安裝錯誤。系統默認安裝…

5-6求1-20的階乘和

#include<stdio.h> //求階乘 int main(){int n;double sum0;//求和&#xff1a;一點一點加int t1;for (n1;n<15;n){tt*n;sumsumt;}printf("結果是&#xff1a;%22.15e \n",sum);return 0; }為啥最后是%22.15e呢&#xff1f; 因為這個求和的結果太大了 所以轉…

轉移表達式:<![CDATA[ ]]>

你是否遇到過&#xff1a;在mybatis 時我們sql是寫在xml 映射文件中&#xff0c;如果寫的sql中有一些特殊的字符的話&#xff0c;在解析xml文件的時候會被轉義&#xff0c;但我們不希望他被轉義&#xff0c;所以我們要使用<![CDATA[ ]]>來解決。 <![CDATA[ ]]> …

【譯】什么時候使用 Spring 6 JdbcClient

原文地址&#xff1a;Spring 6 JdbcClient: When and How to Use it? 一、前言 自 Spring 6.1 起&#xff0c;JdbcClient 為 JDBC 查詢和更新操作提供了統一的客戶端 API&#xff0c;從而提供了更流暢、更簡化的交互模型。本教程演示了如何在各種場景中使用 JdbcClient。 二…

【VScode】安裝配置、插件及遠程SSH連接

一、VSCode安裝 二、配置安裝插件 三、配置遠程連接SSH 四、MinGW 一、VSCode安裝 VS官網 Visual Studio Code - Code Editing. Redefined下載安裝包&#xff1a; 二、配置安裝插件 安裝中文插件 配置字體為20 配置文件–>首選項->設置->Font Size為20 設置 VSC…

【libGDX】使用Mesh繪制圓形

1 前言 使用Mesh繪制三角形 中介紹了繪制三角形的方法&#xff0c;使用Mesh繪制矩形 中介紹了繪制矩形的方法&#xff0c;本文將介紹繪制圓形的方法。 libGDX 以點、線段、三角形為圖元&#xff0c;沒有提供繪制圓形的接口。要繪制圓形邊框&#xff0c;必須通過割圓法逼近圓形&…

問題:vue2使用watch監視對象屬性,但是這個監視只執行了第一次,后面就沒反應了

錯誤版本 這個版本node.a的監視只會執行一次 data(){node:{}, }, watch:{"node.a":{handler(newVal,oldVal){console.log("node.a改變了")}}, }正確版本 這個可以正常監視node.a data(){node:{a:,}, }, watch:{"node.a":{handler(newVal,old…

macos創建xcframework及簽名

前言 Framework 可以理解為封裝了共享資源的具有層次結構的文件夾&#xff0c;共享資源可以是 nib文件、國際化字符串文件、頭文件、庫文件等等。它同時也是一個 Bundle&#xff0c;里面的內容可以通過 Bundle 相關 API 來訪問。Framework 可以是 static framework 或 dynamic…

CSS中實現元素居中的七種方法

在前端開發中&#xff0c;經常需要將元素居中顯示&#xff0c;CSS提供了多種技術方法來實現元素的居中&#xff0c;在不同場景下有不同的使用方法、不同的效果&#xff0c;需要特別記住它們的應用場景才能夠正常的居中。這篇文章就大致總結一下CSS中的居中方法。 一、元素分類…

[遞歸]有理數樹

有理數樹 題目描述 二叉樹指的是一種樹形結構&#xff0c;它的每個結點有至多兩個子節點。 現在有一個由有理數組成的無窮二叉樹形狀如下&#xff1a; 1/1______|______| |1/2 2/1___|___ ___|___| | | | 1/3 3/2 2/3 3/1在p/q結點位…

3.計算機網絡補充

2.5 HTTPS 數字簽名&#xff1a;發送端將消息使? hash 函數?成摘要&#xff0c;并使?私鑰加密后得到“數字簽名”&#xff0c;并將其附在消息之后。接收端使?公鑰對“數字簽名”解密&#xff0c;確認發送端身份&#xff0c;之后對消息使? hash 函數處理并與接收到的摘要對…

【中間件】服務化中間件理論intro

中間件middleware 內容管理 intro服務化middleware架構注冊中心intro服務治理系統intro 本文主要intro服務化中間件的探討 去年cfeng寫了一篇博客走馬觀花般闡述了Spring Cloud下面的各種中間件&#xff0c;連深入使用都談不上&#xff0c;只能說intro&#xff0c;在實際work中…

數字孿生助力污水處理升級

隨著科技的發展&#xff0c;數字孿生技術在各行各業中得到了廣泛應用。在污水處理領域&#xff0c;數字孿生技術為流程監控、效率提升、問題診斷等提供了強有力的支持。本文就借用山海鯨可視化軟件的污水處理解決方案為大家介紹數字孿生在污水處理領域的作用。 一、實時監控 …