Ik vraag me wat af over de seriele poort van de computer welke ik verbonden heb met de UART van een PIC.

Situatie:
COM1 stuurt bytes naar de UART (via MAX233). Dit gaat goed zolang ik de bytes echt 1 voor 1 weg stuur (gebruik makend van GTERM, dit is zoiets als Hyperterminal).

Als ik in GTERM een string bytes aanmaak en die in 1 keer naar de PIC stuur gaat er wat mis.
Kan dit liggen aan het feit dat ik op de DB9 connector slechts de Rx, Tx en GND aansluitingen heb aangesloten en
de overige pinnen los laat hangen?

Ik ben namelijk schema's tegengekomen waar pin8-pin9 verbonden zijn en pin1-pin4-pin6 verbonden zijn. Dit is gedaan omdat sommige programma's anders in de war raken..
(dit stond er bij)

Nu moet ik er eerlijk bij zeggen dat mijn PIC-code nog niet waterdicht is, dus het kan ook daar nog aan liggen, maar voor ik op de verkeerde plek ga zoeken, wil ik dus weten waarom sommige pinnen op de DB9-connector doorverbonden worden.

GTerm ken ik niet, maar als je 1 byte kunt versturen, kun je er waarschijnlijk ook meer versturen. Of je hebt Gterm in gesteld met XON / XOFF. Dat wil zeggen dat je eerst een XON moet ontvangen. Maar voor de zekerheid kun je 7 aan 8, en 1 aan 6 en 4 maken.
Als je twee seriele poorten op je PC hebt, maak TXD van com1 aan RXD van COM2, start Gterm en Hyperterminal, kun je in ieder geval zien of je de hele string wel stuurt. Weet je dus waar je moet zoeken.
De UART in je PC doet niets met die handshake, behalve doorgeven. Je applicatie bepaalt hoe je reageert.
( de windows driver is ook een applicatie, die kun je instellen op wel of geen handshake ).

[Bericht gewijzigd door Sponcebert op ]

Rx, Tx en GND zijn genoeg. de rest is niet nodig.

Op 10 november 2004 12:46:31 schreef Sponcebert:
GTerm ken ik niet

Je zou het voor de grap eens moeten downloaden (freeware). Het werkt eleganter dan Hyperterminal.

Op 10 november 2004 12:46:31 schreef Sponcebert:
Als je twee seriele poorten op je PC hebt, maak TXD van com1 aan RXD van COM2, start Gterm en Hyperterminal, kun je in ieder geval zien of je de hele string wel stuurt. Weet je dus waar je moet zoeken.

Goed idee.

Op 10 november 2004 12:46:31 schreef Sponcebert:
Je applicatie bepaalt hoe je reageert.
( de windows driver is ook een applicatie, die kun je instellen op wel of geen handshake ).

Twee dingen:
1) wat bedoel je met "je applicatie bepaalt hoe je reageert". Bedoel je nu mijn PIC-code?
Voor zover ik weet kan ik toch niet op verschillende manieren reageren?
2) Hoe kun je die instelling maken in de driver?

Op 10 november 2004 12:56:28 schreef Jeroen Boere:
Rx, Tx en GND zijn genoeg. de rest is niet nodig.

Lijkt mij ook, maar ik vraag me wel af waarom in sommige applicaties die andere pinnen doorverbonden worden.

hoi,

die andere doorverbindingen worden gemaakt om de zgn. handshakelijnen te faken. Sommige programma's hebben dit nodig om uberhaupt iets te doen.

de klassieke doorverbinding is 4-6 (DSR-DTR) en 7-8(RTS-CTS)

Je hebt echt alleen TxD, RxD en Gnd nodig.

kijk maar op http://www.aggsoft.com/rs232-pinout-cable/pinout-and-signal.htm

Da fripster.

Goed, lijkt me duidelijk..het ligt niet aan de pinnen, m'n code zal wel niet waterdicht zijn.

Het lijkt erop dat je ontvangstroutine wel 1 byte kan verwerken, maar niet snel genoeg 'weer klaar staat' voor de volgende byte. Deze worden misschien zo snel acter elkaar verzonden dat je routine het gewoon niet bijbeent.

succes!

Da fripster

Op 10 november 2004 13:52:49 schreef fripster:
Het lijkt erop dat je ontvangstroutine wel 1 byte kan verwerken, maar niet snel genoeg 'weer klaar staat' voor de volgende byte. Deze worden misschien zo snel acter elkaar verzonden dat je routine het gewoon niet bijbeent.
Da fripster

