2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Muiden CSDN-bloggaajien kirjoittamat blogikirjoitukset ovat melko hyviä Jos haluat tietää 51-mikroohjaimen UART-sarjaportista, voit klikata sisään ja katsoa:
Asynkroninen viestintäSe tarkoittaa, että kahden merkin (8 bittiä) välinen aikaväli viestinnässä ei ole kiinteä, mutta bittien välinen aikaväli yhden merkin sisällä onvakaa。
UART-sarjaliikenne on mikro-ohjainten yleisimmin käytetty viestintätekniikka. Sitä käytetään yleensä mikro-ohjainten ja tietokoneiden väliseen viestintään.
Viestintä voidaan jakaa perustyyppeihinRinnakkainen viestintäjasarjaviestintä, Rinnakkaisviestinnässä jokainen databitti lähetetään samanaikaisesti, ja tiedonsiirto voidaan toteuttaa tavuina. Useat viestintälinjat vievät kuitenkin paljon resursseja ja ovat kalliita. Esimerkiksi aiemmin käytetty P0 = 0xFF määrittää arvot P0:n 8 IO-portille kerralla ja signaalit samanaikaisesti, kuten 8 kaistaa, jotka voivat ohittaa 8 autoa samanaikaisesti. Tämä muoto on rinnakkainen On tapana kutsua P0, P1, P2 ja P3 51-mikrokontrollerin neljää rinnakkaisväylää.
Sarjaliikenne on kuin kaista, vain yksi auto voi ohittaa kerrallaan.Jos siirretään tavu dataa, kuten 0xFF, olettaen, että auto vetää 1-bittistä dataa, se vaatii enemmän kuin 8 autoa.sama aikaväliYlitä vuorotellen sama kaista.
Ero synkronisen ja asynkronisen viestinnän välillä:
1. Synkroninen viestintä edellyttää, että vastaanottopään kellotaajuus on yhdenmukainen lähetyspään kellotaajuuden kanssa ja että lähetyspää lähettää jatkuvan bittivirran asynkroninen viestintä ei vaadi vastaanottopään kellon ja lähetyspään kellon synkronointia Kun lähetyspää lähettää tavun, se voi kulkea minkä tahansa pitkän aikavälin läpi ennen seuraavan tavun lähettämistä.
2. Synkronisella viestinnällä on korkea hyötysuhde, kun taas asynkronisella viestinnällä on alhainen hyötysuhde.
3. Synkroninen viestintä on monimutkaisempaa ja molempien osapuolten kellojen sallittu virhe on pieni, ja molempien osapuolten kellot voivat sallia tietyn virheen.
4. Synkroninen viestintä soveltuu vain pisteestä monipisteeseen, ja asynkronista viestintää voidaan käyttää pisteestä pisteeseen.
STC89C52-mikrokontrollerissa on kaksi nastaa, joita käytetään erityisesti UART-sarjaviestintään, toinen on P3^0 ja toinen on P3^1. Niillä on myös muita nimiä RXD (Receive Data) ja TXD (Transmit Data). niitä kutsutaan sarjaliitymiksi. Kuten kuvassa näkyy:
Tiedonsiirto mikro-ohjaimen ja mikro-ohjaimen välillä:
Kuvassa GND edustaa mikrokontrollerijärjestelmän virtalähteen vertailumaata. TXD:tä kutsutaan sarjalähetysnastaksi ja RXD:tä sarjavastaanottonastaksi.
Kahden mikro-ohjaimen välistä kommunikointia varten ensinnäkin virtalähteen referenssin on oltava sama, joten kahden mikro-ohjaimen GND:t on kytkettävä toisiinsa.Sitten MCU 1:n TXD-nasta liitetään MCU 2:n RXD-nastaan. Toiminto on, että MCU 1 lähettää tietoa MCU 2:lle. (Tämä prosessi on jaettu kahteen osaan. MCU 1'slähetä signaaliProsessi mikrokontrollerilla 2vastaanottaa signaaliaProsessi) Samalla tavalla mikro-ohjaimen 2 TXD-nasta on kytketty mikro-ohjaimen 1 RXD-nastaan.
Tämä kaavakuva heijastaa prosessia, jossa kaksi mikro-ohjainta lähettää ja vastaanottaa tietoja toisilleen.
Kun mikro-ohjain 1 haluaa lähettää tietoja mikro-ohjaimelle 2, esimerkiksi lähettää 1 0xE4 dataa binäärimuodossa:
0b1110 0100, mikro-ohjain 1 kohtaa useita ongelmia ennen lähetyksen alkamista:
Oletetaan, että lähetän ensin 0:n alimman bitin, sitten minun on asetettava mikro-ohjaimen 1 TXD-portti matalalle tasolle.
Mikro-ohjaimet ovat yleensä TTL- tai CMOS-tasoisia TTL/CMOS-tason standardeja varten:
Mikä tahansa yli 2,0 volttia on korkea taso, jokin alle 0,0 voltti on matala taso, ja mikään siltä väliltä ei ole korkea tai matala korkea taso, sitä voidaan pitää myös matalana. Yritä siksi olla käyttämättä piiriä tällä alueella. Tällä vyöhykkeellä oleminen voi saada tuotteesi osumaan tai puuttumaan. Siksi tuotteita kehitettäessä tulee tarkistaa laitteen tietolehti ja jännite piirin toiminnan aikana varmistaakseen, että se on sopivalla jännitteellä.
1. TTL-taso:
Ulostulon ylätaso >2,4V, ulostulon matala taso <0,4V. Huoneenlämmössä yleinen ulostulon ylätaso on 3,5 V ja ulostulon matala taso on 0,2 V. Minimitulon korkea taso ja matala taso: tulo korkea taso >=2,0V, sisääntulo matala taso <=0,8V, kohinamarginaali on 0,4V.
2. CMOS-taso:
1logiikan taso Jännite on lähellä syöttöjännitettä ja logiikkataso 0 on lähellä 0V. Ja sillä on laaja melutaso.
Joten tässä tulee kysymys:
Kun tietoa ei lähetetä tai vastaanoteta, mikro-ohjaimen 1 lähetysportti (TXD) on korkealla tai matalalla tasolla tai portin jännite on näiden välillä. MCU 2:n vastaanottoportin jännite (RXD) seuraa MCU 1:n lähetysportin jännitettä. Kuinka asettaa signaali, että MCU 1 on alkamassa lähettää tietoa, eli mistä MCU 2 tietää, että MCU 1 on lähettänyt sille tietoa? Siksi viestintästandardit on standardoitava.
Vaihe 1: On määrätty, että kun tiedonsiirtoa ei tapahdu, mikro-ohjaimen TXD- ja RXD-porttien jännite pysyy korkeana.
Vaihe 2: Standardoi tiedonsiirtomenetelmä alla olevan kuvan mukaisesti
Voit nähdä, että se määrittelee 1 aloitusbitin, 1 lopetusbitin sekä 1 tavun siirrettävää dataa, joka on yhteensä 8 bittiä.Kymmenennumeroinen data。
Yllä mainittu 0xE4-datan lähetys lähettää itse asiassa 0 1110 0100 1. 1 tavun datan lähetys MCU:lta 1:lle MCU 2 lähettää itse asiassa 10-bittistä dataa.
Aloitusbitillä ja lopetusbitillä mikrokontrollerin 2 RXD-portti alkaa valmistautua vastaanottamaan dataa, kun se havaitsee alhaisen tason. Samalla tavalla, jos mikro-ohjain 1 haluaa lähettää 1 tavun dataa, sen on ensin lähetettävä aloitusbitti 0 (käske mikro-ohjaimelle 2 valmistelemaan se vastaanottamaan) ja sitten lähetettävä lopetusbitti 1 (kerro mikro-ohjaimelle 2 tavua tiedonsiirto valmis).Ja dataa siirrettäessä se onEnsin matala, sitten korkeaTilaus
Vaihe 3: Sinun on asetettava tasaisesti aika, joka tarvitaan 1 bitin datan lähettämiseen. Tämän ajan nopeus ilmaistaan tiedonsiirtonopeudella (baud). Baudinopeus 1 tarkoittaa 1 bitin datan lähettämistä 1 sekunnissa ja 9600 tiedonsiirtonopeus 9 600 databitin lähettämistä yhdessä sekunnissa.
Sitten saamme tuloksen 1 bitin lähettämisestäkesto = 1/baud., silloin 1 täydellisen datakehyksen lähetysaika voidaan todeta olevan10/baudi,Datakehysten välinen aikaväli on mielivaltainen.
Kun MCU 1 ja MCU 2 lähettävät signaaleja, niiden baudinopeudet on asetettava yhdenmukaisiksi oikean tiedonsiirron saavuttamiseksi.
Pöytätietokoneiden alkuvuosina oli yleensä 9-nastainen sarjaliitäntä. Tätä sarjaliitäntää kutsutaan RS-232-liitännäksi, joka liittyy UART-viestintään. joten kommunikaatiossa mikro-ohjainten kanssa käytetään yhä useammin USB-virtuaalisarjaportteja.
RS232:n käyttämä tasologiikka on negatiivinen logiikka, joka eroaa TTL/CMOS-logiikkatasoista.
Siksi tietokoneen 9-nastaista RS232-sarjaporttia ei voi liittää suoraan mikro-ohjaimeen. Seuraavan kuvan täyttämiseen tarvitaan tasonmuunnossiru MAX232:
RS232-nastan kuvaus:
1. Kantoaallon tunnistus DCD (Data Carrier detection) 2. Vastaanota data RXD 3. Lähetä tiedot TXD
4. Datapääte on valmis DTR:lle (Dataterminaali valmiina) 5. Signaalin maadoitus 6. Data valmis DSR(Tietojoukko valmis)
7. Pyyntö lähettää RTS (Pyydä lähettää) 8. Tyhjennä ja lähetä CTS(Tyhjennä lähetettäväksi) 9. Soittokehote RI (Soitto)
Kuten yllä olevasta kuvasta näkyy, RS232:n sarjaportin johdotuksessa tiedonsiirto voidaan suorittaa loppuun, kunhan nastat 2, 3 ja 5 on kytketty vastaaviin MAX232-nastoihin.
Tekniikan kehittyessä RS-232-sarjaporttiviestintää käytetään laajalti teollisuudessa. Kaupallisen tekniikan sovelluksissa USB-UART-tekniikka on kuitenkin hiljalleen korvannut RS232-sarjaportin.
Joten kuinka toteuttaa tiedonsiirto mikro-ohjaimen ja tietokoneen välillä kuvan osoittamalla tavalla
Tämä on tässä tapauksessa kehityskortti, joka käyttää USB-sarjaportti-sirua CH340T tämän toiminnon saavuttamiseksi.
Mikro-ohjaimen portti TXD käyttää hyppysuojusta USB-TX-liitännässä, ja se on kytketty samanaikaisesti CH340-nastaiseen RXD-porttiin
Mikro-ohjaimen portti RXD käyttää hyppysuojusta USB-RX:n yhdistämiseen, ja se on kytketty CH340:n 3. pin TXD:hen.
Näet, että USB-RX:n ja CH340:n kolmannen pin TXD:n välissä on sarjassa 4148 diodi, koska STC89C52-mikro-ohjain tarvitsee kylmäkäynnistyksen ohjelmaa ladattaessa. Napsauta ensin lataa ja käynnistä sitten virta.
niin sanottuKylmäkäynnistys Se viittaa mikro-ohjaimen käynnistysprosessiin virran katkaisemisesta virran kytkemiseen, kun taas kuumakäynnistys tarkoittaa, että mikro-ohjain on aina päällä. Ero kylmäkäynnistyksen ja kuumakäynnistyksen välillä on: kylmäkäynnistyksen aikana mikro-ohjaimen sisäisen RAM-muistin arvot ovat satunnaisia suureita, kun taas kuumakäynnistyksen aikana mikro-ohjaimen sisäisen RAM-muistin arvot eivät muutu ja pysyvät samoina kuin ennen käynnistystä.
Käynnistyshetkellä mikro-ohjain tunnistaa ensin, onko ohjelman lataus tarpeen. Vaikka mikro-ohjaimen VCC:tä ohjataan kytkimellä, koska CH340T:n nasta 3 on lähtönasta, jos sellaista ei ole. diodi, kytkimen myöhempi mikro-ohjain katkeaa, kun virta on katkaistu, CH340T:n nasta 3 on kytketty mikro-ohjaimen P3.0 (RXD) -nastaan Virta virtaa seuraavan vaiheen piiriin tämän nastan kautta ja lataa sen kondensaattorin seuraava vaihe, mikä johtaa tiettyyn jännitteeseen seuraavassa vaiheessa. Tämä jännite Vaikka arvo on vain noin 2~3 V, se voi vaikuttaa normaaliin kylmäkäynnistykseen. Diodin lisäämisen jälkeen se ei toisaalta vaikuta viestintään, toisaalta se voi poistaa tämän haitallisen vaikutuksen.
Opin mikro-ohjaimen käsikirjasta, että P3.0 on lähes kaksisuuntainen IO-portti.
Punainen laatikkoosa on lähes kaksisuuntainen IO-portti , kun sisäinen lähtöbitti on matalalla tasolla, NOT-portin kautta transistorin kanta on korkealla tasolla, transistori on kytketty päälle (CE:n molemmissa päissä oleva jännite on lähes sama kyllästetyssä johtuessa) ja IO mikro-ohjaimen portti tuottaa matalan tason ulkoisesta riippumatta Riippumatta siitä, painetaanpa avainkytkintä tai ponnahdus ylös, IO-portti pysyy matalana. Eli sitä ei ohjata ulkoisilla signaaleilla.
Kun sisäinen lähtö on korkealla, NOT-portin läpi kulkemisen jälkeen transistorin kanta on erittäin alhainen ja transistori ei johda (CE:n molemmissa päissä vastus on erittäin suuri ja resistanssi R on mitätön verrattuna it). Tällä hetkellä IO-portin lähtö on korkea. Kun painiketta painetaan, IO-portti maadoitetaan ja IO-portti tuottaa matalan tason.
Tästä voidaan nähdä, että vasta kunIO-portin lähtö on korkeakun,IO-portin lähtöä ohjaa ulkoinen piiri。
Siksi tiedämme, että P3.0:n sisäinen lähtö on aina korkea, kun sitä käytetään RXD-porttina.P3.1TXD-portti toimii lähettimenä ja senSisäinen lähtötasoVoidaan vaihtaa ylös tai alas tarpeen mukaan.
Ja: TTL-tasoille
Lähtöliitin: korkea taso >=2,4V, matala taso <=0,4V;
Vastaanottopää: korkea taso >=2,0V, matala taso <=0,8V.
COMS-tasolle
Lähtöliitin: korkea taso = Vcc, matala taso = GND (Vcc on virtalähteen jännite);
Vastaanottopää: korkea taso >=0,7Vcc, matala taso <=0,2Vcc.
Niiden vastaanottopään logiikkatason ja lähtöpään loogisen tason välillä on edelleen jonkin verran jänniteeroa Tämä voi johtua signaalin lähetyksen aikana syntyneestä jännitteen pudotushäiriöstä tai suojapiirin olemassaolosta, joten diodin lisääminen ei onnistu. aiheuttaa sen. Lähetetty jännite on hämmentävällä loogisella alueella.
Käytä IO-porttia simuloidaksesi UART-sarjaliikennettä
Ylempi ohjelma:
- # 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; //置接收结束标志
- }
- }
- }
-
- }
Työlogiikka kartta
Tämä ohjelma käyttää ajastinta 0 UART-sarjaviestinnän simulointiin. Huomaa, että tämä on vain aSimulaatio ohjelma. Tämä ohjelma toteuttaa tiedonsiirron tietokoneen ja mikro-ohjaimen välillä. Sen kommunikaatiotulos on siirtää tietokoneen lähettämät tiedot mikro-ohjaimelle ja mikro-ohjain lisää dataan 1:n ja lähettää sen takaisin tietokoneelle. Käytä STC-ISP:n mukana tulevaa sarjaportin virheenkorjausavustajaa tämän tuloksen osoittamiseen.
Varmista ensin, että portit ovat samat Yllä olevat kuvat ovat kaikki COM3, siirtonopeus on 9600, tarkistusbitti on EI, databitti on 8 ja pysäytysbitti on 1. (Tässä on asetettu tietokoneen arvo. sarjaportin parametrit)
Katso tulosta: normaali viestintä on mahdollistaAjastin 0 simuloi sarjaliikennettä_bilibili_bilibili
Selitä lyhyesti tämän ohjelman toimintalogiikka: forLähetä moduuliLähetä esimerkiksi 0xAA =1010 1010 alkaen alimmasta bitistä
Eli TxdBuf = 1010 1010Katso ohjelmaa
- 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; //置发送结束标志
- }
- }
ensimmäinenSyötä keskeytys cnt = 1
PIN_TXD = TxdBuf & 0x01, eli AND:n 1010 1010 0000 0001 tulos on 0xAA:n alin bitin määrittäminen lähettävälle portille vastaavan tason mahdollistamiseksi. Voidaan nähdä, että keskeytyksen TXD-porttiin ensimmäistä kertaa tuleva jännite on matalalla tasolla, ja tämä prosessi jatkuu, kunnes toinen keskeytys tapahtuu.
Sitten TxdBuff siirretään yhden bitin oikealle, eli TxdBuf = 0101 0101
Sittentoinen kertakeskeyttää
cnt = 2
PIN_TXD = 1 Tällä kertaa lähettävän portin taso on korkea
TxdBuf = 0010 1010
Sitten kolmannen ja neljännen kerran asti8 kertaa
cnt = 8
PIN_TXD = 1:llä asetettu taso on korkea taso, joka on lähetetyn datan korkein bitti 1.
Tällä hetkellä TxdBuf = 0x00
Sen jälkeen9. kertaKeskeytyksen syöttäminen 9. keskeytyksen syöttäminen tarkoittaa, että databitit on juuri lähetetty ja on aika valmistautua lähettämään pysäytysbitti.
Siksi PIN_TXD = 1, lähettävä portti on suoraan määritetty korkealle tasolle.
Viimeinen kymmenes keskeytys tarkoittaa, että myös pysäytysbitti on lähetetty.Siksi cnt resetille annetaan arvo 0, TR0:lle arvo 0, ajastin 0 on kytketty pois päältä, TXDEnd = 1, lähetyksen lopetuslippu asetetaan arvoon 1 ja täydellisen datakehyksen lähetys on valmis.
Sen jälkeenvastaanottomoduuli: Lähetimme 0xAA aiemmin Tämän funktion arvo on tulos 1:n lisäämisestä vastaanotettuihin tietoihin, joten vastaanotettu data on: 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; //置接收结束标志
- }
- }
- }
On havaittavissa, että lähetys- ja vastaanottoprosessit ovat itse asiassa samankaltaisia. Tietojen vastaanottamista varten merkitsin ensimmäisen keskeytyksen alkavaksi 0. kerrasta lähinnä yhteistyöhön cnt:n kanssa helpon ymmärtämisen vuoksi.
Kuten kuvasta näkyy, voit nähdä, että keskeytyksen syöttämiseen kuluva aika on puolet esiasetetusta keskeytysajasta. Tämä johtuu siitä, että kun vahvistetaan, onko tasosignaali 0 vai 1, jos taso aikaisintaan näytteenottoaika voi tapahtua Virhe tai häiriö, joten näytteenottopiste asetetaan yleensä signaalin lähetysajan puoliväliin ja siellä oleva tasosignaali katsotaan tällä ajanjaksolla lähetettäväksi signaaliksi. Siksi vastaanottomoduulin tarvitsee vain asettaa keskeytysaika puoleen alkuperäisestä, kun se vastaanottaa aloitusbitin ensimmäistä kertaa, jotta varmistetaan, että kaikki myöhemmät signaalinkeräyspisteet ovat keskipisteessä.
Katsotaanpa, miten ohjelma on asetettu: TL0 = 256 - ((256-TH0) >> 1);
256-TH0 on esiasetettu keskeytysaika. Toivomme, että keskeytysaika on puolet edellisestä. Otetaan esimerkiksi binääriarvo 0000 1000 8:sta. Sen siirtäminen oikealle luvulla 1 on 0000 0100 = 4. Voidaan nähdä, että 1 bitin oikealle siirtämisen operaatio on muuttaa luku puoleen alkuperäisestä arvosta. Samalla tavalla 1 bitin vasemmalle siirtymisen tulos on 0001 0000 =16, mikä tarkoittaa alkuperäisen luvun kertomista kahdella
Käynnistä ohjelmaprosessin analyysi
Kun RxdorTxd on 0, kirjoita else-funktio, eli0:nnen kerran Keskeytykseen syöttäessä vastaanottavan moduulin aloituspiste aika-alueella on aloitusbitin keskipiste. Määritä ensin, onko portin jännite todella alhainen, ja jos ei, sammuta keskeytys. Miksi tehdä tämä?
Koska tämä on vastaanottomoduuli, mikro-ohjain ei ohjaa RXD:n jännitettä. Tässä tapauksessa sitä ohjaa tietokone, joka ohjaa CH340T:n TXD-liittimen jännitettä. Mikro-ohjaimen RXD:n jännite seuraa CH340TXD-päätä.
Jos kyllä, cnt++, niin cnt=1. RxdBuf = 0 tyhjennä vastaanottopuskuri arvoon 0
Sen jälkeen1(oikeastaan toisen kerran)Toisen luokan Syötä keskeytys cnt = 1 ja syötä else if()-funktio siirtääksesi tietoja puskuriin askel askeleelta. Seuraavaa prosessia ei kuvata yksityiskohtaisesti, jos kiinnostuneet lukijat voivat käydä sen läpi itse ohjelman logiikan mukaisesti. Katso, voidaanko tiedot todella tallentaa puskurimuuttujaan ensin matalan bitin ja sitten korkean bitin tavalla. Koska edellisessä blogikirjoituksessa funktio käyttää vasemmalle siirtomenetelmää tallentaakseen ensin datan korkeat bitit. Tämä lähestymistapa täydentää täysin toista työskentelytapaa.
Tässä vaiheessa ohjelma käyttää ajastinta 0 simuloimaan UART-sarjaliikennettä.
Kolme kommunikoinnin perustyyppiä
Yksinkertainen viestintä: Vain toinen osapuoli saa lähettää tietoja toiselle osapuolelle, eikä toinen osapuoli voi lähettää takaisin tietoja, kuten television kaukosäätimiä, radiolähetyksiä jne.
Half-duplex-viestintä: Tietoja voidaan siirtää kahden osapuolen välillä, ja vain toinen osapuoli voi lähettää sen toiselle osapuolelle samanaikaisesti. Esimerkiksi radiopuhelin on tyypillinen puolikaksisuuntainen viestintä. Yllä oleva sarjaportin simulointiohjelma voidaan ymmärtää myös half-duplex-kommunikaatioksi
Full-duplex-kommunikaatio: dataa voidaan lähettää ja vastaanottaa tietoja, ja nämä kaksi suoritetaan samanaikaisesti, kuten puhelinviestintämme.
IO-portin simulaatiosarjaliikenne näyttää periaatteessa sarjaliikenteen olemuksen, mutta mikro-ohjainohjelman on jatkuvasti tunnistettava ja skannattava mikro-ohjaimen IO-portin vastaanottamat tiedot, mikä vie paljon mikro-ohjaimen käyttöajasta. Siksi 51-mikrokontrollerin sisällä on UART-moduuli, joka voi vastaanottaa tietoja automaattisesti, jotta voit käyttää sitä oikein.
SCON-sarjaohjausrekisteri
Tämä tapaus esittelee vain tilan 1, eli asetus SM1 = 1 ja SM0 = 0 on tila 1. Tämä tila on aiemmassa simuloidussa sarjaviestinnässä käytetty datakehysmuoto: 1 aloitusbitti, 8 databittiä ja 1 lopetusbitti.
Analoginen sarjaviestintä käyttää ajastinta 0 tiedonsiirtonopeuden ilmaisemiseen. STC89C52-moduulin tiedonsiirtonopeus voidaan tuottaa vain ajastimella T1 tai ajastimella T0. Tämä on täysin erilaista kuin analoginen tiedonsiirto.
Käytettäessä ajastinta T2 tarvitaan lisäkonfiguraatiorekistereitä Oletusarvoisesti ajastinta T1.
Ohjelmakoodi:
- # 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发送中断标志位
- }
-
- }
Katso video tuloksista:Mukana moduuli sarja communication_bilibili_bilibili
Voidaan nähdä, että normaali viestintä voidaan saavuttaa ilman ongelmia, ja sitten annetaan lyhyt selitys ohjelman asiaankuuluvasta sisällöstä:
Ajastimen T1 uudelleenlatausarvon laskentakaava on:
TH1 = TL1 = 256 - kideoskillaattorin arvo/12/2/16/baudinopeus, sitten sen
Keskeytysvälin aika = kideoskillaattorin arvo/12/2/16/baudinopeus = kideoskillaattorin arvo/12*(1/baudinopeus)*(1/32)
Kideoskillaattorin arvo/12 tarkoittaa koneen jaksojen määrää 1 sekunnissa, (1/baudinopeus) tarkoittaa aikaa, joka tarvitaan 1 bitin datan lähettämiseen
Kristallioskillaattorin arvo/12* (1/baudinopeus) tarkoittaa, kuinka monta koneprosessoria tarvitaan 1 bitin datan lähettämiseen
Samalla tavalla kideoskillaattorin arvo/12*(1/baudinopeus)*(1/32) tämän keskeytyksen aika = 1/32 ajasta, joka kuluu 1 bitin dataa.
Eli 1 bitin dataa siirretään 32 aikaväliin.
Laskettu tulos on 3, eli keskeytysväli = 3 konesykliä. Tämä aika on hyvin lyhyt.
Koska sarjaporttimoduulin signaalin näytteenottomenetelmänä on kerätä yksi signaali 16 kertaa ja ottaa pois 7., 8. ja 9. kerran signaalitasot. Jos kaksi kolmesta ajasta ovat korkeita, datan katsotaan olevan olla 1 .Jos taso on 0 kahdesti, tämän bitin katsotaan olevan 0. Tällä tavalla, jos data luetaan väärin odottamattoman häiriön vuoksi, voidaan lopullisten tietojen oikeellisuus silti taata.
Alla oleva kuva on suositellusta blogikirjoituksesta lähinnä selityksen helpottamiseksi.: baudinopeuden laskentakaava
SMOD:ta ohjaa tehorekisteri PCON Oletusarvoisesti SMOD on 0. Sen korvaaminen yllä olevaan kaavaan on edellinen alkuarvon ratkaisukaava.
TH1 = TL1 = 256 - kideoskillaattorin arvo/12/2/16/siirtonopeus
Kun rekisterin korkein arvo on asetettu arvoon 1 PCON |= 0x80, eli SMOD on asetettu arvoon 1, siirtonopeus voidaan kaksinkertaistaa yllä olevan kaavan mukaisesti.
Tällä hetkellä T1:n alkuarvoksi tulee: TH1 = TL1 = 256 - kideoskillaattorin arvo/12/16/baudinopeus
Yksi asia, joka on syytä huomioida tässä, on se: Jos haluat käyttää PCON-rekisteriä ohjaamaan aaltonopeuden kaksinkertaiseksi, sen alkuarvon kaava on silti kirjoitettava muodossa
TH1 = TL1 = 256 - kideoskillaattorin arvo/12/2/16/siirtonopeus on vain
Nykyinen uudelleenlatausarvo on TH1=256 - (11059200/12/32)/baud =256-(11059200/12/16)/(2*buad) baud*2=4800*2=9600, 9600 on nykyisen ohjelman tiedonsiirtonopeus
Jos alkuperäistä arvoa lataava yritys kirjoittaa TH1 = TL1 = 256 - kideoskillaattorin arvo/12/16/baudinopeus, sen nykyinen siirtonopeus on edelleen 4800, ei 9600.Asetat sarjaliikenneohjelmiston tiedonsiirtonopeudeksi 9600 ja se lähettääTulos on väärä。
Katso video:Tiedonsiirtonopeuden liittyvät_bilibili_bilibili
Näemme, että 9600:n baudinopeuden aikaväli on vain 3 konejaksoa ja 14400:n aikaväli on 2 konesykliä. Voidaan nähdä, että jos sen baudinopeus on suurempi, sen aikaväli voi olla pienempi kuin 1 konejakso. Siksi on olemassa toinen toimintatila, toisin sanoen ConfigUART(9600) sen jälkeen, kun PCON:n korkein bitti on asetettu arvoon 1, sen nykyinen siirtonopeus on 19200, mutta sen aikaväli on alkuperäisen 9600 baudinopeuden aikaväli; 3 konesykliä.
On muistettava, että ajastin 0 simuloidun sarjaviestinnän ja sarjaliikennemoduulin toiminnassa on edelleen monia eroja. Sarjaliikennemoduuli suorittaa yhden tulon ja lähdön, ja se syöttää vain kaksi sarjaliikennekatkosta. Kerran vastauksena siihen, että RI on asetettu arvoon 1, kerran vastauksena TI:n arvoon 1, ja sitten ohjelmisto tyhjentää. Älä enää kiinnitä huomiota lähetysprosessiin, keskity vain siihen, onko lähetys valmis, ja lähetä signaali, kun lähetys on valmis.
Sarjaliikenteen lähetys- ja vastaanottopiirissä on fyysisesti kaksi identtistä SBUF-rekisteriä ja niiden osoitteet ovat myös 0x99, mutta toista käytetään puskurin lähettämiseen ja toista vastaanottopuskuriin. Tämä tarkoittaa, että on kaksi huonetta, ja kahden huoneen talonumerot ovat samat, joista toinen saa mennä sisään, mutta toinen ei saa mennä ulos, mutta ei. Tällä tavalla UART:n full-duplex-kommunikaatio voidaan saavuttaa ilman häiriöitä toistensa välillä. Mutta loogisesti ajatellen, vain SBUF käytetään joka kerta, ja mikro-ohjain automaattisesti valitsee vastaanottaako SBUF vai lähettääkö SBUF sen perusteella, suorittaako se "luku" tai "kirjoitus" toiminnon sille.
Sarjaliikenneohjelman perusvaiheet:
1. Määritä sarjaportti tilaan 1.
2. Aseta ajastin T1 tilaan 2, joka on automaattinen uudelleenasennustila.
3. Laske TH1:n ja TL1:n alkuarvot baudinopeuden perusteella. Tarvittaessa voit kaksinkertaistaa siirtonopeuden PCON:lla.
4. Avaa ajastimen ohjausrekisteri TR1 ja anna ajastimen käydä.Huomautus: Kun käytät sarjaportin keskeytystä, ajastimen 1 keskeytystä ei voi enää ottaa käyttöön, ellet käytä ajastimen 2 sarjaportin keskeytystä.