單片機原理與應用設計(C51編程+Proteus仿真)(第4版)課件匯 張毅剛 第8-12章 串行口的工作原理及應用 -應用系統設計_第1頁
單片機原理與應用設計(C51編程+Proteus仿真)(第4版)課件匯 張毅剛 第8-12章 串行口的工作原理及應用 -應用系統設計_第2頁
單片機原理與應用設計(C51編程+Proteus仿真)(第4版)課件匯 張毅剛 第8-12章 串行口的工作原理及應用 -應用系統設計_第3頁
單片機原理與應用設計(C51編程+Proteus仿真)(第4版)課件匯 張毅剛 第8-12章 串行口的工作原理及應用 -應用系統設計_第4頁
單片機原理與應用設計(C51編程+Proteus仿真)(第4版)課件匯 張毅剛 第8-12章 串行口的工作原理及應用 -應用系統設計_第5頁
已閱讀5頁,還剩567頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1

第8章

串行口的工作原理及應用

12

導讀:

本章首先介紹有關串行通信的基礎,然后對AT89S51單片機串行通信口(串行口)的基本結構與工作原理、相關的特殊功能寄存器,以及串行口的4種工作方式進行介紹。此外還介紹如何利用串行口實現多機串行通信,與PC機的串行通信,以及串行通信的各種應用編程。最后,從實用角度對目前單片機串行通信廣泛應用的各種常見的串行通信標準接口RS-232、RS-422及RS-485給予簡要介紹。38.1串行通信基礎隨著單片機的廣泛應用與計算機網絡技術的普及,單片機與個人計算機或單片機與單片機之間的通信使用較多。8.1.1并行通信與串行通信單片機的數據通信有并行通信與串行通信兩種方式。1.并行通信單片機的并行通信通常使用多條數據線將數據字節的各個位同時傳送,每一位數據都需要一條傳輸線,此外還需要一條或幾條控制信號線。并行通信的示意圖見圖8-1。4圖8-1

并行通信示意圖5并行通信相對傳輸速度快。但由于傳輸線較多,長距離傳送時成本高,因此這種方式適合于短距離的數據傳輸。2.串行通信單片機串行通信是將數據字節分成一位一位的形式在一條傳輸線上逐個傳送。一次只能傳送一位,對于一個字節的數據,至少要分8位才能傳送完畢。如圖8-2所示。串行通信在發送時,要把并行數據變成串行數據發送到線路上去,接收時要把串行數據再變成并行數據。

串行通信傳輸線少,長距離傳送時成本低,且可以利用電話網等現成設備,因此在單片機應用系統中,串行通信的使用非常普遍。6圖8-2

串行通信的示意圖78.1.2同步通信與異步通信串行通信又有兩種方式:異步通信與同步通信。同步串行通信是采用一個同步時鐘,通過一條同步時鐘線,加到收發雙方,使收、發雙方達到完全同步,此時,傳輸數據的位之間的距離均為“位間隔”的整數倍,同時傳送的字符間不留間隙,既保持位同步關系。同步通信及數據格式見圖8-3。異步串行通信是指收、發雙方使用各自的時鐘控制數據的發送和接收,這樣可省去連接收、發雙方的一條同步時鐘信號線,使得異步串行通信連接更加簡單且容易實現。為使收發雙方協調,要求收、發雙方的時鐘盡可能一致。8圖8-3

同步通信及數據格式9

圖8-4給出了異步串行通信的示意圖以及數據幀格式。異步串行通信是以數據幀為單位進行數據傳輸,各數據幀之間的間隔是任意的,但每個數據幀中的各位是以固定的時間傳送的。異步串行通信不要求收、發雙方時鐘嚴格一致,實現容易,成本低,但是每個數據幀要附加起始位、停止位有時還要再加上校驗位。同步串行通信相比異步串行通信,同步串行通信數據傳輸的效率較高,但是額外增加了一條同步時鐘線。10圖8-4

異步串行通信118.1.3串行通信的傳輸模式串行通信按照按照數據傳輸的方向及時間關系可分為單工、半雙工和全雙工。1.單工數據傳輸僅能按一個固定方向傳輸,不能反向傳輸,如圖8-5(a)所示。2.半雙工數據傳輸可以雙向傳輸,但不能同時進行,不能同時傳輸,如圖8-5(b)所示。3.全雙工數據傳輸可同時進行雙向傳輸,如圖8-5(c)所示。12圖8-5

單工、半雙工和全雙工的數據傳輸模式138.1.4串行通信的錯誤校驗在串行通信中,往往要對數據傳送的正確與否進行校驗。校驗時保證傳輸數據準確無誤的關鍵。常用的有奇偶校驗與循環冗余碼校驗等方法。1.奇偶校驗串行發送數據時,數據位尾隨1位奇偶校驗位(1或0)。當約定為奇校驗時,數據中“1”的個數與校驗位“1”的個數之和應為奇數;當約定為偶校驗時,數據中“1”的個數與校驗位“1”的個數之和應為偶數。數據發送方與接收方應一致。在接收數據幀時,對“1”的個數進行校驗,若發現不一致,則說明數據傳輸過程中出現了差錯,則通知發送端重發。142.代碼和校驗代碼和校驗是發送方將所發數據塊求和或各字節異或,產生一個字節的校驗字符(校驗和)附加到數據塊末尾。接收方接收數據時同時對數據塊(除校驗字節)求和或各字節異或,將所得結果與發送方的“校驗和”進行比較,如果相符,則無差錯,否則即認為在傳輸過程中出現了差錯。3.循環冗余碼校驗循環冗余碼校驗糾錯能力強,容易實現。該校驗是通過某種數學運算實現有效信息與校驗位之間的循環校驗,常用于對磁盤信息的傳輸、存儲區的完整性校驗等。是目前應用最廣的檢錯碼編碼方式之一,廣泛用于同步通信中。158.2串行口的結構結構見圖8-6。有兩個物理上獨立的接收、發送緩沖器SBUF(屬于特殊功能寄存器),可同時發送、接收數據。發送緩沖器只能寫入不能讀出接收緩沖器只能讀出不能寫入

兩個緩沖器共用一個特殊功能寄存器字節地址(99H)。控制寄存器共有兩個:特殊功能寄存器SCON和PCON。16

