日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

 dushikuaile 2024-03-30 發(fā)布于上海

1)實(shí)驗(yàn)平臺(tái):alientek 阿波羅 STM32F767 開發(fā)板
2)摘自《STM32F7 開發(fā)指南(HAL 庫版)》關(guān)注官方微信號(hào)公眾號(hào),獲取更多資料:正點(diǎn)原子

第三十一章 485 實(shí)驗(yàn)

本章我們將向大家介紹如何使用 STM32F4 的串口實(shí)現(xiàn) 485 通信(半雙工)。在本章中,我

們將使用 STM32F4 的串口 2 來實(shí)現(xiàn)兩塊開發(fā)板之間的 485 通信,并將結(jié)果顯示在 TFTLCD 模

塊上。本章分為如下幾個(gè)部分:

31.1 485 簡介

31.2 硬件設(shè)計(jì)

31.3 軟件設(shè)計(jì)

31.4 下載驗(yàn)證

31.1 485 簡介

485(一般稱作 RS485/EIA-485)是隸屬于 OSI 模型物理層的電氣特性規(guī)定為 2 線,半雙工,

多點(diǎn)通信的標(biāo)準(zhǔn)。它的電氣特性和 RS-232 大不一樣。用纜線兩端的電壓差值來表示傳遞信號(hào)。

RS485 僅僅規(guī)定了接受端和發(fā)送端的電氣特性。它沒有規(guī)定或推薦任何數(shù)據(jù)協(xié)議。

RS485 的特點(diǎn)包括:

1)

接口電平低,不易損壞芯片。RS485 的電氣特性:邏輯“1”以兩線間的電壓差為

+(2~6)V

表示;邏輯“0”以兩線間的電壓差為-(2~6)V 表示。接口信號(hào)電平比 RS232 降低了,

不易損壞接口電路的芯片,且該電平與 TTL 電平兼容,可方便與 TTL 電路連接。

2)

傳輸速率高。10 米時(shí),RS485 的數(shù)據(jù)最高傳輸速率可達(dá) 35Mbps,在 1200m 時(shí),

傳輸速度可達(dá) 100Kbps。

3)

抗干擾能力強(qiáng)。RS485 接口是采用平衡驅(qū)動(dòng)器和差分接收器的組合,抗共模干擾能

力增強(qiáng),即抗噪聲干擾性好。

4)

傳輸距離遠(yuǎn),支持節(jié)點(diǎn)多。RS485 總線最長可以傳輸 1200m 以上(速率≤100Kbps)

一般最大支持 32 個(gè)節(jié)點(diǎn),如果使用特制的 485 芯片,可以達(dá)到 128 個(gè)或者 256 個(gè)節(jié)點(diǎn),

最大的可以支持到 400 個(gè)節(jié)點(diǎn)。

RS485 推薦使用在點(diǎn)對點(diǎn)網(wǎng)絡(luò)中,線型,總線型,不能是星型,環(huán)型網(wǎng)絡(luò)。理想情況下 RS485

需要 2 個(gè)終端匹配電阻,其阻值要求等于傳輸電纜的特性阻抗(一般為 120Ω)。沒有特性阻抗

的話,當(dāng)所有的設(shè)備都靜止或者沒有能量的時(shí)候就會(huì)產(chǎn)生噪聲,而且線移需要雙端的電壓差。

沒有終接電阻的話,會(huì)使得較快速的發(fā)送端產(chǎn)生多個(gè)數(shù)據(jù)信號(hào)的邊緣,導(dǎo)致數(shù)據(jù)傳輸出錯(cuò)。485

推薦的連接方式如圖 31.1.2 所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.1.2 RS485 連接

在上面的連接中,如果需要添加匹配電阻,我們一般在總線的起止端加入,也就是主機(jī)和

設(shè)備 4 上面各加一個(gè) 120Ω的匹配電阻。

由于 RS485 具有傳輸距離遠(yuǎn)、傳輸速度快、支持節(jié)點(diǎn)多和抗干擾能力更強(qiáng)等特點(diǎn),所以

RS485 有很廣泛的應(yīng)用。

探索者 STM32F4 開發(fā)板采用 SP3485 作為收發(fā)器,該芯片支持 3.3V 供電,最大傳輸速度

可達(dá) 10Mbps,支持多達(dá) 32 個(gè)節(jié)點(diǎn),并且有輸出短路保護(hù)。該芯片的框圖如圖 31.1.2 所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.1.2 SP3485 框圖

圖中 A、B 總線接口,用于連接 485 總線。RO 是接收輸出端,DI 是發(fā)送數(shù)據(jù)收入端,RE

