Dátum: 15.-16.7.2011

Komunikácia s MCU cez sériovú linku

Už dlho mám doma pár mikrokontrolérov AT89C2051 a zatiaľ jediné čo som s nimi spravil bolo blikanie LED. Po tohtoročnej skúsenosti s Freescale som si povedal, že by som sa na ne mohol lepšie pozrieť a skúsiť niečo lepšie ako len zapínanie a vypínanie vstupov. Vytiahol som teda knižku od Dávida Matouška "Práce s mikrokontroléri ATMEL AT89C2051" a nalistoval kapitolu o komunikácií cez sériovú linku.

Prvý problém na ktorý som narazil, bolo že keď som si zmeral výstupné napätia RS232 na pc, tak som zistil, že z pc lezie 9V a mikrokontrolér je napájaný asi 5V, maximálne však 6V a teda, že priamo ich spojiť nemôžem a teda MAX232 budem musieť použiť. Počkal som teda chvíľu kým sa zjavil na stole a pustil sa do toho.

Vytiahol som nepájivé pole, načrel do zásob a vylovil pár tantalových kondenzátorov. Pozapájal podľa schémy, skontroloval zapojenie a zapol. Samozrejme, že na prvýkrát sa nič nestalo, takže som opätovne musel skontrolovať zapojenie a potom napísať do programu pár riadkov, aby som videl, či MCU niečo robí alebo sa len niekde nezacyklil. Nakoniec po niekoľkých pokusoch a mnoho hodín strávených nad assemblerov skúšaním či z obslužnej rutiny prerušenia naozaj musím vyskakovať pomocou príkazu (skúšal som v rutine vynulovať príznaky prerušenia a vybrať zo zásobníku uložené adresy a pokračovať bez vyskočenia z rutiny no nefungovalo to) som dokopal všetko do šťastného konca.


Konštrukčný plánik (pin 16 = napájanie +5V, pin 15 = zem)

Takto vyzeralo zapojenie vo finálnej podobe:


Naľavo je MAX232, napravo ATMEL 89c2051

Výsledok programovania v assembleri, všetko funguje tak ako má. V pamäti programu je uložený reťazec a hneď za ním je uložená 0, dĺžku reťazca si zistím tak, že skočím na jeho začiatok a posúvam sa po pamäti kým nenarazím na nulu. Potom od aktuálnej adresy odčítam adresu začiatku reťazca a dostanem jeho dĺžku.


prgm:

ch1	equ	243
portA	equ	90h
length:	ds	1	;premmena na ulozenie dlzky retazca

	org 0		;obsluha prerusenia resetu
	ajmp reset
	org 0023h	;obsluha prerusenia serioveho portu
	ajmp serial

reset:
	call debug	;pri starte parkrat bliknem LED aby som overil ci vsetko funguje
	
	mov dptr, #text	;ulozim si poziciu zaciatku textu

	mov r0, #text-1
nacitajDlzkuRetazca:	;nacitam si dlzku retazca, inkremetujem A, kym sa nerovna 0 co je koniec stringu
	inc r0
	mov a, @r0
	jz nacitajDlzkuRetazca
	mov a, r0
	subb a, #text
	mov length, r0

	mov th1, #ch1
	mov tmod, #00100000B	;nastavenie casovacu do rezimu RELOAD
	mov scon, #01010000B	;8-bit prijem riadeny casovacom
	setb EA	;povolenie prerusenia
	setb ES	;nastavenie prerusenia od seriovej linky
	setb tr1	;zapnutie casovaca
	mov pcon, #10000000B	;SMOD=1	
	sjmp $	;skace na aktualne miesto, nerobi nic

serial:		;obsluzna rutina prerusenia
	jb RI, pocetVysielani	;ak prislo prerusenie od prijimaca, tak musim zacat posiealt text
vysielajText:
	mov a, r7
	jz serialKoniec-2	;ak som na konci retazca, tak skocim na instrukciu umoznujucu prijem
	mov a, length	;od dlzky odcitam r7 a dostanem adresu pismena ktore chcem vypisat
	subb a, r7
	movc a, @a+dptr	;vyberiem si potrebne pismeno
	mov sbuf, a	;a tu ho zapisem do registra na odoslanie
	dec r7
	sjmp serialKoniec
pocetVysielani:
	clr REN		;zakazem prijem kym vysielam text
	mov r7, length	;nacitam si dlzku retazca
	sjmp vysielajText	;a pustim sa do vysielania

	setb REN
serialKoniec:
	clr RI	;odstranim priznaky RI a TI
	clr TI
	reti	;vyskocim z rutiny
	
debug:	;blikanie LED na kontrolu ci program vobec bezi
	mov a, #0FFh
	mov r0, #0
	mov r1, #0
	mov r3, #5
blikaj:
	cpl a
	mov portA, a
	mov r2, #10
slucka:
	djnz r0, slucka
	djnz r1, slucka
	djnz r2, slucka
	djnz r3, blikaj
	mov portA, #0FFh
	ret

text: db 'Hello world! by Lubo ',0	;samotny text

koniec:
	end	;koniec programu

Tu možno vidieť výsledok v Hypertermináli. Použil som ho, aby mi odpadla starosť s tým či mám správne napísaný program na čítanie sériovej linky.

Po každom stlačení klávesy dôjde k odoslaniu informácie po sériovej linke do MCU a ten pošle naspäť reťazec z pamäte, teda po každom stlačení nejakej klávesi sa mi na obrazovk vypíše text.

Jediné čo k tomu môžem dodať je: Bol to pôrod!

Späť