16

圖8-6

串行口的內部結構178.2.1串行口控制寄存器SCON串行口控制寄存器SCON,字節地址98H,可位尋址,位地址為98H~9FH,即SCON的所有位都可用軟件來進行位操作清“0”或置“1”。SCON格式見圖8-7。17圖8-7

串口控制寄存器SCON格式18

寄存器SCON各位功能:(1)SM0、SM1—串口4種工作方式選擇SM0、SM12位編碼對應4種工作方式見表8-1。

18

表8-1串口4種工作方式表8-119(2)SM2—多機通信控制位

多機通信是在方式2和方式3下進行,因此SM2位主要用于方式2或方式3。

當串口以方式2或方式3接收時,如SM2=1,則只有當接收到的第9位數據(RB8)為“1”時,才使RI置“1”,產生中斷請求,并將收到的前8位數據送入SBUF;當收到的第9位數據(RB8)為“0”時,則將收到的前8位數據丟棄。

當SM2=0時,則不論第9位數據是“1”還是“0”,都將接收的前8位數據送入SBUF中,并使RI置“1”,產生中斷請求。

方式1時,如果SM2=1,則只有收到有效的停止位時才會激活RI。

方式0時,SM2必須為0。1920(3)REN—允許串行接收位,由軟件置“1”或清“0”。

REN=1,允許串行口接收數據。

REN=0,禁止串行口接收數據。

(4)TB8—發送的第9位數據在方式2和方式3時,TB8是要發送的第9位數據,其值由軟件置“1”或清“0”。

在雙機串行通信時,TB8一般作為奇偶校驗位使用;也可在多機串行通信中表示主機發送的是地址幀還是數據幀,TB8=1為地址幀,TB8=0為數據幀。2021(5)RB8—接收的第9位數據在方式2和方式3時,RB8存放接收到的第9位數據。在方式1,如果SM2=0,RB8是接收到的停止位。在方式0,不使用RB8。(6)TI—發送中斷標志位方式0時,串行發送的第8位數據結束時,TI由硬件置“1”,在其他工作方式中,串行口發送停止位的開始時,置TI為“1”。TI=1,表示1幀數據發送結束。TI位狀態可供軟件查詢,也可申請中斷。CPU響應中斷后,在中斷服務程序向SBUF寫入要發送的下一幀數據。注意:TI必須由軟件清“0”。(7)RI—接收中斷標志位

2122串口在方式0時,接收完第8位數據時,RI由硬件置“1”。在其他工作方式中,串行接收到停止位時,該位置“1”。RI=1,表示一幀數據接收完畢,并申請中斷,要求CPU從接收SBUF取走數據。該位狀態也可供軟件查詢。

注意:RI必須由軟件清“0”。

8.2.2電源控制寄存器PCON

字節地址為87H,不能位尋址。格式見圖8-8。僅最高位SMOD與串口有關,低4位功能在第2章中已介紹。SMOD位:波特率選擇位。

2223

圖8-8

特殊功能寄存器PCON的格式24例如,方式1的波特率計算公式為

當SMOD=1時,比SMOD=0時波特率加倍,所以也稱SMOD位為波特率倍增位。24258.3串行口的4種工作方式

4種工作方式由特殊功能寄存器SCON中SM0、SM1位定義,編碼見表8-1。8.3.1方式0方式0為同步移位寄存器輸入/輸出方式。該方式并不用于兩個AT89S51單片機間的異步串行通信,而是用于外接移位寄存器,用來擴展并行I/O口。方式0以8位數據為1幀,沒有起始位和停止位,先發送或接收最低位。波特率是固定的,為fosc/12。幀格式見圖8-9。25圖8-9

方式0幀格式261.方式0輸出(1)方式0輸出的工作原理當單片機執行將數據寫入發送緩沖器SBUF指令時,產生一個正脈沖,串口把8位數據以fosc/12固定波特率從RXD腳串行輸出,低位在先,TXD腳輸出同步移位脈沖,當8位數據發送完,中斷標志位TI置“1”。

方式0的發送時序見圖8-10。2627圖8-10

方式0發送時序28(2)方式0輸出的應用案例

典型應用是串口外接串行輸入/并行輸出的同步移位寄存器74LS164,實現并行端口的擴展。

圖8-11為串口方式0,通過74LS164輸出控制8個外接LED發光二極管亮滅的接口電路。當串口設置在方式0輸出時,串行數據由RXD端(P3.0)送出,移位脈沖由TXD端(P3.1)送出。在移位脈沖的作用下,串行口發送緩沖器的數據逐位地從RXD端串行地移入74LS164中。

2829

29圖8-11

方式0輸出外接8個LED發光二極管接口電路30

【例8-1】如圖8-11,控制8個發光二極管流水點亮。圖中74LS164的8腳(CLK端)為同步脈沖輸入端,9腳為控制端,9腳電平由單片機的P1.0控制,當9腳為0時,允許串行數據由RXD端(P3.0)向74LS164的串行數據輸入端A和B(1腳和2腳)輸入,但是74LS164的8位并行輸出端關閉;當9腳為1時,A和B輸入端關閉,但是允許74LS164中的8位數據并行輸出。當串行口將8位串行數據發送完畢后,申請中斷,在中斷服務程序中,單片機向通過串行口輸出下一個8位數據。

采用中斷方式的參考程序:

#include<reg51.h>

#include<stdio.h>

sbitP1_0=0x90;

unsignedcharnSendByte;3031

voiddelay(unsignedinti)

//延時子程序{

unsignedcharj;

for(;i>0;i--)

//變量i由實際參數傳入一個值,因此i不能賦初值 for(j=0;j<125;j++);}

main()

//主程序{

SCON=0x00; //設置串行口為方式0

EA=1; //全局中斷允許

ES=1; //允許串行口中斷

nSendByte=1; //點亮數據初始為00000001送入nSendByte

SBUF=nSendByte; //向SBUF寫入點亮數據,啟動串行發送

P1_0=0; //允許串口向74LS164串行發送數據

while(1){;}}3132

voidSerial_Port()interrupt4using0//串行口中斷服務程序{

if(TI)

//如果TI=1,1個字節串行發送完畢{ P1_0=1;