是接收使能信號(hào)(低電平有效),DE 是發(fā)送使能信號(hào)(高電平有效)。

本章,我們通過該芯片連接 STM32F4 的串口 2,實(shí)現(xiàn)兩個(gè)開發(fā)板之間的 485 通信。本章將

實(shí)現(xiàn)這樣的功能:通過連接兩個(gè)探索者 STM32F4 開發(fā)板的 RS485 接口,然后由 KEY0 控制發(fā)

送,當(dāng)按下一個(gè)開發(fā)板的 KEY0 的時(shí)候,就發(fā)送 5 個(gè)數(shù)據(jù)給另外一個(gè)開發(fā)板,并在兩個(gè)開發(fā)板

上分別顯示發(fā)送的值和接收到的值。

本章,我們只需要配置好串口 2,就可以實(shí)現(xiàn)正常的 485 通信了,串口 2 的配置和串口 1

基本類似,只是串口的時(shí)鐘來自 APB1,最大頻率為 42Mhz。

31.2 硬件設(shè)計(jì)

本章要用到的硬件資源如下:

1) 指示燈 DS0

2) KEY0 按鍵

3) TFTLCD 模塊

4) 串口 2

5) RS485 收發(fā)芯片 SP3485

前面 3 個(gè)之前都已經(jīng)詳細(xì)介紹過了,這里我們介紹 SP3485 和串口 2 的連接關(guān)系,如圖 31.2.1

所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.2.1 STM32F4 與 SP3485 連接電路圖

從上圖可以看出:STM32F4 的串口 2 通過 P9 端口設(shè)置,連接到 SP3485,通過 STM32F4

的 PG8 控制 SP3485 的收發(fā),當(dāng) PG8=0 的時(shí)候,為接收模式;當(dāng) PG8=1 的時(shí)候,為發(fā)送模式。

這里需要注意,PA2,PA3 和 ETH_MDIO 和 PWM_DAC 有共用 IO,所以在使用的時(shí)候,注意

分時(shí)復(fù)用,不能同時(shí)使用。另外 RS485_RE 信號(hào),也和 NRF_IRQ 共用 PG8,所以他們也不可

以同時(shí)使用,只能分時(shí)復(fù)用。

另外,圖中的 R38 和 R40 是兩個(gè)偏置電阻,用來保證總線空閑時(shí),A、B 之間的電壓差都

會(huì)大于 200mV(邏輯 1)。從而避免因總線空閑時(shí),A、B 壓差不定,引起邏輯錯(cuò)亂,可能出

現(xiàn)的亂碼。

然后,我們要設(shè)置好開發(fā)板上P9排針的連接,通過跳線帽將PA2和PA3分別連接到485_TX

和 485_RX 上面,如圖 31.2.2 所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.2.2 硬件連接示意圖

最后,我們用 2 根導(dǎo)線將兩個(gè)開發(fā)板 RS485 端子的 A 和 A,B 和 B 連接起來。這里注意不

要接反了(A 接 B),接反了會(huì)導(dǎo)致通訊異常!!

31.3 軟件設(shè)計(jì)

打開我們的 485 實(shí)驗(yàn)例程,可以發(fā)現(xiàn)項(xiàng)目中加入了一個(gè) rs485.c 文件以及其頭文件 rs485 文

件,同時(shí) 485 通信因?yàn)榈讓佑玫氖谴?2,所以需要引入庫函數(shù) stm32f4xx_hal_usart.c 文件和對

應(yīng)的頭文件 stm32f4xx_hal_usart.h。

打開 rs485.c 文件,代碼如下:

UART_HandleTypeDef USART2_RS485Handler; //USART2 句柄(用于 RS485)#if EN_USART2_RX//如果使能了接收//接收緩存區(qū)u8 RS485_RX_BUF[64]; //接收緩沖,最大 64 個(gè)字節(jié).//接收到的數(shù)據(jù)長度u8 RS485_RX_CNT=0;void USART2_IRQHandler(void){ u8 res; if((__HAL_UART_GET_FLAG(&USART2_RS485Handler,UART_FLAG_RXNE)!=RESET)) //接收中斷{ HAL_UART_Receive(&USART2_RS485Handler,&res,1,1000); if(RS485_RX_CNT<64) { RS485_RX_BUF[RS485_RX_CNT]=res;//記錄接收到的值 RS485_RX_CNT++;//接收數(shù)據(jù)增加 1 }}}#endif//初始化 IO 串口 2//bound:波特率void RS485_Init(u32 bound){ //GPIO 端口設(shè)置GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOA_CLK_ENABLE();//使能 GPIOA 時(shí)鐘__HAL_RCC_USART2_CLK_ENABLE();//使能 USART2 時(shí)鐘GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3;//PA2,3GPIO_Initure.Mode=GPIO_MODE_AF_PP;//復(fù)用推挽輸出GPIO_Initure.Pull=GPIO_PULLUP;//上拉GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速GPIO_Initure.Alternate=GPIO_AF7_USART2;//復(fù)用為 USART2HAL_GPIO_Init(GPIOA,&GPIO_Initure);//初始化 PA2,3//PG8 推挽輸出,485 模式控制 GPIO_Initure.Pin=GPIO_PIN_8;//PG8GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽輸出 GPIO_Initure.Pull=GPIO_PULLUP;//上拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速 HAL_GPIO_Init(GPIOG,&GPIO_Initure); //USART 初始化設(shè)置USART2_RS485Handler.Instance=USART2; //USART2USART2_RS485Handler.Init.BaudRate=bound; //波特率USART2_RS485Handler.Init.WordLength=UART_WORDLENGTH_8B;//字長為 8 位數(shù)據(jù)格式USART2_RS485Handler.Init.StopBits=UART_STOPBITS_1; //一個(gè)停止位USART2_RS485Handler.Init.Parity=UART_PARITY_NONE; //無奇偶校驗(yàn)位USART2_RS485Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;//無硬件流控USART2_RS485Handler.Init.Mode=UART_MODE_TX_RX; //收發(fā)模式HAL_UART_Init(&USART2_RS485Handler); //HAL_UART_Init()會(huì)使能 USART2 __HAL_UART_DISABLE_IT(&USART2_RS485Handler,UART_IT_TC);#if EN_USART2_RX__HAL_UART_ENABLE_IT(&USART2_RS485Handler,UART_IT_RXNE);//開啟接收中斷HAL_NVIC_EnableIRQ(USART2_IRQn); //使能 USART1 中斷HAL_NVIC_SetPriority(USART2_IRQn,3,3); //搶占優(yōu)先級 3,子優(yōu)先級 3#endifRS485_TX_EN=0; //默認(rèn)為接收模式}//RS485 發(fā)送 len 個(gè)字節(jié).//buf:發(fā)送區(qū)首地址//len:發(fā)送的字節(jié)數(shù)(為了和本代碼的接收匹配,這里建議不要超過 64 個(gè)字節(jié))void RS485_Send_Data(u8 *buf,u8 len){RS485_TX_EN=1;//設(shè)置為發(fā)送模式HAL_UART_Transmit(&USART2_RS485Handler,buf,len,1000);//串口 2 發(fā)送數(shù)據(jù)RS485_RX_CNT=0;RS485_TX_EN=0;//設(shè)置為接收模式}//RS485 查詢接收到的數(shù)據(jù)//buf:接收緩存首地址//len:讀到的數(shù)據(jù)長度void RS485_Receive_Data(u8 *buf,u8 *len){u8 rxlen=RS485_RX_CNT;u8 i=0;*len=0;//默認(rèn)為 0delay_ms(10);//等待 10ms,連續(xù)超過 10ms 沒有接收到一個(gè)數(shù)據(jù),則認(rèn)為接收結(jié)束if(rxlen==RS485_RX_CNT&&rxlen)//接收到了數(shù)據(jù),且接收完成了{(lán)for(i=0;i<rxlen;i++){buf[i]=RS485_RX_BUF[i];}*len=RS485_RX_CNT; //記錄本次數(shù)據(jù)長度RS485_RX_CNT=0;//清零}}

此部分代碼總共 4 個(gè)函數(shù),其中 RS485_Init 函數(shù)為 485 通信初始化函數(shù),其實(shí)基本上就是

在配置串口 2,只是把 PG8 也順帶配置了,用于控制 SP3485 的收發(fā)。同時(shí)如果使能中斷接收

的話,會(huì)執(zhí)行串口 2 的中斷接收配置。USART2_IRQHandler 函數(shù)用于中斷接收來自 485 總線的

數(shù)據(jù),將其存放在 RS485_RX_BUF 里面。最后 RS485_Send_Data 和 RS485_Receive_Data 這兩

個(gè)函數(shù)用來發(fā)送數(shù)據(jù)到 485 總線和讀取從 485 總線收到的數(shù)據(jù),都比較簡單。

頭文件 rs485.h 文件中,我們通過下面一行代碼打開了接受中斷:

#define EN_USART2_RX 1//0,不接收;1,接收.

其他內(nèi)容就是一些函數(shù)什么,所以這里我們不細(xì)說。

接下來,我們來看看主函數(shù)代碼:

int main(void){ u8 key;u8 i=0,t=0;u8 cnt=0;u8 rs485buf[5]; HAL_Init();//初始化 HAL 庫 Stm32_Clock_Init(336,8,2,7);//設(shè)置時(shí)鐘,168Mhzdelay_init(168);//初始化延時(shí)函數(shù)uart_init(115200);//初始化 USARTusmart_dev.init(84);//初始化 USMARTLED_Init();//初始化 LEDKEY_Init();//初始化 KEYLCD_Init();//初始化 LCDRS485_Init(9600);//初始化 RS485 POINT_COLOR=RED;LCD_ShowString(30,50,200,16,16,'Explorer STM32F4');LCD_ShowString(30,70,200,16,16,'RS485 TEST');LCD_ShowString(30,90,200,16,16,'ATOM@ALIENTEK');LCD_ShowString(30,110,200,16,16,'2017/4/14');LCD_ShowString(30,130,200,16,16,'KEY0:Send'); //顯示提示信息POINT_COLOR=BLUE;//設(shè)置字體為藍(lán)色LCD_ShowString(30,150,200,16,16,'Count:');//顯示當(dāng)前計(jì)數(shù)值LCD_ShowString(30,170,200,16,16,'Send Data:');//提示發(fā)送的數(shù)據(jù)LCD_ShowString(30,210,200,16,16,'Receive Data:');//提示接收到的數(shù)據(jù)while(1) { key=KEY_Scan(0);if(key==KEY0_PRES)//KEY0 按下,發(fā)送一次數(shù)據(jù) { for(i=0;i<5;i++){ rs485buf[i]=cnt+i;//填充發(fā)送緩沖區(qū)LCD_ShowxNum(30+i*32,190,rs485buf[i],3,16,0X80);//顯示數(shù)據(jù) } RS485_Send_Data(rs485buf,5);//發(fā)送 5 個(gè)字節(jié)}RS485_Receive_Data(rs485buf,&key);if(key)//接收到有數(shù)據(jù){if(key>5)key=5;//最大是 5 個(gè)數(shù)據(jù).for(i=0;i<key;i++)LCD_ShowxNum(30+i*32,230,rs485buf[i],3,16,0X80);//顯示數(shù)據(jù) }t++;delay_ms(10);if(t==20){LED0=!LED0;//提示系統(tǒng)正在運(yùn)行t=0;cnt++;LCD_ShowxNum(30+48,150,cnt,3,16,0X80); //顯示數(shù)據(jù)}}}

此部分代碼,我們通過函數(shù) RS485_Init(9600),初始化串口 2 的波特率為 9600。cnt 是一個(gè)

累加數(shù),一旦 KEY0 按下,就以這個(gè)數(shù)位基準(zhǔn)連續(xù)發(fā)送 5 個(gè)數(shù)據(jù)。當(dāng) 485 總線收到數(shù)據(jù)的時(shí)候,

就將收到的數(shù)據(jù)直接顯示在 LCD 屏幕上。

31.4 下載驗(yàn)證

在代碼編譯成功之后,我們通過下載代碼到 ALIENTEK 探索者 STM32F4 開發(fā)板上(注意

要 2 個(gè)開發(fā)板都下載這個(gè)代碼哦),得到如圖 31.4.1 所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.4.1 程序運(yùn)行效果圖

伴隨 DS0 的不停閃爍,提示程序在運(yùn)行。此時(shí),我們按下 KEY0 就可以在另外一個(gè)開發(fā)板

上面收到這個(gè)開發(fā)板發(fā)送的數(shù)據(jù)了。如圖 31.4.2 和圖 31.4.3 所示:

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.4.2 RS485 發(fā)送數(shù)據(jù)

探索者 STM32F407 開發(fā)板資料連載第三十一章 485 實(shí)驗(yàn)

圖 31.4.3 RS485 接收數(shù)據(jù)

圖 31.4.2 來自開發(fā)板 A,發(fā)送了 5 個(gè)數(shù)據(jù),圖 31.4.3 來自開發(fā)板 B,接收到了來自開發(fā)板

A 的 5 個(gè)數(shù)據(jù)。

本章介紹的 485 總線時(shí)通過串口控制收發(fā)的,我們只需要將 P9 的跳線帽稍作改變,該實(shí)

驗(yàn)就變成了一個(gè) RS232 串口通信實(shí)驗(yàn)了,通過對接兩個(gè)開發(fā)板的 RS232 接口,即可得到同樣的

實(shí)驗(yàn)現(xiàn)象,有興趣的讀者可以實(shí)驗(yàn)一下。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多