Fórum témák
» Több friss téma |
Sorosporton binárisan is kommunikálhatunk, bájtokat küldünk.
Kitalálunk 1 formátum szabályt, amit a túloldalon már tudsz értelmezni. Pl: 1. byte: 0xAB start of message, és ha 0xAB előfordul az üzenetben is, akkor duplázni kell (escape). 2. byte: Üzenet típusa (Áram, feszültség, hőmérséklet, miegymás) 3-n byte: Adat. A küldeni kívánt értékek byteonként. Küldő oldalonn szétszeded, fogadó oldalon összerakod. Az üzenet típusából tudod, hogy hány bytera számíts, és azok mit jelentenek. Érdemes még a fejlécbe bele rakni az üzenet hosszát, CRC-t, kér-e a küldő ACK-t, stb. Lehet escape nélkül is, ilyenkor csak a start byte, a hossz és a CRC ellenőrzése után tudod, hogy egész üzenetet kaptál, vagy csak egy részletet.
Ezzel az a gond, hogy mi van, ha az érték is 2byte: 0xAB,0xAB?
És startnak fogja értelmezni? Így csak a String/szám konvertálástól szabadulsz meg. Viszont lesz helyett több egyéb megoldandó feladatod. Én a szöveges kommunikálást ember közelebbinek érzem. A hozzászólás módosítva: Máj 27, 2017
Vannak C függvények a szavak szétbontására:
Bővebben: Link char *strtok(s, ct) Az strtok függvény megkeresi az s karaktersorozatban a ct karaktersorozatból vett karakterekkel határolt tokeneket. És a string/szám konvertálására: B5. Kiegészítő rendszerfüggvények: az <stdlib.h> header-ben …
> Ezzel az a gond, hogy mi van, ha az érték is 2byte: 0xAB,0xAB?
> És startnak fogja értelmezni? Egy darab start byte lehet csak. Ha az adatban kettő pont olyan is van egymás után, akkor mindkettőt megkettőzi, vagyis összesen négyet küld. Fogadó oldalon pedig kiszedi. Ha jól van megírva a feldolgozó, akkor alacsony szinten, automatikusan. Te, az applikációd programozása közben már nem találkozol megkettőzött bájtokkal, csak a szép, tiszta üzenettel. (OSI/ISO modell) Ez azt jelenti, hogy az applikációd alatt bármikor kicserélheted a protokollt, akár binárisról szövegesre, az applikációs réteg ebből semmit sem fog észrevenni. Nem én találtam ki, bevett módszer. Lásd: Escape De ahogy írtam, kihagyhatod, és használhatsz start/stop byte-ot csomaghosszal kombinálva escape nélkül. Rajtad múlik. Viszont szöveges protokoll esetén is szükséged van fejlécre, hogy tudd, hol kezdődik az adat, mik tartoznak össze, sokszor kell küldeni CRC-t, stb. > Így csak a String/szám konvertálástól szabadulsz meg. > Viszont lesz helyett több egyéb megoldandó feladatod. A String/szám konvertálás eléggé számításigényes művelet. Bináris kommunikáció esetén a csomagfeldolgozás sokkal kisebb erőforrásigényű. Olyan műveleteket használ, amik max néhány gépi utasítássá fordulnak le. Desktop környezetben ez a különbség elhanyagolható, mikrokontrolleren viszont nem mindig. Ugyanez igaz a csomagok hosszára is. Szöveges protokoll esetén több bájton lehet ugyanazt az adatmennyiséget átvinni, ami növeli a pufferek memória igényét és az átviteli időt is. > Én a szöveges kommunikálást ember közelebbinek érzem. Ez így is van. Kérdés, hogy miért kellene emberközelinek lennie két gép beszélgetésének... Nem nekem kell látnom az adatokat, hanem a gépeknek.
OK!
Vannak érvek, ellen érvek! Majd a felhasználó dönt, melyik felel meg jobban a céljának. ![]()
Mi történik akkor ha egy időzítő megszakításából meghívok egy USART_TX adatküldés függvényt ami eltart egy ideig, de ezalatt jön egy másik megszakítás pl USART_RX.
Sikerült megcsinálnom az USART adatcsomagok küldését külön külön minden szépen oda vissza megy de egyben RX-TX lefagy a program néhány mp-re mihelyst ráadom a bemenetre az RX-et.
Szerintem a vételnek kel megszakítás, az RX-re .
Ha mégis? Akkor csak 1 Byte-ot veszünk/küldünk és pufferolunk, majd ha kész, Akkor dolgozzuk fel a puffer tartalmát már megszakításon kívül. Mondjuk a Küldést DMA-ra biznám!
Igen. A z RX megszakítással megy. Tuti az kavar be mert a küldés 100ms-ként megy 5-5 csomag a fogadás 10msec-ként jön 5-5 csomag.
Ha kiveszem a teljes TX függvényt akkor megy szépen, ha benne hagyom de lehúzom az RX vezetéket e prociról akkor is megy. Kettő együtt van hogy azonnal de max 4-5mp-en belül lefagy a program. Tehát jópár ciklust megcsinál jól aztán random 1-4mp-re kb lefagy. Igazából semmi mást nem csinálok az RX- megszakításban hogy ha 0x40 nél nagyobb csomag jön akkor azt veszem kezdő karakternek és utána lementem a további 4 csomagot. Ha megvan a 4 csomag akkor abból legyártom az eredeti 16 bites adatot és berakom a megfelelő változóba. Szerintem azért fagy le mert pont egybeesik az RX-TX feladat és valahogy elveszti a fonalat a a proci az RX-en belül. A TX függvény nagyon egyszerű ott nem hinném hogy baj lehet. Ott csak beírom a regiszterbe az adatot és várok míg elküldi. Utána jön a többi 4 csomag és ki is lép. DMA-t néztem én is esetleg TX re nagyon hasznos lenne mindenképp. Csak a TX DMA nál nem értem hogy mit adok meg regiszter címnek hogy honnan olvassa a küldeni kívánt tömböt? 5db short alsó 8-bit-jén tárolom jelenleg a küldeni kívánt adatot. Azt adagolom be jelenleg a TX-nek egymás után.
A hozzászólás módosítva: Máj 28, 2017
Az adást szervezdki DMA-ra. Csak 1* kel jól megcsinálni, és tehermentesíti a procit.
Mivel külön adat busza van. Megszakításban nem szoktunk adatott feldolgozni, csak eltesszük a pufferbe. Végén jelezzük, hogy készen van a vétel. A többi shiftelés részét nem igazán értem! A hozzászólás módosítva: Máj 28, 2017
Ha a forrásnak a short usart_tx_store[5] tömb lesz 16 bites ugye amiben az alsó 8 bit az adat a többi üres, célnak pedig akkor mehet az USART1->TDR. Nem lesz baj hogy az csak 8 bites? A felső 8 bit simán elveszik vagy azt két részben akarja majd adagolni?
A hozzászólás módosítva: Máj 28, 2017
És a vétel is megszervezhető DMA-val, ha a start jel után elküldöd az adatok számát.
Akkor már tudod milyen értékekkel indítsad a DMA-t.
Biztosítsad típus módosítással, hogy csak az alsó 8 bitet írja felül:
Ezeket tettem hozzá memory to peripheral módot kell használjak circular mode nélkül?
Adatlap azt írja: Idézet: „Memory-to-memory mode The DMA channels can also work without being triggered by a request from a peripheral. This mode is called Memory to Memory mode. If the MEM2MEM bit in the DMA_CCRx register is set, then the channel initiates transfers as soon as it is enabled by software by setting the Enable bit (EN) in the DMA_CCRx register. The transfer stops once the DMA_CNDTRx register reaches zero. Memory to Memory mode may not be used at the same time as Circular mode.”
Ez még kell:
DMA1_Channel2->CCR |= DMA_CCR_DIR; // Memory to peripheral direction És be kell állítani az adat szélességet 8 vagy 16 bit lehet különböző is a 2 oldal. És meg kell adni a memória puffer kezdő pointerét. Aztán még meglehet szervezni, hogy a végén kérjen megszakítást. Ahol jelezhetett, hogy végzett a DMA.
Igen a DMA1_Channel2->CCR |= DMA_CCR_DIR; közben észrevettem. Az adatszélességet végül 8->8 bit lesz mert nem fontos hogy short típusban legyen tárolva így ez nem igényel további beállítást.
A memória kezdő pointernek nem jó a DMA1_Channel2->CMAR = (uint8_t)(usart_tx_store); ? Egyébként ezekkel így nem megy azért lehet tényleg a pointer de lehet valami más hiányzik még. A hozzászólás módosítva: Máj 28, 2017
Itt 1 példa:
Bővebben: Link Ha ez tömbb? Átadhatod pointerként:
Valami nem oké nem indul.
A hozzászólás módosítva: Máj 29, 2017
Időzítővel többször indítgatom programon belül a
paranccsal fel töltöttem a tömböt fix adattal de nem akar indulni.
Generáltam az STM cube al is egy alapbeállítást azt még beraktam + ba hátha valami kimaradt de akkor sem. Az az érdekes hogy ugyan ez a beállítás circualr-al működik egy másik programomban ott ADC-t adagol egy regiszterbe.
Na meg lett mi volt igazából nem értem miért kell de a neten volt egy példa és az illető a küldés parancsot ezzel indítja minden alkalommal:
Örülök hogy megy de igazából nem értem a ref manual azt írja elég csak az EN regisztert izgatni hogy induljon de valahogy nekem mégsem sikerült azzal.
Most rájöttél, hogy érdemes használni a: STM32F4xx_HAL_Driver –t!
A kézi regiszter állítgatásokkal mindig kifelejt az ember valami. Amit az előbb ajánlottam lib-et, ott is ott van a végén az: Enable USART TX DMA
A hozzászólás módosítva: Máj 29, 2017
Én USART-nál körkörös DMA puffert használnék. Foglalsz 512 bájt puffert.
A DMA aktuális pozícióját ki lehet olvasni: DMA1_Channel4->CNDTR. Tehát:
Egyszerű körkörös puffer, ha a DMA mutató 2-n áll, a feldolgozott mutató 510-en, akkor
Tehát 4 elemet tudsz feldolgozni. A hozzászólás módosítva: Máj 29, 2017
Szerintem nem törölted előtte az Enable bitet. Általában azt szokták elfelejteni (a DMA felfutó élre indul, ha nem törlöd az Enable-t, nincs felfutó él se).
Én is körkörös DMA-val oldom meg a fogadást. Nem kell amiatt aggódni, hogy adatot vesztesz az indítgatás során. Arra ügyelni kell persze, hogy belátható időn belül feldogozd persze a puffer-t, nehogy felülíródjon. Idézet: „Neharagudjatok a kérdésért, de milyen IDE-t érdemes használni ARM-ra?” Az nem tudom, hogy melyiket érdemes használni, de vannak olyanok, mint pl: Atollic TrueStudio (van ingyenes Lite változata, méretkorlátozás nélkül) Segger Embedded Studio (noncommercial verziója ingyenes, méretkorlátozás nélkül)
Ma szerettem volna folytatni a rx dma kiegészítéssel.
Már legeneráltam a kódot stm cube-ak hogy tuti ne legyen hiba de amint berakom a USART1->CR3 = USART_CR3_DMAR; parancsot a TX rész megszűnik működni. Egyszerűen nem értem, lassan tökön szúrom magam.
A hozzászólás módosítva: Máj 29, 2017
Magyarázzátok már el nekem!
Hogy az ilyen definiciók mért vannak do { között } while(0) ?
![]() A hozzászólás módosítva: Máj 31, 2017
A #define-al olyan makrókat hozol létre, amik a tényleges fordítás előtt kicserélik a makró nevét a makró-ban defininált szövegre. Ha nem csinálod elég általánosra a makrót, akkor ezért érdekes "mágikus" hibaüzeneteket kaphatsz, amiket néha komoly szívás kijavítani.
A do { .. } while(0) egy ügyes trükk, ami bármely olyan helyre beszúrhatóvá teszi a makrót, ahol sok esetben hibát okozhatna, ha mint függvényt próbálnánk használni azt a do while nélkül. pl.: mi történik ha egy if-ben használod a fenti makrót (do while nélkül) és utána raksz egy else-t, ami egyébként rendben is lenne? Hibaüzenet, hogy mit akarsz else-vel if nélkül, te meg pislognál, hogy mégis mi van. |
Bejelentkezés
Hirdetés |