//P1_0=1,允許74LS164并行輸出,流水點亮二極管

SBUF=nSendByte;//向SBUF寫入數據,啟動串行發送 delay(500);

//延時,點亮二極管持續一段時間 P1_0=0;

//P1_0=0,允許向74LS164串行寫入

nSendByte=nSendByte<<1;//點亮數據左移1位

if(nSendByte==0)

nSendByte=1; //點亮數據是否左移8次?是,重新送點亮數據

SBUF=nSendByte; //向74LS164串行發送點亮數據} TI=0;RI=0;} 3233程序說明:(1)程序中定義了全局變量nSendByte,以便在中斷服務程序中能訪問該變量。nSendByte用于存放從串行口發出的點亮數據,在程序中使用左移1位操作符“<<”對nSendByte變量進行移位,使得從串口發出的數據為0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80,從而流水點亮各個發光二極管。(2)程序中if語句的作用是當nSendByte左移1位由0x80變為0x00后,需對變量nSendByte重新賦值為1。(3)主程序中SBUF=nSendByte語句必不可少,如果沒有該語句,主程序并不從串行口發送數據,也就不會產生隨后的發送完成中斷。(4)兩條語句“while(1){;}”實現反復循環的功能。33342.方式0輸入

(1)工作原理:方式0輸入時,REN為串行口允許接收控制位,REN=0,禁止接收;REN=1,允許接收。

當CPU向串行口SCON寄存器寫入控制字(設置為方式0,并使REN位置“1”,同時RI=0)時,產生一正脈沖,串口開始接收數據。引腳RXD為數據輸入端,TXD為移位脈沖信號輸出端,接收器以fosc/12固定波特率

采樣RXD引腳

數據信息,當接收器接收完8位數據時,中斷標志RI置“1”,表示一幀接收完畢,可進行下一幀接收,時序見圖8-12。3435圖8-12

方式0接收時序36(2)方式0輸入應用舉例【例8-2】圖8-13為串口外接一片8位并行輸入、串行輸出同步移位寄存器74LS165,擴展一個8位并行輸入口的電路,可將接在74LS165的8個開關S0~S7的狀態通過串行口的方式0讀入到單片機內。74LS165的SH/LD*端(1腳)為控制端,由單片機的P1.1腳控制。若SH/LD*=0,則74LS165可以并行輸入數據,且串行輸出端關閉;當SH/LD*=1,則并行輸入關斷,可以向單片機串行傳送。當P1.0連接的開關K合上時,可進行開關S0~S7狀態數字量的并行讀入。由圖8-13,采用中斷方式來對S0~S7狀態讀取,并由單片機P2口驅動二極管點亮(開關S0~S7中的任何一個按下,則對應的二極管點亮)。37

37圖8-13

串口方式0外接并行輸入、串行輸出的同步移位寄存器38

參考程序如下:#include<reg51.h>#include"intrins.h"#include<stdio.h>sbitP1_0=0x90;sbitP1_1=0x91;unsignedcharnRxByte;

voiddelay(unsignedinti) //延時子程序{ unsignedcharj; for(;i>0;i--) //變量i由實際參數傳入一個值,因此i不能賦初值 for(j=0;j<125;j++); }

main(){

SCON=0x10; //串行口初始化為方式0 ES=1;

//允許串行口中斷EA=1; //允許全局中斷 for(;;);}

3839

voidSerial_Port()interrupt4using0//串行口中斷服務子程序{

if(P1_0==0)

//如果P1_0=0表示開關K按下,可以讀開關S0~S7的狀態 {

P1_1=0; //P1_1=0并行讀入開關的狀態

delay(1);

P1_1=1; //P1_1=1將開關的狀態串行讀入到串口中

RI=0; //接收中斷標志RI清0

nRxByte=SBUF;//接收的開關狀態數據從SBUF讀入到nRxByte單元中

P2=nRxByte;/開關狀態數據送到P2口,驅動發光二極管發光 }} 程序說明:當P1.0為0,即開關K按下,表示允許并行讀入開關S0~S7的狀態數字量,通過P1.1把SH/LD*置0,則并行讀入開關S0~S7的狀態。再讓P1.1=1,即SH/LD*置1,74LS165將剛才讀入的S0~S7狀態通過QH端(RXD腳)串行發送到單片機的SBUF中,在中斷服務程序中把SBUF中的數據讀到nRxByte單元,并送到P2口驅動8個發光二極管。39408.3.2方式1

方式1為雙機串行通信方式,如圖8-14。

當SM0、SM1=01時,串行口設為方式1雙機串行通信。TXD腳和RXD腳分別用于發送和接收數據。方式1收發一幀數據為10位,1個起始位(0),8個數據位,1個停止位(1),先發送或接收最低位。方式1幀格式見圖8-15。

40圖8-14

方式1雙機串行通信的連接電路41

方式1為波特率可變的8位異步通信接口。波特率由下式確定:

式中,SMOD為PCON寄存器的最高位的值(0或1)。41圖8-15

方式1的幀格式421.方式1發送

串口以方式1輸出,數據位由TXD端輸出,發送一幀信息為10位,1位起始位0,8位數據位(先低位)和1位停止位1,當CPU執行寫數據到發送緩沖器SBUF的命令后,就啟動發送。方式1發送時序如圖8-16。

圖8-16發送時鐘TX時鐘頻率就是發送波特率。發送開始時,內部邏輯將起始位向TXD腳(P3.1)輸出,此后每經1個TX時鐘周期,便產生1個移位脈沖,并由TXD腳輸出1個數據位。8位全發送完后,中斷標志位TI置“1”。4243圖8-16方式1發送時序442.方式1接收串行口以方式1(SM0、SM1=01)接收時(REN=1),數據從RXD(P3.0)腳輸入。當檢測到起始位負跳變時,則開始接收。方式1接收時序如圖8-17。

44圖8-17

方式1接收時序45

接收時,定時控制信號有兩種:

(1)接收移位時鐘(RX時鐘),頻率和傳送的波特率相同,

(2)位檢測器采樣脈沖,它的頻率是RX時鐘的16倍。也就是在1位數據期間,有16個采樣脈沖,以波特率的16倍速率采樣RXD引腳狀態。