Dat is dus precies waarom ik deze topic gestart ben. Maar toch wel maf..de baudrate is aan beide kanten gedefinieerd (en gelijk), dus het zou moeten kunnen.

Zoals ik al zei, aan de PC kant bepaalt je PC applicatie of handshake lijnen gebruikt worden. Je kunt met "properties" van je com poort dit aan en uit zetten, maar je applicatie kan dat weer overschrijven. Ik zou

a. Op de connector zoals beschreven de draden doorkoppelen.
b. COM1 aan COM2 verbinden en kijken of het echt gezonden wordt.

Dit heeft niets met je baudrate te maken. Ik weet niet of je Rx side op polling of op interrupt basis werkt, maar in beide gevallen is het te langzaam.

Als je op polling basis werkt, zou je het om kunnen schrijven naar interrupt, hetgeen meestal sneller is.
Als het al op interrupt basis is, moet het botweg sneller (efficientere code; interrupt routines schrijf je in assembly, als het echt moet in C en in niets anders :) ).

Als lapmiddel zou je de baudrate omlaag kunnen halen. Elke byte duurt nu langer, met als gevolg dat je code snel genoeg zou kunnen zijn.

Op 10 november 2004 23:06:08 schreef Marco69
:efficientere code; interrupt routines schrijf je in assembly, als het echt moet in C en in niets anders :) ).

Als lapmiddel zou je de baudrate omlaag kunnen halen. Elke byte duurt nu langer, met als gevolg dat je code snel genoeg zou kunnen zijn.

De UART-routines werke op interruptbasis en ze zijn geschreven in assembly. De baudrate is 19k2, relatief langzaam voor een 4MHz processor zou ik zeggen..

Het ontvangen van bytes gaat in code ook behoorlijk snel:
1) ontvang byte
2) schrijf naar RAM
3) ontvang byte
4) schrijf naar RAM
enz enz 32 keer

Ik ga nog verder zoeken naar het probleem..suggesties blijven welkom!

EDIT//
Ik ga de boel morgen testen met behulp van software die een kennis van me geschreven heeft, hier kunnen waarschijnlijk wel zinnige conclusies uit voort komen.

EDIT 2//
Heeft iemand wel eens de mogelijkheid geprobeerd om met handshake lijnen te werken? Of te wel, niet allen Tx, Rx en GND gebruiken?

[Bericht gewijzigd door DIY op ]

Jazeker. Maar handshake lijnen werken naar. In principe kan Windows de RTS bijvoorbeeld automatisch sturen, staat er nog wat in je zendbuffer, is ie actief, is je zendbuffer leeg, wordt hij laag.
Maar A. Dit werkt niet onder WIN98. B. Wat is zendbuffer leeg , is dit in je schuifregister van je UART, of werkelijk verstuurd ? Oftwel, lastig qua interpretatie.

Maar heb je al getest of je het echt stuurt ?
Heb je baudrate, berichtlengte en parity gecontroleerdt ?
Moet je de interupt flag ,nog zelf laag maken ?
Kun je wel zenden ? ( weet je dat je parity etc goed zijn )
(Testlusje, om de seconde je controller 'A' laten sturen.

De UART-routines werke op interruptbasis en ze zijn geschreven in assembly. De baudrate is 19k2, relatief langzaam voor een 4MHz processor zou ik zeggen..

Als je een uC zonder UART gebruikt kon dit wel eens te hoog zijn. Ik ben met een 16F84 (zonder uart) en de zgn bit banging methode in assembly nooit hoger gekomen dan 9600, ook omdat de uC nog andere dingen moest doen dan alleen serieele communicatie.

Op 11 november 2004 12:39:38 schreef Sponcebert:
Jazeker. Maar handshake lijnen werken naar. In principe kan Windows de RTS bijvoorbeeld automatisch sturen, staat er nog wat in je zendbuffer, is ie actief, is je zendbuffer leeg, wordt hij laag.
Maar A. Dit werkt niet onder WIN98. B. Wat is zendbuffer leeg , is dit in je schuifregister van je UART, of werkelijk verstuurd ? Oftwel, lastig qua interpretatie.

Maar heb je al getest of je het echt stuurt ?
Heb je baudrate, berichtlengte en parity gecontroleerdt ?
Moet je de interupt flag ,nog zelf laag maken ?
Kun je wel zenden ? ( weet je dat je parity etc goed zijn )
(Testlusje, om de seconde je controller 'A' laten sturen.

Dank voor de inhoudelijke reactie!

1) de controller ontvangt alleen maar. Ik gebruik de PC om een blok van ongeveer 4kbytes (in subblokken van 32 bytes) up te loaden naar de PIC.
2) Dit maakt handshaking interessant aangezien de PIC de bottleneck van het verhaal is en de PC echt wel even kan wachten (:))
3) Baudrate klopt
4) Berichtlengte wordt goed door gegeven.
5) Parity langs beide kanten uitgeschakeld
6) Ik kan zenden (ook al doe ik dit niet, maar voor de zekerheid ben ik begonnen met een 'bounce'-programmatje; PC stuurt character, PIC bounced dit terug. Dit werkt)
7) De interrupthandling gaat goed (vlag neerhalen gaat vanzelf zodra RCREG wordt gelezen).

