2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Die von anderen CSDN-Bloggern verfassten Blog-Beiträge sind recht gut. Wenn Sie mehr über den seriellen 51-Mikrocontroller-UART-Port erfahren möchten, können Sie einen Blick darauf werfen:
Asynchrone KommunikationDies bedeutet, dass der Zeitabstand zwischen zwei Zeichen (8 Bits) in der Kommunikation nicht festgelegt ist, wohl aber der Zeitabstand zwischen Bits innerhalb eines Zeichensstabil。
Die serielle UART-Kommunikation ist die am häufigsten verwendete Kommunikationstechnologie für Mikrocontroller. Sie wird normalerweise für die Kommunikation zwischen Mikrocontrollern und Computern sowie zwischen Mikrocontrollern verwendet.
Kommunikation kann in Grundtypen unterteilt werdenParallele KommunikationUndserielle Kommunikation, Bei der parallelen Kommunikation wird jedes Datenbit gleichzeitig übertragen und die Kommunikation kann in Bytes erfolgen. Mehrere Kommunikationsleitungen beanspruchen jedoch viele Ressourcen und sind kostspielig. Beispielsweise wird P0 = 0xFF zuvor verwendet. Weisen Sie den 8 E/A-Ports von P0 gleichzeitig Werte zu und geben Sie gleichzeitig Signale aus, ähnlich wie bei 8 Fahrspuren, die 8 Autos gleichzeitig passieren können. Diese Form ist parallel. Es ist üblich, die vier Sätze paralleler Busse des 51-Mikrocontrollers als P0, P1, P2 und P3 zu bezeichnen.
Serielle Kommunikation ist wie eine Fahrspur, an der jeweils nur ein Auto vorbeifahren kann.Wenn ein Datenbyte wie 0xFF übertragen werden soll und davon ausgegangen wird, dass ein Auto 1-Bit-Daten abruft, sind mehr als 8 Autos erforderlich.gleichen ZeitintervallÜberqueren Sie abwechselnd dieselbe Spur.
Der Unterschied zwischen synchroner Kommunikation und asynchroner Kommunikation:
1. Die synchrone Kommunikation erfordert, dass die Taktfrequenz des empfangenden Endes mit der Taktfrequenz des sendenden Endes übereinstimmt, und das sendende Ende sendet einen kontinuierlichen Bitstrom. Für die asynchrone Kommunikation ist keine Synchronisierung des empfangenden Endes und des sendenden Endes erforderlich Nachdem das sendende Ende ein Byte gesendet hat, kann es ein beliebiges langes Zeitintervall durchlaufen, bevor das nächste Byte gesendet wird.
2. Synchrone Kommunikation weist eine hohe Effizienz auf, während asynchrone Kommunikation eine geringe Effizienz aufweist.
3. Die synchrone Kommunikation ist komplizierter und der zulässige Fehler der Uhren beider Parteien ist gering. Die asynchrone Kommunikation ist einfach und die Uhren beider Parteien können einen bestimmten Fehler zulassen.
4. Synchrone Kommunikation ist nur für Punkt-zu-Mehrpunkt geeignet, und asynchrone Kommunikation kann für Punkt-zu-Punkt verwendet werden.
Der STC89C52-Mikrocontroller verfügt über zwei Pins, die speziell für die serielle UART-Kommunikation verwendet werden, einer ist P3^0 und der andere ist P3^1. Sie haben auch andere Namen, die als RXD (Receive Data) bzw. TXD (Transmit Data) bezeichnet werden Sie werden als serielle Schnittstelle bezeichnet. Wie im Bild gezeigt:
Kommunikation zwischen Mikrocontroller und Mikrocontroller:
In der Abbildung stellt GND die Bezugsmasse der Stromversorgung des Mikrocontrollersystems dar. TXD wird als serieller Sendepin bezeichnet und RXD ist der serielle Empfangspin.
Um zwischen zwei Mikrocontrollern zu kommunizieren, muss zunächst die Stromversorgungsreferenz gleich sein, also müssen die GNDs der beiden Mikrocontroller miteinander verbunden sein.Dann wird der TXD-Pin von MCU 1 mit dem RXD-Pin von MCU 2 verbunden. Die Funktion besteht darin, dass MCU 1 Informationen an MCU 2 sendet. (Dieser Vorgang ist in zwei Teile unterteilt. MCU 1Signal sendenProzess mit Mikrocontroller 2Signal empfangenAblauf) Auf die gleiche Weise wird der TXD-Pin von Mikrocontroller 2 mit dem RXD-Pin von Mikrocontroller 1 verbunden.
Dieses schematische Diagramm spiegelt den Prozess wider, bei dem zwei Mikrocontroller Informationen aneinander senden und empfangen.
Wenn Mikrocontroller 1 Daten an Mikrocontroller 2 senden möchte, sendet er beispielsweise 1 0xE4-Daten, ausgedrückt in Binärform:
0b1110 0100, Mikrocontroller 1 hat vor Beginn der Übertragung mehrere Probleme:
Angenommen, ich übertrage zuerst das niedrigste Bit von 0, dann muss ich den TXD-Port von Mikrocontroller 1 auf einen niedrigen Pegel setzen.
Mikrocontroller sind im Allgemeinen auf TTL- oder CMOS-Ebene. Für TTL/CMOS-Ebene-Standards:
Alles über 2,0 Volt ist ein hoher Pegel, alles unter 0,0 Volt ist ein niedriger Pegel und alles dazwischen ist weder ein hoher noch ein niedriger Pegel. Die Logik dazwischen ist verwirrend und kann vom Gerät beurteilt werden Obwohl es sich um ein hohes Niveau handelt, kann es auch als niedriges Niveau beurteilt werden. Versuchen Sie daher, die Schaltung in diesem Bereich nicht zu betreiben. Wenn Sie sich in dieser Zone befinden, kann Ihr Produkt ein Erfolg oder Misserfolg sein. Daher müssen Sie bei der Entwicklung von Produkten das Datenblatt des Geräts und die Spannung während des Betriebs der Schaltung überprüfen, um sicherzustellen, dass diese eine geeignete Spannung aufweist.
1. TTL-Pegel:
Hoher Ausgangspegel >2,4 V, niedriger Ausgangspegel <0,4 V. Bei Raumtemperatur beträgt der allgemeine hohe Ausgangspegel 3,5 V und der niedrige Ausgangspegel 0,2 V. Minimaler hoher und niedriger Eingangspegel: hoher Eingangspegel >=2,0 V, niedriger Eingangspegel <=0,8 V, Rauschabstand beträgt 0,4 V.
2. CMOS-Ebene:
1Logikebene Die Spannung liegt nahe an der Versorgungsspannung und der Logikpegel 0 liegt nahe bei 0 V. Und verfügt über eine große Geräuschtoleranz.
Hier kommt also die Frage:
Wenn keine Informationen gesendet oder empfangen werden, befindet sich der Übertragungsport (TXD) des Mikrocontrollers 1 auf einem hohen oder niedrigen Pegel oder die Spannung des Ports liegt dazwischen. Die Empfangsportspannung (RXD) von MCU 2 folgt der Spannung des Sendeports von MCU 1. Wie stellt man das Signal ein, dass MCU 1 mit der Übertragung von Informationen beginnen wird, d. h. woher weiß MCU 2, dass MCU 1 Informationen an ihn übertragen hat? Daher besteht die Notwendigkeit, Kommunikationsstandards zu standardisieren.
Schritt 1: Es wird festgelegt, dass die Spannung der TXD- und RXD-Ports des Mikrocontrollers hoch bleibt, wenn keine Kommunikation stattfindet.
Schritt 2: Standardisieren Sie die Datenübertragungsmethode wie unten gezeigt
Sie können sehen, dass es 1 Startbit, 1 Stoppbit und 1 Byte der zu übertragenden Daten definiert, also insgesamt 8 Bits.Zehnstellige Daten。
Die oben erwähnte Übertragung von 0xE4-Daten überträgt tatsächlich 0 1110 0100 1. Die Übertragung von 1 Byte Daten von MCU 1 zu MCU 2 überträgt tatsächlich 10-Bit-Daten. Dieses 10-Bit-Gesamt wird als vollständiger serieller Datenrahmen bezeichnet.
Mit dem Startbit und dem Stoppbit beginnt der RXD-Port des Mikrocontrollers 2, sich auf den Empfang von Daten vorzubereiten, wenn er einen niedrigen Pegel erkennt. Wenn Mikrocontroller 1 1 Byte Daten senden möchte, muss er auf die gleiche Weise zuerst ein Startbit 0 senden (Mikrocontroller 2 anweisen, ihn auf den Empfang vorzubereiten) und dann ein Stoppbit 1 senden (Mikrocontroller 2 a Bytes mitteilen). Datenübertragung abgeschlossen).Und bei der Datenübertragung ist es soErst niedrig, dann hochBefehl
Schritt 3: Sie müssen die Zeit, die zum Übertragen von 1 Bit Daten benötigt wird, einheitlich einstellen. Die Geschwindigkeit dieser Zeit wird durch die Baudrate (Baud) ausgedrückt. Eine Baudrate von 1 bedeutet die Übertragung von 1 Bit Daten in 1 Sekunde, und eine Baudrate von 9600 bedeutet die Übertragung von 9600 Datenbits in 1 Sekunde.
Dann erhalten wir das Ergebnis der Übertragung von 1 BitDauer=1/Baud., dann kann die Zeit zum Übertragen eines vollständigen Datenrahmens ermittelt werden10/Baud,Das Zeitintervall zwischen Datenrahmen ist beliebig.
Wenn MCU 1 und MCU 2 Signale übertragen, müssen ihre Baudraten konsistent eingestellt sein, um eine korrekte Kommunikation zu erreichen.
In den Anfangsjahren der Desktop-Computer gab es üblicherweise eine 9-polige serielle Schnittstelle, die als RS-232-Schnittstelle bezeichnet wird und mit der UART-Kommunikation verwandt ist. Moderne Notebooks verfügen jedoch nicht mehr über diese 9-polige serielle Schnittstelle. Daher werden bei der Kommunikation mit Mikrocontrollern zunehmend virtuelle serielle USB-Anschlüsse verwendet.
Die von RS232 verwendete Pegellogik ist eine negative Logik, die sich von den TTL/CMOS-Logikpegeln unterscheidet.
Daher kann der 9-polige serielle RS232-Anschluss des Computers nicht direkt mit dem Mikrocontroller verbunden werden. Zur Vervollständigung der folgenden Abbildung ist ein Pegelumwandlungschip MAX232 erforderlich:
Beschreibung des RS232-Pins:
1. Trägererkennung DCD (Datenträgererkennung) 2. Empfangsdaten RXD 3. Sendedaten TXD
4. Das Datenterminal ist bereit für DTR (Datenterminal bereit) 5. Signalmasse 6. Daten bereit DSR(Datensatz bereit)
7. Anfrage zum Senden von RTS (Anfrage zum Senden) 8. Löschen und senden Sie CTS(Klar zum Senden) 9. Rufansage RI (Klingeln)
Wie in der Abbildung oben gezeigt, kann bei der Verkabelung der seriellen Schnittstelle von RS232 die Kommunikation abgeschlossen werden, solange die Pins 2, 3 und 5 mit den entsprechenden MAX232-Pins verbunden sind.
Mit der Entwicklung der Technologie wird die serielle RS-232-Schnittstelle in der Industrie häufig verwendet. Bei der Anwendung kommerzieller Technologie hat die USB-zu-UART-Technologie jedoch langsam die serielle RS232-Schnittstelle ersetzt.
So realisieren Sie die Kommunikation zwischen dem Mikrocontroller und dem Computer, wie in der Abbildung gezeigt
In diesem Fall handelt es sich um die Entwicklungsplatine, die den USB-zu-Seriell-Port-Chip CH340T verwendet, um diese Funktion zu erreichen.
Der Mikrocontroller-Port TXD verwendet eine Jumper-Kappe zum Anschluss an den USB-TX und ist gleichzeitig mit dem CH340 Pin 4 RXD-Port verbunden
Der Mikrocontroller-Port RXD verbindet sich über eine Jumper-Kappe mit dem USB-RX und ist mit dem 3. Pin TXD des CH340 verbunden.
Sie können sehen, dass zwischen USB-RX und dem dritten Pin TXD von CH340 eine 4148-Diode in Reihe geschaltet ist, da der STC89C52-Mikrocontroller beim Herunterladen des Programms einen Kaltstart benötigt. Klicken Sie einfach zuerst auf „Herunterladen“ und dann auf „Einschalten“.
sogenanntKaltstart Es bezieht sich auf den Startvorgang des Mikrocontrollers vom Ausschalten bis zum Einschalten; während Heißstart bedeutet, dass der Mikrocontroller immer eingeschaltet ist. Der Unterschied zwischen Kaltstart und Heißstart besteht darin, dass beim Kaltstart die Werte im internen RAM des Mikrocontrollers Zufallsgrößen sind, während beim Heißstart die Werte im internen RAM des Mikrocontrollers nicht verändert werden und bleiben die gleichen wie vor dem Start.
Beim Einschalten erkennt der Mikrocontroller zunächst, ob das Programm heruntergeladen werden muss. Der VCC des Mikrocontrollers wird jedoch vom Schalter gesteuert, da Pin 3 des CH340T ein Ausgangspin ist, sofern kein solcher vorhanden ist Wenn die Diode ausgeschaltet ist, fällt der nachfolgende Mikrocontroller aus. Pin 3 von CH340T ist mit dem P3.0-Pin (RXD) des Mikrocontrollers verbunden. Über diesen Pin fließt Strom in den Schaltkreis der nachfolgenden Stufe und lädt den Kondensator auf Die nachfolgende Stufe führt zu einer bestimmten Spannung in der nachfolgenden Stufe. Diese Spannung beträgt zwar nur etwa 2 bis 3 V, kann jedoch den normalen Kaltstart beeinträchtigen. Durch das Hinzufügen einer Diode wird einerseits die Kommunikation nicht beeinträchtigt, andererseits kann dieser nachteilige Effekt beseitigt werden.
Aus dem Mikrocontroller-Handbuch habe ich erfahren, dass P3.0 ein quasi-bidirektionaler IO-Port ist.
Der Red-Box-Teil ist der quasi-bidirektionale IO-Port Wenn das interne Ausgangsbit einen niedrigen Pegel hat, befindet sich die Basis des Transistors über das NICHT-Gatter auf einem hohen Pegel, der Transistor ist eingeschaltet (die Spannung an beiden Enden von CE ist bei gesättigter Leitung nahezu gleich) und der IO Der Port des Mikrocontrollers gibt Low-Pegel aus, unabhängig davon, ob der Schlüsselschalter gedrückt oder hochgeklappt ist, der IO-Port bleibt Low. Das heißt, es wird nicht durch externe Signale gesteuert.
Wenn der interne Ausgang einen hohen Pegel hat, ist die Basis des Transistors nach dem Durchlaufen des NICHT-Gatters extrem niedrig und der Transistor ist nicht leitend (der Widerstand an beiden Enden von CE ist sehr groß und der Widerstand R ist im Vergleich dazu vernachlässigbar (it). Zu diesem Zeitpunkt ist der Ausgang des IO-Ports hoch. Wenn die Taste gedrückt wird, wird der IO-Port geerdet und der IO-Port gibt einen niedrigen Pegel aus.
Daraus lässt sich erkennen, dass nur wannDer IO-Port-Ausgang ist High-PegelWann,Der Ausgang des IO-Ports wird durch den externen Schaltkreis gesteuert。
Daher wissen wir, dass der interne Ausgang von P3.0 immer hoch ist, wenn er als RXD-Port verwendet wird.Der P3.1TXD-Port dient als Sender und dessenInterner AusgangspegelKann je nach Bedarf nach oben oder unten geändert werden.
Und: für TTL-Pegel
Ausgangsanschluss: hoher Pegel >=2,4 V, niedriger Pegel <=0,4 V;
Empfangsende: hoher Pegel >=2,0 V, niedriger Pegel <=0,8 V.
Für COMS-Ebene
Ausgangsklemme: hoher Pegel = Vcc, niedriger Pegel = GND (Vcc ist die Versorgungsspannung);
Empfangsende: hoher Pegel >=0,7 Vcc, niedriger Pegel <=0,2 Vcc.
Es besteht immer noch ein gewisser Spannungsunterschied zwischen dem Logikpegel des Empfangsendes und dem Logikpegel des Ausgangsendes. Dies kann auf die während der Signalübertragung erzeugten Spannungsabfallstörungen oder das Vorhandensein einer Schutzschaltung zurückzuführen sein, sodass das Hinzufügen einer Diode nicht möglich ist Ursache dafür ist die übertragene Spannung in einem verwirrenden logischen Bereich.
Verwenden Sie den E/A-Port, um die serielle UART-Kommunikation zu simulieren
Oberprogramm:
- # include<reg52.h>
-
- sbit PIN_RXD = P3^0; //接受引脚定义
- sbit PIN_TXD = P3^1; //发送引脚定义
-
- bit RxdorTxd = 0; //指示当前状态为接受还是发送
- bit RxdEnd = 0; //接受结束标志
- bit TxdEnd = 0; //发送结束标志
- unsigned char RxdBuf = 0; //接收缓冲区
- unsigned char TxdBuf = 0; //发送缓冲器
-
- void ConfigUART(unsigned int baud);
- void StartTXD(unsigned char dat);
- void StartRXD();
-
-
- void main()
- {
- EA = 1; //打开总中断
- ConfigUART(9600); //配置波特率为9600
-
- while(1)
- {
- while(PIN_RXD); //等待接收引脚出现低电平,即起始位
- StartRXD(); //启动接收
- while(!RxdEnd); //等待接受完成
- StartTXD(RxdBuf +1);//接受到的整数+1后,发送回去
- while(!TxdEnd); //等待发送结束
- }
- }
-
- /* 串口配置函数,baud-通信波特率 */
- void ConfigUART(unsigned int baud)
- {
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x02; //配置T0为模式2
- TH0 = 256 - (11059200/12)/baud; //计数T0的重载值
- }
-
- /* 启动串行接受 */
- void StartRXD()
- {
- TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- RxdEnd = 0; //清零接受结束标志
- RxdorTxd = 0; //设置当前状态为接受 1位发送
-
- }
-
- /* 启动串行发送,dat-待发送字节数据 */
- void StartTXD(unsigned char dat)
- {
- TxdBuf = dat; //待发送数据保存到发送缓冲器
- TL0 = TH0; //T0计算初值为重载值
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- PIN_TXD = 0; //发送起始位
- TxdEnd = 0; //清零发送结束标志
- RxdorTxd = 1; //设置当前状态为发送
- }
-
- /*T0中断服务函数,处理串行发送和接收 */
- void interruptTimer0() interrupt 1
- {
- static unsigned char cnt = 0;
-
- if(RxdorTxd)
- {
- cnt++;
- if(cnt <= 8) //低位在先一次发送8bit数据位
- {
- PIN_TXD = TxdBuf & 0x01;
- TxdBuf >>= 1;
- }
- else if(cnt == 9) //发送停止位
- {
- PIN_TXD = 1;
- }
- else //发送结束
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- TxdEnd = 1; //置发送结束标志
- }
- }
-
- else //串行接收处理
- {
- if(cnt == 0) // 处理起始位
- {
- if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
- {
- RxdBuf = 0;
- cnt++;
- }
- else //起始位为1(不为0)时,中止接收
- {
- TR0 = 0; //关闭T0
- }
- }
- else if(cnt <= 8) //处理8位数据位
- {
- RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
- if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
- { //而为0时不处理即仍保持位移后的0
- RxdBuf |= 0x80;
- }
- cnt++;
- }
- else //停止位处理
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- if(PIN_RXD) //停止位为1时,方认为数据有效
- {
- RxdEnd = 1; //置接收结束标志
- }
- }
- }
-
- }
Arbeitslogikkarte
Dieses Programm verwendet Timer 0, um die serielle UART-Kommunikation zu simulierenSimulationsprogramm. Dieses Programm implementiert die Kommunikation zwischen dem Computer und dem Mikrocontroller. Das Kommunikationsergebnis besteht darin, die vom Computer übertragenen Daten an den Mikrocontroller zu übertragen. Der Mikrocontroller addiert 1 zu den Daten und sendet sie an den Computer zurück. Verwenden Sie den Debugging-Assistenten für serielle Ports, der mit STC-ISP geliefert wird, um dieses Ergebnis zu demonstrieren.
Stellen Sie zunächst sicher, dass die Ports gleich sind. Die obigen Bilder sind alle COM3, die Baudrate ist 9600, das Prüfbit ist NEIN, das Datenbit ist 8 und das Stoppbit ist 1. (Was hier eingestellt ist, ist das des Computers Parameter der seriellen Schnittstelle)
Schauen Sie sich das Ergebnis an: Eine normale Kommunikation ist möglichTimer 0 simuliert die serielle Kommunikation_bilibili_bilibili
Erläutern Sie kurz die Arbeitslogik dieses Programms: zModul sendenSenden Sie beispielsweise 0xAA =1010 1010 beginnend mit dem niedrigsten Bit
Das ist TxdBuf = 1010 1010Schauen Sie sich das Programm an
- if(RxdorTxd)
- {
- cnt++;
- if(cnt <= 8) //低位在先一次发送8bit数据位
- {
- PIN_TXD = TxdBuf & 0x01;
- TxdBuf >>= 1;
- }
- else if(cnt == 9) //发送停止位
- {
- PIN_TXD = 1;
- }
- else //发送结束
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- TxdEnd = 1; //置发送结束标志
- }
- }
ErsteGeben Sie Interrupt cnt = 1 ein
PIN_TXD = TxdBuf & 0x01, das heißt, das Ergebnis der UND-Verknüpfung von 1010 1010 0000 0001 besteht darin, dem sendenden Port das niedrigste Bit von 0xAA zuzuweisen, um die entsprechende Ebene zu aktivieren. Es ist ersichtlich, dass die Spannung, die zum ersten Mal in den Interrupt-TXD-Port eintritt, einen niedrigen Pegel hat und dieser Vorgang fortgesetzt wird, bis der zweite Interrupt auftritt.
Dann wird TxdBuff um ein Bit nach rechts verschoben, also TxdBuf = 0101 0101
Danndas zweite Malunterbrechen
Anzahl = 2
PIN_TXD = 1 Diesmal ist der Pegel des sendenden Ports hoch
TxdBuf = 0010 1010
Dann das dritte und vierte Mal bis8. Mal
Anzahl = 8
Der durch PIN_TXD = 1 festgelegte Pegel ist der hohe Pegel, d. h. das höchste Bit 1 der übertragenen Daten.
Zu diesem Zeitpunkt ist TxdBuf = 0x00
Danach9. MalDer Eintritt in den Interrupt bedeutet, dass die Datenbits gerade gesendet wurden und es Zeit ist, das Senden des Stoppbits vorzubereiten.
Daher ist PIN_TXD = 1, der sendende Port wird direkt der hohen Ebene zugewiesen.
Der letzte zehnte Interrupt stellt dar, dass auch das Stoppbit gesendet wurde.Daher wird cnt reset der Wert 0 zugewiesen, TR0 wird der Wert 0 zugewiesen, Timer 0 wird ausgeschaltet, TXDEnd = 1, das Übertragungsende-Flag wird auf 1 gesetzt und die Übertragung eines vollständigen Datenrahmens ist abgeschlossen.
DanachEmpfangsmodul: Wir haben zuvor 0xAA gesendet. Der Wert dieser Funktion ist das Ergebnis der Addition von 1 zu den empfangenen Daten. Die empfangenen Daten sind also: 0xA9 = 1010 1001
- void StartRXD()
- {
- TL0 = 256 - ((256-TH0) >> 1);//接受启动时T0定时为半个波特率周期
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- RxdEnd = 0; //清零接受结束标志
- RxdorTxd = 0; //设置当前状态为0接收 1为发送
-
- }
- else //串行接收处理
- {
- if(cnt == 0) // 处理起始位
- {
- if(!PIN_RXD) //起始位为0时,清零接收缓冲器,准备接受数据位
- {
- RxdBuf = 0;
- cnt++;
- }
- else //起始位为1(不为0)时,中止接收
- {
- TR0 = 0; //关闭T0
- }
- }
- else if(cnt <= 8) //处理8位数据位
- {
- RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
- if(PIN_RXD) //接收脚为1时,缓冲器最高位置1
- { //而为0时不处理即仍保持位移后的0
- RxdBuf |= 0x80;
- }
- cnt++;
- }
- else //停止位处理
- {
- cnt = 0; //复位bit计数器
- TR0 = 0; //关闭T0
- if(PIN_RXD) //停止位为1时,方认为数据有效
- {
- RxdEnd = 1; //置接收结束标志
- }
- }
- }
Es ist ersichtlich, dass die Sende- und Empfangsprozesse tatsächlich ähnlich sind. Beim Empfang von Daten habe ich den ersten Interrupt als ab dem 0. Mal markiert, hauptsächlich um mit cnt zusammenzuarbeiten, um das Verständnis zu erleichtern.
Wie in der Abbildung gezeigt, beträgt die Zeit, die benötigt wird, um zum 0. Mal in den Interrupt einzutreten, die Hälfte der voreingestellten Interrupt-Zeit. Dies liegt daran, dass bei der Bestätigung, ob ein Pegelsignal 0 oder 1 ist, der Pegel frühestens beträgt Zum Zeitpunkt der Abtastung kann es zu Fehlern oder Störungen kommen. Daher wird der Abtastpunkt im Allgemeinen auf die Mitte der Signalübertragungszeit eingestellt und das Pegelsignal dort wird als das in diesem Zeitraum übertragene Signal angesehen. Daher muss das Empfangsmodul beim ersten Empfang des Startbits seine Interruptzeit nur auf die Hälfte des Originals einstellen, um sicherzustellen, dass sich alle nachfolgenden Signalsammelpunkte im Mittelpunkt befinden.
Sehen wir uns an, wie das Programm eingestellt ist: TL0 = 256 - ((256-TH0) >> 1); // Akzeptieren Sie, dass das T0-Timing beim Start die halbe Baudratenperiode ist
256-TH0 ist die voreingestellte Interrupt-Zeit. Wir hoffen, dass die Interrupt-Zeit die Hälfte der vorherigen beträgt. Die Programmoperation besteht darin, sie um 1 Bit nach rechts zu verschieben von 8. Eine Verschiebung um 1 nach rechts ergibt 0000 0100 = 4. Es ist ersichtlich, dass die Operation der Verschiebung um 1 Bit nach rechts darin besteht, die Zahl auf die Hälfte des ursprünglichen Werts zu ändern. Auf die gleiche Weise ist das Ergebnis einer Verschiebung um 1 Bit nach links 0001 0000 =16, was bedeutet, dass die ursprüngliche Zahl mit 2 multipliziert wird
Programmprozessanalyse starten
Wenn RxdorTxd 0 ist, geben Sie die else-Funktion ein0. Mal Beim Eintritt in den Interrupt ist der Startpunkt des empfangenden Moduls im Zeitbereich der Mittelpunkt des Startbits. Stellen Sie zunächst fest, ob die Portspannung wirklich niedrig ist. Wenn nicht, schalten Sie den Interrupt aus. Warum das tun?
Da es sich um ein Empfangsmodul handelt, wird die Spannung von RXD nicht vom Mikrocontroller gesteuert. In diesem Fall wird sie vom Computer gesteuert, der die Spannung des TXD-Anschlusses von CH340T steuert. Die Spannung des RXD des Mikrocontrollers folgt dem CH340TXD-Ende. Auf der Empfangsseite können die empfangenen Informationen gestört sein und müssen erneut bestätigt werden.
Wenn ja, cnt++, dann cnt=1. RxdBuf = 0; Empfangspuffer auf 0 löschen
Danach1(eigentlich das zweite Mal)Zweitklassig Geben Sie den Interrupt cnt = 1 ein und geben Sie die Funktion else if() ein, um Daten Schritt für Schritt in den Puffer zu übertragen. Der weitere Ablauf wird bei Interesse nicht näher beschrieben und kann entsprechend der Programmlogik selbst durchlaufen werden. Prüfen Sie, ob die Daten wirklich zuerst im Low-Bit-Modus und dann im High-Bit-Modus in der Puffervariablen gespeichert werden können. Denn im vorherigen Blogbeitrag verwendet die Funktion die Linksverschiebungsmethode, um zunächst die hohen Bits der Daten zu speichern. Dieser Ansatz ergänzt durchaus eine andere Arbeitsweise.
Zu diesem Zeitpunkt verwendet das Programm Timer 0, um die serielle UART-Kommunikation zu simulieren.
Drei grundlegende Arten der Kommunikation
Simplex-Kommunikation: Nur eine Partei darf Informationen an die andere Partei übertragen, und die andere Partei kann keine Informationen zurücksenden, z. B. TV-Fernbedienungen, Radiosendungen usw.
Halbduplex-Kommunikation: Daten können zwischen zwei Parteien übertragen werden und nur eine Partei kann sie gleichzeitig an die andere Partei senden. Ein Walkie-Talkie ist beispielsweise eine typische Halbduplex-Kommunikation. Das obige Simulationsprogramm für die serielle Schnittstelle kann auch als Halbduplex-Kommunikation verstanden werden
Vollduplex-Kommunikation: Daten können gesendet und gleichzeitig Daten empfangen werden, und beides erfolgt gleichzeitig, wie zum Beispiel unsere Telefonkommunikation.
Die Simulation der seriellen Kommunikation mit E/A-Ports zeigt im Grunde die Essenz der seriellen Kommunikation, aber das Mikrocontroller-Programm muss die vom E/A-Port des Mikrocontrollers empfangenen Daten ständig erkennen und scannen, was einen großen Teil der Laufzeit des Mikrocontrollers in Anspruch nimmt. Daher befindet sich im 51-Mikrocontroller ein UART-Modul, das Daten automatisch empfangen kann. Um es korrekt zu verwenden, müssen Sie das Sonderfunktionsregister richtig konfigurieren.
SCON serielles Steuerregister
In diesem Fall wird nur Modus 1 eingeführt, d. h. die Einstellung SM1 = 1 und SM0 = 0 ist Modus 1. Dieser Modus ist das Datenrahmenformat, das in der vorherigen simulierten seriellen Kommunikation verwendet wurde: 1 Startbit, 8 Datenbits und 1 Stoppbit.
Die analoge serielle Kommunikation verwendet Timer 0, um die Baudrate auszudrücken. Der Baudratensender des STC89C52 kann nur durch Timer T1 oder Timer T2 generiert werden. Dies unterscheidet sich völlig vom analogen Kommunikationskonzept.
Bei Verwendung von Timer T2 sind zusätzliche Konfigurationsregister erforderlich. Standardmäßig wird Timer T1 verwendet.
Programmcode:
- # include<reg52.h>
-
- void ConfigUART(unsigned int baud);
-
- void main()
- {
- EA = 1;
- ConfigUART(9600); //配置波特率为9600
- while(1);
-
- }
- /* 串口配置函数,baud-通信波特率 */
- void ConfigUART(unsigned int baud)
- {
- SCON = 0x50; //0x50= 0101 0000 配置串口为模式1
- TMOD &= 0x0F; //清零T1的控制位
- TMOD |= 0x20; //0x20 = 0010 0000 配置T1的为模式2自动重载模式
- TH1 = 256 - (11059200/12/32)/baud; //计算T1的重载值
- TL1 = TH1; //设置初值
- ET1 = 0; //禁止T1中断
- ES = 1; //启动串口中断
- TR1 = 1; //启动T1定时器
- }
-
- /*UART中断服务函数 */
- void interruptUART() interrupt 4
- {
- if(RI) //接收到字节
- {
- RI = 0; //软件清0接收中断标志
- SBUF = SBUF+1;//接收的数据+1,左边是发送SBUF,右边是接收SBUF
-
- }
- if(TI)
- {
- TI = 0; //软件清0发送中断标志位
- }
-
- }
Schauen Sie sich das Video der Ergebnisse an:Kommt mit dem Modul serial communication_bilibili_bilibili
Es ist ersichtlich, dass eine normale Kommunikation problemlos möglich ist. Anschließend wird der relevante Inhalt des Programms kurz erläutert:
Die Berechnungsformel für den Nachladewert des Timers T1 lautet:
TH1 = TL1 = 256 – Quarzoszillatorwert/12/2/16/Baudrate, dann ist es so
Interrupt-Intervallzeit = Quarzoszillatorwert/12/2/16/Baudrate = Quarzoszillatorwert/12*(1/Baudrate)*(1/32)
Der Quarzoszillatorwert/12 bedeutet die Anzahl der Maschinenzyklen in 1 Sekunde, (1/Baudrate) bedeutet die Zeit, die zum Übertragen von 1 Datenbit erforderlich ist
Der Quarzoszillatorwert/12* (1/Baudrate) gibt an, wie viele Maschinenprozessoren erforderlich sind, um 1 Datenbit zu übertragen
Auf die gleiche Weise beträgt der Quarzoszillatorwert/12*(1/Baudrate)*(1/32) die Zeit dieses Interrupts = 1/32 der Zeit zum Übertragen von 1 Datenbit
Das heißt, die Übertragung von 1 Datenbit wird in 32 Zeitintervalle unterteilt.
Das berechnete Ergebnis ist 3, d. h. das Interrupt-Intervall = 3 Maschinenzyklen. Diese Zeit ist sehr kurz.
Da die Signalabtastmethode des Moduls für die serielle Schnittstelle darin besteht, ein einzelnes Signal 16 Mal zu erfassen und die Signalpegel des 7., 8. und 9. Mals zu entnehmen, werden die Daten als hoch angesehen sei 1. Wenn der Pegel zweimal 0 ist, wird dieses Bit als 0 betrachtet. Auf diese Weise kann die Richtigkeit der endgültigen Daten dennoch gewährleistet werden, wenn die Daten aufgrund unerwarteter Störungen falsch gelesen werden.
Das Bild unten stammt aus dem empfohlenen Blog-Beitrag und dient hauptsächlich der einfacheren Erklärung.: Berechnungsformel der Baudrate
SMOD wird durch das Leistungsregister PCON gesteuert. Standardmäßig ist SMOD 0. Das Einsetzen in die obige Formel ist die vorherige Lösungsformel für den Anfangswert.
TH1 = TL1 = 256 – Quarzoszillatorwert/12/2/16/Baudrate
Wenn der höchste Wert des Registers auf 1 PCON |= 0x80; d. h. SMOD auf 1 gesetzt ist, kann die Baudrate verdoppelt werden, wie in der Formel oben gezeigt.
Zu diesem Zeitpunkt beträgt der Anfangswert von T1: TH1 = TL1 = 256 – Quarzoszillatorwert/12/16/Baudrate
Eine Sache, die hier beachtet werden muss, ist Folgendes: Wenn Sie das PCON-Register verwenden möchten, um die Wellenrate auf das Doppelte zu steuern, muss die Anfangswertformel noch wie folgt geschrieben werden
TH1 = TL1 = 256 – Quarzoszillatorwert/12/2/16/Baudrate ist gerade
Der aktuelle Reload-Wert ist TH1=256 - (11059200/12/32)/Baud =256-(11059200/12/16)/(2*Buad) Baud*2=4800*2=9600, 9600 ist der Wert von aktuelle Programmbaudrate
Wenn Ihr Unternehmen, das den Anfangswert neu lädt, schreibt: TH1 = TL1 = 256 – Quarzoszillatorwert/12/16/Baudrate, dann beträgt die aktuelle Baudrate immer noch 4800 und nicht 9600.Sie verwenden die Software für die serielle Kommunikation, um die Kommunikations-Baudrate auf 9600 einzustellen und die Übertragung erfolgtDas Ergebnis ist falsch。
Schau das Video:Baudrate related_bilibili_bilibili
Wir können sehen, dass das Zeitintervall für die Baudrate von 9600 nur 3 Maschinenzyklen beträgt und das Zeitintervall von 14400 2 Maschinenzyklen beträgt. Es ist ersichtlich, dass bei einer höheren Baudrate das Zeitintervall möglicherweise weniger als 1 Maschinenzyklus beträgt. Daher gibt es einen anderen Arbeitsmodus, nämlich ConfigUART (9600), nachdem das höchste Bit von PCON auf 1 gesetzt wurde. Die aktuelle Baudrate beträgt jedoch 19200, das Zeitintervall entspricht jedoch dem Zeitintervall der ursprünglichen Baudrate von 9600 3 Maschinenzyklen.
Es muss daran erinnert werden, dass es immer noch viele Unterschiede in der Arbeit der simulierten seriellen Kommunikation von Timer 0 und des seriellen Kommunikationsmoduls gibt. Das serielle Kommunikationsmodul führt eine Ein- und Ausgabe durch und weist nur zwei Unterbrechungen der seriellen Kommunikation auf. Einmal als Reaktion darauf, dass RI auf 1 gesetzt wurde, einmal als Reaktion darauf, dass TI auf 1 gesetzt wurde, und dann durch die Software gelöscht. Achten Sie nicht mehr auf den Übertragungsprozess, sondern konzentrieren Sie sich nur darauf, ob die Übertragung abgeschlossen ist, und senden Sie ein Signal, wenn die Übertragung abgeschlossen ist.
Die Sende- und Empfangsschaltung der seriellen Kommunikation verfügt physisch über zwei identische SBUF-Register, und ihre Adressen sind ebenfalls 0x99, aber eines wird als Sendepuffer und das andere als Empfangspuffer verwendet. Das bedeutet, dass es zwei Räume gibt und die Hausnummern der beiden Räume gleich sind. Einer von ihnen darf hineingehen, der andere darf jedoch nicht hineingehen. Auf diese Weise kann eine Vollduplex-Kommunikation von UART ohne gegenseitige Beeinträchtigung erreicht werden. Aber logischerweise wird jedes Mal nur SBUF bedient, und der Mikrocontroller entscheidet automatisch, ob er SBUF empfängt oder SBUF sendet, je nachdem, ob er einen „Lese“- oder „Schreib“-Vorgang darauf ausführt.
Grundlegende Schritte des seriellen Kommunikationsprogramms:
1. Konfigurieren Sie den seriellen Port auf Modus 1.
2. Konfigurieren Sie Timer T1 auf Modus 2, den automatischen Neuinstallationsmodus.
3. Berechnen Sie die Anfangswerte von TH1 und TL1 anhand der Baudrate. Bei Bedarf können Sie die Baudrate mit PCON verdoppeln.
4. Öffnen Sie das Timer-Steuerregister TR1 und lassen Sie den Timer laufen.Hinweis: Wenn Sie den Interrupt für die serielle Schnittstelle verwenden, kann der Interrupt für Timer 1 nicht mehr aktiviert werden, es sei denn, Sie verwenden den Interrupt für die serielle Schnittstelle für Timer 2.