當采樣到RXD端從1到0的負跳變(有可能是起始位)時,就啟動接收檢測器。接收的值是3次連續采樣(第7、8、9個脈沖時采樣),取其中兩次相同的值,以確認是否是真正起始位(負跳變)開始,這樣能較好消除干擾引起的影響,以保證可靠無誤地開始接收數據。46當確認起始位有效時,開始接收一幀信息。接收每一位數據時,也都進行3次連續采樣(第7、8、9個脈沖時采樣),接收的值是3次采樣中至少兩次相同的值,以保證接收到的數據位的準確性。當一幀數據接收完畢后,必須同時滿足以下兩個條件,這次接收才真正有效。(1)RI=0,即上一幀數據接收完成時,RI=1發出的中斷請求已被響應,SBUF中的數據已被取走,說明“接收SBUF”已空。(2)SM2=0或收到的停止位=1(方式1時,停止位已進入RB8),則將接收到的數據裝入SBUF和RB8(裝入的是停止位),且中斷標志RI置“1”。

若不能同時滿足這兩個條件,收到的數據不能裝入SBUF,這意味著該幀數據將丟失。4647

8.3.3方式2串口工作于方式2和方式3時,為9位異步通信接口。每幀數據均為11位,1位起始位0,8位數據位(先低位),1位可程控為1或0的第9位數據及1位停止位。方式2、方式3幀格式如圖8-18。方式2的波特率由下式確定:

圖8-18

方式2、方式3的幀格式481.方式2發送發送前,先由通信協議由軟件設置TB8(如奇偶校驗位或多機通信的地址/數據的標志位),然后將要發送的數據寫入SBUF,即可啟動發送過程。串行口能自動把TB8取出,并裝入到第9位數據位的位置,再逐一發送出去。發送完畢,則使TI位置“1”。方式2和方式3發送時序如圖8-19。48圖8-19

方式2和方式3發送時序492.方式2接收當SCON寄存器SM0、SM1=10,且REN=1時,允許串行口以方式2接收數據。接收時,數據由RXD端輸入,接收11位信息。當位檢測邏輯采樣到RXD引腳從1到0的負跳變,并判斷起始位有效后,便開始接收一幀信息。在接收完第9位數據后,需滿足以下兩個條件,才將接收到的數據送入接收緩沖器SBUF。(1)RI=0,意味著接收緩沖器為空。(2)SM2=0或接收到的第9位數據位RB8=1。

當滿足上述兩個條件時,接收到的數據送入SBUF(接收緩沖器),第9位數據送入RB8,且RI置“1”。若不滿足這兩個條件,接收的信息將被丟棄。

4950串行口方式2和方式3接收時序如圖8-20。圖8-20

方式2和方式3接收時序518.3.4方式3當SM0、SM1兩位為11時,串行口被定義工作在方式3。方式3為波特率可變的9位異步通信方式,除了波特率外,方式3和方式2相同。方式3發送和接收時序見圖8-16和圖8-17。方式3波特率見下式:

51528.4多機通信多個AT89S51單片機可利用串行口進行多機通信,經常采用圖8-21主從式結構。

1個主機(AT89S51單片機或其他具有串口的微機)和3個(也可為多個)AT89S51單片機組成的從機系統,如圖8-21。主機RXD與所有從機TXD端相連,TXD與所有從機RXD端相連。從機地址分別為01H、02H和03H。52圖8-21

多機通信的主從式結構53

主從式是指多機系統中,只有一個主機,其余的全是從機。主機發送的信息可以被所有從機接收,任何一個從機發送的信息,只能由主機接收。從機和從機之間不能相互直接通信,它們的通信只能經主機才能實現。

1.多機通信工作原理要保證主機與所選擇的從機實現可靠通信,必須保證串行口具有識別功能。串行口控制寄存器SCON中的SM2位就是為滿足這一條件而設置的多機通信控制位。其工作原理是在串行口以方式2(或方式3)接收時,若SM2=1,則表示進行多機通信,可能出現兩種情況。5354

(1)從機收到主機發來的第9位數據RB8=1時,前8位數據才裝入SBUF,并置中斷標志RI=1,向CPU發出中斷請求。在中斷服務程序中,從機把接收到的SBUF中數據存入數據緩沖區中。

(2)如從機接收到的第9位數據RB8=0時,則不產生中斷標志RI=1,不引起中斷,從機不接收主機發來的數據。

若SM2=0,則接收的第9位數據不論是0還是1,從機都將產生RI=1中斷標志,接收到的數據裝入SBUF中。應用AT89S51單片機串口這一特性,可實現AT89S51的多機通信。多機通信的工作過程如下。

5455

2.多機通信的工作過程

(1)各從機初始化程序允許從機的串行口中斷,將串行口編程為方式2或方式3接收,即9位異步通信方式,且SM2和REN位置“1”,使從機只處于多機通信且接收地址幀的狀態。(2)主機和某個從機通信前,先將準備接收數據的從機地址發給各從機,接著才傳送數據(或命令),主機發出的地址幀信息的第9位為1,數據(或命令)幀的第9位為0。當主機向各從機發送地址幀時,各從機串口接收到的第9位信息RB8為1,且由于各從機SM2=1,則中斷標志位RI置“1”,各從機響應中斷,在中斷服務程序中,判斷主機送來的地址是否和本機地址相符,若為本機地址,則該從機SM2位清“0”,準備接收主機的數據或命令;若地址不相符,則保持SM2=1狀態。5556(3)接著主機發送數據(或命令)幀,數據幀的第9位為0。此時各從機接收到的RB8=0,只有與前面地址相符的從機(即SM2位已清“0”的從機)才能激活中斷標志位RI,從而進入中斷服務程序,在中斷服務程序中接收主機發來的數據(或命令);

與主機發來地址不符的從機,由于SM2保持為1,又RB8=0,因此不能激活中斷標志RI,也就不能接收主機發來的數據幀。從而保證主機與從機間通信的正確性。此時主機與建立聯系的從機已設置為單機通信模式,即在整個通信中,通信的雙方都要保持發送數據的第9位(即TB8位)為0,防止其他的從機誤接收數據。

5657(4)結束數據通信并為下一次多機通信做準備。在多機通信系統中每個從機都被賦予唯一一個地址。