Het volgende probleem doet zich dus voor:
Als ik vanuit GTERM (of Hyperterminal) een character verstuur en nog 1 en nog 1 en nog 1 en nog 1 en nog 1 etc etc.. gaat dit helemaal goed.
Als ik een string verstuur (of te wel eerst alle characters intypen en dan 'transfer'-button indruk gebeurt er niks. Het lijkt er overigens op dat er ook niks uit de PC komt. Ik heb een nulmodem kabel nodig om de data vanuit de PC m'n laptop in te spugen en die heb ik niet (dom dom)..
Anyway, het lijkt toch een beetje aan gterm te liggen..

Goed dat je de manco's van WIN98 even bovenhaalt. Het testprogramma (door kennis geschreven) werkt op WIN98, maar ik wil hem overhalen naar WIN2000. Dit zien we morgen.

probeer anders eens een andere terminal:
http://bray.velenje.cx/avr/terminal ben ik een grote fan van...

In hyperterminal heb je ook nog een aantal ingebouwde protocollen, Zmodem , Xmodem, Kermit. Die werken met een software handshake. Veel makkelijker dan een hardware handshake. Net als XOn / Off . Stuur een blok, PIC geeft "OK" terug ( bijvoorbeeld 'A' ) of als het blok niet goed aankomt 'B', dan wordt het volgende blok gestuurd.
Wat doe je met al die data ? Op een gegeven moment moet dat ergens heen. Kost dat geen tijd ?

Op 11 november 2004 14:21:27 schreef Sponcebert:
Wat doe je met al die data ? Op een gegeven moment moet dat ergens heen. Kost dat geen tijd ?

De data wordt in het programma geheugen weggeschreven (ongeveer 5k vrij).
Ik wil 32 bytes per keer ontvangen. Deze worden in RAM weggeschreven. Zodra dit gedaan is wordt het RAM overgeheveld naar het flashROM.
Dan wil ik weer 32 bytes krijgen.
(De 32 bytes worden door 3 ID-bytes vooraf gegaan, welke aangeven wat het is en waar het in ROM moet komen. In totaal dus eigenlijk pakketjes van 35 bytes)

Tussen het wegschrijven naar ROM en het klaarstaan voor de volgende stroom bytes zit een hoop tijd. De routine om naar flash te schrijven is relatief lang. En dat 32 keer.
Dus er is iets van handshaking nodig..

Op 11 november 2004 14:21:27 schreef Sponcebert:
Net als XOn / Off . Stuur een blok, PIC geeft "OK" terug ( bijvoorbeeld 'A' ) of als het blok niet goed aankomt 'B', dan wordt het volgende blok gestuurd.

Okey dan. Dit is wat ik zoek. Kun je mij vertellen hoe dit gaat? Of kan ik dit eenvoudig via google vinden? Ben nu aan het werk, dus ga even niet uitgebreid googlen..

Die protocollen ( X modem, Z Modem ) kun je wel googlen.
Maar zelf bedenken is ook makkelijk :
PC stuurt 32 bytes ( plus eventueel checkbyte )
PIC controleerd blok, schrijft weg, indien klaar -> 'A'.
PC wacht op 'A'. Geen A, download fout, jammer de bammer ( gaat toch meestal goed ). Je PC kan hierop net zo lang wachten als de PIC nodig heeft, een timer is eigenlijk niet eens nodig.
Wel A, volgende blok. Etc.
Eventueel aan het einde speciaal blok, bijvoorbeeld met index 9999 ofzo, PIC telt alle geheugenplaatsen op ( in 1 byte ) en stuurd deze naar de PC. PC check dit getal.
Je checkbyte kan een LRC zijn , moet je alle bytes met XOR functie optellen.

En bedankt! Ook een goeie om zo'n check te doen op het eind. Ik had dit natuurlijk zelf kunnen bedenken...
Uhh..genoeg stof om mee door te gaan, ik post de resultaten morgen. Nogmaals dank.

Ik heb het ook maar "gejat". Kijk maar naar de opbouw van een hex file, kun je zo gebruiken. Specifiek gemaakt om via een serieele lijn naar een programmer gestuurd te worden !
( Idee van mijzelf : bij elk blok ledje toggelen ! )

Inderdaad Sponcebert, die logica zie ik ook. Nogmaals bedankt. Ik zal dus morgen verslagje doen (tenminste als m'n internet het in m'n werkplaats weer doet..).

Enne, goed gejat is nooit verkeerd!

[Bericht gewijzigd door DIY op ]

Ik heb vrijdag-zondag geen internet gehad, dus kon nieuwe conclusies nog niet neerschrijven.
Maar goed..resultaten:
De seriele communicatie werkt een stuk beter dan eerst; Het is mogelijk om een string van 35 bytes vanuit de PC "in 1 keer" up te loaden naar de processor.
19.2kBaud is blijkbaar traag genoeg voor mijn 4MHZ PIC om continue stream naar RAM weg te kunnen schrijven.

De tijd die nodig is om deze bytes verder in de processor te verwerken is te lang om de volgende string van 35 bytes te kunnen binnenhalen.
Dus, ik ga nu proberen wat er gebeurt als ik na de eerste 35 bytes een 'data received'-byte kan terugsturen zodat de PC weet dat de volgende 35 bytes verstuurd mogen worden. Als dit werkt, ben ik er uit.
Sponcebert, nogmaals, dank.

Laatste aanvulling op het probleem: De seriele communicatie is nu rond. Het is gelukt om een blok van 2976 bytes in blokken van 32 naar de PIC up te loaden en weg te schrijven in flash.
Het 'antwoorden' door een byte terug te sturen werkt dus.
Nogmaals bedankt iedereen die in deze thread wat te melden had.

misschien een late toevoeging
het input buffer van de PIC is maar 2 bytes groot, zit het buffer vol en je begint er een derde in te shiften gaat de eerste byte verloren
Je kan dit testen een de hand van een error-flag (waarschijnlijk doe je dat niet :p)

Ik doe de communicatie als volgt:
Byte komt binnen: een interrupt wordt gemaakt
Op deze interrupt schrijf ik de byte vlug weg in een ringbuffer (een korte interrupt-routine dus ) waarvan je de grootte zelf definieert (de grootte van je blokken)

In je main code kan je dan gewoon afvragen hoeveel bytes er in het buffer zitten, eens je blok binnen is bv 32, leeg je je buffer en zeg je tegen de PC dan ie verder mag doen :)