例如,圖8-21中3個從機的地址可設為:01H、02H、03H。還要預留1~2個“廣播地址”,它是所有從機共有的地址,例如將“廣播地址”設為00H。當主機與從機的數據通信結束后,一定要將從機再設置為多機通信模式,以便進行下一次的多機通信。這時要求與主機正在進行數據傳輸的從機必須隨時注意,一旦接收數據第9位(RB8)為“1”,說明主機傳送的不再是數據,而是地址,這個地址就有可能是“廣播地址”,當收到“廣播地址”后,便將從機的通信模式再設置成多機模式,為下一次多機通信做好準備。57588.5波特率的制定方法在串行通信中,收、發雙方發送或接收的波特率必須一致。通過軟件對串口可設定4種工作方式。其中方式0和方式2的波特率是固定的;方式1和方式3的波特率是可變的,由定時器T1的溢出率(T1每秒溢出的次數)來確定。8.5.1波特率的定義

定義:串行口每秒鐘發送(或接收)的位數稱為波特率。設發送一位所需要的時間為T,則波特率為1/T。對于定時器的不同工作方式,得到的波特率的范圍是不一樣的,這是由于定時器/計數器T1在不同工作方式下計數位數不同所決定。58598.5.2定時器T1產生波特率的計算波特率和串口工作方式有關。

(1)方式0

波特率固定為fosc的1/12,且不受SMOD位的影響。若fosc=12MHz,波特率為fosc/12,即1Mbit/s。

(2)方式2

波特率僅與SMOD位的值有關。

若fosc=12MHz:SMOD=0,波特率=187.5kbit/s;SMOD=1,波特率=375kbit/s。5960(3)方式1或方式3常用T1作為波特率發生器,其關系式為

由式(8-1),T1的溢出率和SMOD的值共同決定波特率。

在實際設定波特率時,用

定時器方式2(自動裝初值)確定波特率較理想,它不需用軟件重裝初值,可避免因軟件重裝初值帶來的定時誤差,且算出的波特率比較準確。即TL1作為8位計數器,TH1存放備用初值。60(8-1)61設定時器T1方式2的初值為X,則有

將式(8-2)代入式(8-1),則有

由式(8-3),這種方式波特率隨fosc、SMOD和初值X而變化。在實際使用時,常根據已知波特率和時鐘頻率fosc來計算T1的初值X。為避免繁雜初值計算,常用波特率和初值X間關系常列成表8-2形式,供查用。61(8-2)(8-3)6263表8-2有兩點需要注意:(1)在時鐘振蕩頻率fosc為12MHz或6MHz時,將初值X和fosc帶入式(8-3),不能整除,因此算出的波特率有一定誤差。要消除誤差可通過調整fosc實現,例如采用的時鐘頻率為11.0592MHz。因此,為減小波特率誤差,應該使用的時鐘頻率必須為11.0592MHz。(2)如果串行通信選用很低波特率(如波特率選為55),可將定時器T1設置為方式1定時。但在這種情況下,T1溢出時,需在中斷服務程序中重新裝入初值。中斷響應時間和執行指令時間會使波特率產生一定的誤差,可用改變初值的方法加以調整。6364

【例8-3】若AT89S51的時鐘為11.0592MHz,選用T1的方式2定時作為波特率發生器,波特率為2

400bit/s,求初值。設T1為方式2定時,選SMOD=0。將已知條件帶入式(8-3)

從中解

X=244=F4H。只要把F4H裝入TH1和TL1,則T1發出的波特率為2400bit/s。在實際編程中,該結果也可直接從表8-2中查到。這里時鐘振蕩頻率選為11.0592MHz,就可使初值為整數,從而產生精確的波特率。64658.6串行口應用設計案例單片機串行通信接口設計時,需考慮如下問題。(1)確定串行通信雙方的數傳速率和通信距離。(2)由串行通信的數傳速率和通信距離確定采用的串行通信接口標準。(3)注意串行通信的通信線選擇,一般選用雙絞線較好,并根據傳輸的距離選擇纖芯的直徑。如空間干擾較多,還要選擇帶有屏蔽層的雙絞線。下面首先介紹有關串行通信各種接口標準。65668.6.1串行通信標準接口RS232、RS422與RS485簡介

AT89S51串口輸入、輸出均為TTL電平。這種以TTL電平來串行傳輸數據,抗干擾性差,傳輸距離短,傳輸速率低。為提高串行通信可靠性,增大串行通信距離和提高傳輸速率,在實際設計中都采用標準串行接口,如RS-232、RS-422A、RS-485等。根據雙機通信距離和抗干擾性要求,可選擇TTL電平傳輸,或選擇RS-232C、RS-422A、RS-485串行接口進行串行數據傳輸。

1.TTL電平通信接口如兩個AT89S51相距在1.5m之內,串行口可直接相連,接口電路如圖8-9。甲機RXD與乙機TXD端相連,乙機RXD與甲機TXD端相連,從而直接用TTL電平傳輸方法來實現雙機通信。66672.RS-232C雙機通信接口如雙機通信距離在1.5~15m時,可用RS-232C標準接口實現點對點的雙機通信,接口電路見圖8-22。

圖8-22芯片MAX232A是美國MAXIM公司生產的RS-232C全雙工發送器/接收器電路芯片。67圖8-22RS-232C雙機通信接口電路68RS-232C標準規定電纜長度限定在≤15米,最高數傳速率為20kbit/s。足以覆蓋個人計算機使用的50~9600bit/s范圍。傳送的數字量采用負邏輯,且與地對稱。其中:邏輯“1”

:-3~-15V;邏輯“0”

:+3~+15V。由于單片機的引腳為TTL電平,與RS-232C標準的電平互不兼容,所以單片機使用RS-232C標準串行通信時,必須進行TTL電平與RS-232C標準電平之間的轉換。RS-232C電平與TTL電平的之間轉換,常采用美國MAXIM公司的MAX232A,它是全雙工發送器/接收器接口電路芯片,可實現TTL電平到RS-232C電平、RS-232C電平到TTL電平的轉換。MAX232A的引腳見圖8-23,內部結構及外部元件如圖8-24所示。由于芯片內部有自升壓69圖8-23MAX232A的引腳

的電平倍增電路,將+5V轉換成-

10V~+10V,滿足RS-232C標準對邏輯“1”和邏輯“0”的電平要求。工作時僅需單一的+5V電源。其片內有2個發送器,2個接收器,有TTL信號輸入/RS-232C輸出的功能,也有RS-232C輸入/TTL輸出的功能。70圖8-24MAX232的內部結構及外部元件713.RS-422A雙機通信接口

RS-232C雖應用廣泛,但推出較早,有明顯缺點:傳輸速率低、通信距離短、接口處信號易產生串擾等。于是國際上又推出了RS-422A標準。

RS-422A與RS-232C主要區別是,收發雙方信號地不再共地,RS-422A采用了平衡驅動和差分接收的方法。每個方向用于數據傳輸的是兩條平衡導線,這相當于兩個單端驅動器。輸入同一個信號時,其中一個驅動器輸出永遠是另一個驅動器反相信號。于是兩條線上傳輸的信號電平,當一個表示邏輯“1”時,另一條一定為邏輯“0”。

7172若傳輸過程中,信號中混入了干擾和噪聲(以共模形式出現),由于差分接收器的作用,就能識別有用信號并正確接收傳輸信息,使干擾和噪聲相互抵消。因此,RS-422A能在長距離、高速率下傳輸數據。最大傳輸率為10Mbit/s,此速率下,電纜允許長度為12m,如采用較低速率,最大傳輸距離可達1219m。為增加通信距離,可在通信線路上采用光電隔離,利用RS-422A標準進行雙機通信的接口電路見圖8-25。7273圖8-25RS-422A雙機通信接口電路74

圖8-25中,每通道接收端都接有3個電阻R1、R2和R3,其中R1為傳輸線的匹配電阻,取值范圍在50~1k,其他兩個電阻是為了解決第1個數據誤碼而設置的匹配電阻。為起到隔離、抗干擾作用,圖8-20中必須使用兩組獨立的電源。

圖8-25所示的SN75174、SN75175是TTL電平到RS-422A電平與RS-422A電平到TTL電平的電平轉換芯片。4.RS-485雙機通信接口RS-422A雙機通信需四芯傳輸線,長距離通信不經濟。在工業現場,常采用雙絞線傳輸的RS-485串行通信接口,很易實現多機通信。RS-485是RS-422A變型,與RS-422A區別是:RS-422A為全雙工,采用兩對平衡差分信號線;7475而RS-485為半雙工,采用一對平衡差分信號線。RS-485與多站互連是十分方便的,很易實現1對N的多機通信。

RS-485標準允許最多并聯32臺驅動器和32臺接收器。圖8-21為RS-485雙機通信接口。RS-485與RS-422A一樣,最大傳輸距離約1219m,最大傳輸速率為10Mbit/s。通信線路要采用平衡雙絞線。平衡雙絞線長度與傳輸速率成反比,在100kbit/s速率以下,才可能使用規定的最長電纜。只有在很短距離下才能獲得最大傳輸速率。一般100m長雙絞線最大傳輸速率僅為1Mbit/s。圖8-26中,RS-485以雙向、半雙工方式實現雙機通信。在AT89S51系統發送或接收數據前,應先將SN75176的發送門或接收門打開,當P1.0=1時,7576發送門打開,接收門關閉;當P1.0=0時,接收門打開,發送門關閉。

圖8-26的SN75176片內集成一個差分驅動器和一個差分接收器,且兼有TTL電平到RS-485電平、RS-485電平到TTL電平的轉換功能。此外常用的RS-485接口芯片還有MAX485。76圖8-26RS-485雙機通信接口電路77

8.6.2方式1的應用設計

【例8-4】圖8-27為單片機甲、乙雙機串行通信,雙機RXD和TXD相互交叉相連,甲機P1口接8個開關,乙機P1口接8個發光二極管。

甲機設置為只能發送不能接收的單工方式。要求甲機讀入P1口的8個開關的狀態后,通過串行口發送到乙機,乙機將接收到的甲機的8個開關的狀態數據送入P1口,由P1口的8個發光二極管來顯示8個開關的狀態。雙方晶振均采用11.0592MHz。7778

78圖8-27

單片機方式1雙機通信的連接79參考程序如下://甲機串行發送#include<reg51.h>#defineucharunsignedchar #defineuintunsignedint