ik haal zonder problemen een baudrate van 115200 met een 20Mhz-Xtal wel te verstaan

EDIT

Op 15 november 2004 17:39:22 schreef Sp3ci3S:
misschien een late toevoeging

inderdaad ;(

Op 15 november 2004 17:39:22 schreef Sp3ci3S:
het input buffer van de PIC is maar 2 bytes groot, zit het buffer vol en je begint er een derde in te shiften gaat de eerste byte verloren
Je kan dit testen een de hand van een error-flag (waarschijnlijk doe je dat niet :p)

Dat doe ik dus wel :)

Op 15 november 2004 17:39:22 schreef Sp3ci3S:
Ik doe de communicatie als volgt:
Byte komt binnen: een interrupt wordt gemaakt
Op deze interrupt schrijf ik de byte vlug weg in een ringbuffer (een korte interrupt-routine dus ) waarvan je de grootte zelf definieert (de grootte van je blokken)

Dat doe ik dus ook ja :)

Op 15 november 2004 17:39:22 schreef Sp3ci3S:
In je main code kan je dan gewoon afvragen hoeveel bytes er in het buffer zitten, eens je blok binnen is bv 32, leeg je je buffer en zeg je tegen de PC dan ie verder mag doen :)

Precies

He Sp3ci3S: Het is al tof dat je reageert hoor! Beter te laat dan nooit :)