voidmain(){ uchartemp=0;

TMOD=0x20; //設置定時器T1為方式2

TH1=0xfd; //波特率9600

TL1=0xfd;

SCON=0x40; //串口初始化方式1發送,不接收

PCON=0x00; //SMOD=0TR1=1; //啟動T1P1=0xff; //設置P1口為輸入

while(1){ while(TI==0); //如果TI=0,未發送完,循環等待 TI=0; //已發送完,把TI清0 temp=P1; //讀入P1口開關的狀態

SBUF=temp;} //數據送串行口發送 } 7980//乙機串行接收#include<reg51.h>#defineucharunsignedchar #defineuintunsignedint

voidmain(){

uchartemp=0;

TMOD=0x20; //設置定時器T1為方式2TH1=0xfd; //波特率9600TL1=0xfd;

SCON=0x50; //設置串口為方式1接收,REN=1PCON=0x00; //SMOD=0

TR1=1; //啟動T1

while(1)

{

while(RI==0); //若RI為0,未接收到數據

RI=0;

//接收到數據,則把RI清0

temp=SBUF;

//讀取數據存入temp中

P1=temp;

//接收的數據送P1口控制8個LED的亮滅 }}

8081【例8-5】如圖8-28,甲乙兩機以方式1進行串行通信,雙方晶振頻率均為11.059

2MHz,波特率為2400bit/s。甲機TXD腳、RXD腳分別與乙機RXD、TXD腳相連。

為觀察串行口傳輸的數據,電路中添加了兩個虛擬終端來分別顯示串口發出的數據。添加虛擬終端,只需單擊圖4-2左側工具箱中的虛擬儀器圖標,在預覽窗口中顯示的各種虛擬儀器選項,點擊“VIRTUALTERMINAL”項,并放置在原理圖編輯窗口,然后把虛擬終端的“RXD”端與單片機的“TXD”端相連即可。當串行通信開始時,甲機首先發送數據AAH,乙機收到后應答BBH,表示同意接收。甲機收到BBH后,即可發送數據。如果乙機發現數據出錯,就向甲機發送FFH,甲機收到FFH后,重新發送數據給乙機。8182

82圖8-28

方式1雙機通信的連接83串行通信時,如觀察單片機仿真運行時串行口發送出的數據,只需用鼠標右鍵點擊虛擬終端,會出現選擇菜單,點擊最下方“VirtualTerminal”項,會彈出窗口,窗口顯示了單片機串口“TXD”端發出的一個個數據字節,如圖8-29所示。設發送字節塊長度為10字節,數據緩沖區為buf,數據發送完畢要立即發送校驗和,進行數據發送準確性驗證。乙機接收到的數據存儲到數據緩沖區buf,收到一個數據塊后,再接收甲機發來的校驗和,并將其與乙機求得的校驗和比較:若相等,說明接收正確,乙機回答00H;若不等,說明接收不正確,乙機回答FFH;請求甲機重新發送。8384選擇定時器T1為方式2定時,波特率不倍增,即SMOD=0。查表8-2,可得寫入T1的初值應為F4H。以下為雙機通信程序,該程序可在甲乙兩機中運行,不同的是在程序運行之前,要人為設置TR。若選擇TR=0,表示該機為發送方;若TR=1,表示該機是接收方。程序根據TR設置,利用發送函數send()和接收函數receive()分別實現發送和接收功能。8485圖8-29

通過串口觀察兩個單片機串行口發出的數據86參考程序如下://甲機串口通信程序#include<reg51.h>#defineucharunsignedchar #defineTR //接收、發送的區別值,TR=0,為發送

ucharbuf[10]

={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};//發送的10個數據ucharsum;

voidmain(void)

//甲機主程序{

init();

//調用甲機串口初始化

if(TR==0) //TR=0,為發送

{send();} //調用發送函數

if(TR==1) //TR=1,為接收

{receive();} //調用接收函數}8687voiddelay(unsignedinti) //延時函數

{

unsignedcharj;

for(;i>0;i--)

for(j=0;j<125;j++)

;

}

voidinit(void)

//甲機串口初始化函數

{

TMOD=0x20; //T1方式2定時

TH1=0xf4; //波特率2400

TL1=0xf4;

PCON=0x00; //SMOD=0

SCON=0x50; //串行口方式1,REN=1允許接收

TR1=1; //啟動T1

}8788voidsend(void) //甲機發送函數{

uchari

do{

delay(1000);

SBUF=0xaa; //發送聯絡信號

while(TI==0); //等待數據發送完畢

TI=0; //發送完畢,清TI

while(RI==0); //等待乙機應答

RI=0; //乙機應答完畢,甲機RI清0}while(SBUF!=0xbb); //乙機未準備好,繼續聯絡

8889do{

sum=0;

//校驗和變量清0for(i=0;i<10;i++){

delay(1000);

SBUF=buf[i];

//向乙機發數據

sum+=buf[i]; //求校驗和

while(TI==0);

TI=0;

//甲機發送數據完畢,清TI}delay(1000);

SBUF=sum; //發送校驗和while(TI==0);TI=0;while(RI==0);RI=0;}while(SBUF!=0x00); //出錯,重新發送while(1);}8990

voidreceive(void)

//甲機接收函數

{

uchari;

RI=0;

while(RI==0);RI=0;

while(SBUF!=0xaa); //判乙機是否發出請求

SBUF=0xBB; //發送應答信號BBH

while(TI==0); //等待發送結束

TI=0;

sum=0; //清校驗和

for(i=0;i<10;i++)

{

while(RI==0); RI=0; //接收數據

buf[i]=SBUF; //接收一個數據

sum+=buf[i]; //求校驗和

}

9091

while(RI==0);

RI=0; //接收乙機的校驗和

if(SBUF==sum) //比較校驗和

{

SBUF=0x00; //校驗和相等,則發00H

}

else

{

SBUF=0xFF; //出錯發FFH,重新接收

while(TI==0);TI=0;

}

}

9192#include<reg51.h>

//乙機串行通信程序#defineucharunsignedchar #defineTR1 //接收、發送的區別值,TR=1,為接收ucharidatabuf[10]={0x01,0x02,0x03,0x04,0x05, 0x06,0x07,0x08,0x09,0x0a}; ucharsum;

//校驗和

voiddelay(unsignedinti){

unsignedcharj;

for(;i>0;i--) for(j=0;j<125;j++) ;}9293

voidinit(void)//乙機串口初始化函數{ TMOD=0x20; //T1方式2定時 TH1=0xf4; //波特率2400 TL1=0xf4; PCON=0x00; //SMOD=0 SCON=0x50; //串行口方式1,REN=1允許接收 TR1=1; //啟動T1}

voidmain(void)

//乙機主程序{

init();

if(TR==0) //TR=0,為發送

{send();} //調用發送函數else

{receive();} //調用接收函數}9394

voidsend(void)

//乙機發送函數{ uchari;

do{

SBUF=0xAA; //發送聯絡信號 while(TI==0); //等待數據發送完畢 TI=0; while(RI==0);

//等待乙機應答 RI=0; }while(SBUF!=0xbb); //乙機未準備好,繼續聯絡(按位取異或)9495do{ sum=0;

//校驗和變量清0

for(i=0;i<10;i++) { SBUF=buf[i];

sum+=buf[i]; //求校驗和 while(TI==0); TI=0; } SBUF=sum; while(TI==0);TI=0; while(RI==0);RI=0;}while(SBUF!=0); //出錯,重新發送}9596voidreceive(void)

//乙機接收函數{

uchari;

RI=0;while(RI==0);RI=0;while(SBUF!=0xaa) { SBUF=0xff; while(TI!=1); TI=0; delay(1000); } //判甲機是否發出請求SBUF=0xBB; //發送應答信號0xBBwhile(TI==0);

//等待發送結束TI=0; sum=0;9697

for(i=0;i<10;i++)

{

while(RI==0);RI=0; //接收校驗和

buf[i]=SBUF; //接收一個數據

sum+=buf[i]; //求校驗和

}

while(RI==0);

RI=0; //接收甲機的校驗和

if(SBUF==sum) //比較校驗和

{

SBUF=0x00; //校驗和相等,則發00H

}

else

{

SBUF=0xFF; //出錯發FFH,重新接收

while(TI==0); TI=0;

}

}

9798

8.6.3方式2和方式3的應用設計舉例方式2與方式1相比兩點不同之處:(1)方式2接收/發送11位信息,第0位為起始位,第1~8位為數據位,第9位是程控位,由用戶設置的TB8位決定,第10位是停止位1,這是方式2與方式1的一個不同點。(2)方式2的波特率變化范圍比方式1小,方式2的波特率=振蕩器頻率/n。當SMOD=0時,n=64。當SMOD=1時,n=32。而方式2和方式3相比,除了波特率的差別外,其它都相同,所以下面介紹的方式3應用編程,也適用于方式2。9899

【例8-6】如圖8-30,甲、乙兩單片機進行

方式3(或方式2)串行通信。甲機把控制8個流水燈點亮的數據發送給乙機并點亮其P1口的8個LED。方式3比方式1多了1個可編程位TB8,該位一般作奇偶校驗位。乙機接收到的8位二進制數據有可能出錯,需進行奇偶校驗,其方法是將乙機的RB8和PSW的奇偶校驗位P進行比較,如果相同,接收數據;否則拒絕接收。本例使用了一個虛擬終端來觀察甲機串口發出的數據。99100

100圖8-30

甲乙兩個單片機進行方式3(或方式2)串行通信101參考程序如下。//甲機發送程序#include<reg51.h>sbitP=PSW^0;

//P位為PSW寄存器的第0位,即奇偶校驗位unsignedcharTab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,

0xbf,0x7f};

//控制流水燈顯示數據數組,為全局變量voidmain(void) //主函數{

unsignedchari;

TMOD=0x20; //設置定時器T1為方式2

SCON=0xc0; //設置串口為方式3

PCON=0x00; //SMOD=0

101102

TH1=0xfd; //給T1賦初值,波特率設置為9600

TL1=0xfd;

TR1=1; //啟動定時器T1

while(1)

{

for(i=0;i<8;i++)

{

Send(Tab[i]);

delay(); //大約200ms發送一次數據

}

}

}

voidSend(unsignedchardat) //發送1字節數據的函數

{

TB8=P; //將偶校驗位作為第9位數據發送

SBUF=dat;

while(TI==0); //檢測TI,TI=0,未發送完

; //空操作

TI=0; //1字節發送完,TI清0

}

102103

voiddelay(void)

//延時約200ms的函數{

unsignedcharm,n;

for(m=0;m<250;m++)

for(n=0;n<250;n++);}

//乙機接收程序

#include<reg51.h>sbitP=PSW^0; //P位為PSW寄存器的第0位,即奇偶校驗位

voidmain(void) //主函數{

TMOD=0x20; //設置定時器T1為方式2

SCON=0xd0; //設置串口為方式3,允許接收REN=1

PCON=0x00; //SMOD=0

TH1=0xfd; //給定時器T1賦初值,波特率為9600

TL1=0xfd;

TR1=1; //接通定時器T1

REN=1; //允許接收

103104

while(1)

{

P1=Receive(); //將接收到的數據送P1口顯示

}

}

unsignedcharReceive(void) //接收1字節數據的函數

{

unsignedchardat;

while(RI==0); //檢測RI,RI=0,未接收完,則循環等待

;

RI=0; //已接收一幀數據,將RI清0

ACC=SBUF; //將接收緩沖器的數據存于ACC

if(RB8==P) //只有偶校驗成功才能往下執行,接收數據

{

dat=ACC; //將接收緩沖器的數據存于dat

returndat; //將接收的數據返回

}

}

104105

8.6.4多機通信的應用設計下面通過一個具體案例,介紹如何來實現單片機的多機通信。

【例8-7】實現主單片機分別與3個從單片機串行通信,原理電路見圖8-31。用戶通過分別按下開關k1、k2或k3來選擇主機與對應1#、2#或3#從機串行通信,當黃色LED點亮,表示主機與相應的從機連接成功;該從機的8個綠色LED閃亮,表示主機與從機在進行串行數據通信。如果斷開k1、k2或k3,則主機與相應從機的串行通信中斷。105106

106圖8-31

主機與3從機的多機通信的原理電路與仿真107本例實現主、從機串行通信,各從機程序都相同,只是地址不同。串行通信約定如下。(1)3臺從機的地址為01H~03H。(2)主機發出的0xff為控制命令,使所有從機都處于SM2=1的狀態。(3)其余的控制命令:00H—接收命令,01H—發送命令。這兩條命令是以數據幀形式發送的。(4)從機的狀態字如圖8-32所示。107圖8-32

從機狀態字格式約定108其中:

ERR(D7位)=1,表示收到非法命令。

TRDY(D1位)=1,表示發送準備完畢。

RRDY(D0位)=1,表示接收準備完畢。串行通信時,主機采用查詢方式,從機采用中斷方式。主機串口設為方式3,允許接收,并置TB8為1。因只有1個主機,所以主機SCON控制寄存器中的SM2不要置1,故控制字為11011000,即0xd8。108109參考程序如下:

//主機程序

#include<reg51.h>

#include<math.h>

sbitswitch1=P0^0; //定義k1與P0.0連接

sbitswitch2=P0^1; //定義k2與P0.1連接

sbitswitch3=P0^2;

//定義k3與P0.2連接

voidmain()

//主函數{ EA=1; //總中斷允許 TMOD=0x20;

//設置T1定時方式2自動裝載初值 TL1=0xfd; //波特率設為9600 TH1=0xfd; PCON=0x00;

//SMOD=0,不倍增 SCON=0xd0;

//SM2設為0,TB8設為0 TR1=1;

//啟動定時器T1 ES=1; //允許串口中斷

SBUF=0xff;

//串口發送0xff

109110

while(TI==0); //判是否發送完畢

TI=0; //發送完畢,TI清0

while(1)

{

delay_ms(100);

if(switch1==0) //判是否k1按下,k1按下往下執行

{

TB8=1; //第9位數據為1,送TB8,準備發地址幀

SBUF=0x01; //串口發1#從機的地址0x01以及TB8=1

while(TI==0);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論