Software
Start ] Uni-Tx ] links ]

 

Het bediendeel gebruikt een Microchip PIC16F84 controller om de zender te sturen. De code is geschreven in assembler taal en maakt veelvuldig gebruik van routines zoals die door Microchip zelf als application notes zijn gepubliceerd. Het is zeker de moeite waard om ook eens op hun site rond te neuzen wat er zo allemaal is te vinden. Voor adressen zie de rubriek Links 

Beschrijving van de Software. De tekst refereert aan de sourcecode file : TX_mk2c.asm          De code is geassembleerd met MPASM van Microchip.

I2c aansturing van de synthesiser.

Het I2c protocol is begin jaren 80 door Philips ontwikkeld om chips met elkaar te laten communiceren via een tweedraads verbinding. Er bestaan intussen veel verschillende ic's die via dit protocol bestuurd worden. Ook de hier gebruikte TSA5055 (of SP5055) synthesiser valt daaronder.

Een I2c boodschap begint altijd met het versturen van het adres van de chip waarvoor de boodschap bestemd is. Daarna worden de registers in de betreffende chip gelezen of beschreven.

De routines die in de pic-controller zijn gebruikt, zijn volgens het "single-master protocol" d.w.z. er is op de i2c-bus maar één master (de pic) die de bus bestuurt. De overige chips zijn "slave" ze wachten tot ze aangesproken worden. Deze werkwijze is het meest simpel te programmeren en wordt vaak gebruikt voor eenvoudige toepassingen.

Voor een exacte specificatie van het i2c protocol zie de Philips website.

Hardware realisatie met de PIC

De i2c lijnen RA3 en RA4 van de pic zijn open drain in/outputs. Door de poort als input te configureren wordt hij "zwevend" (hoge impedantie). Met behulp van een externe weerstand van 4k7 wordt het niveau naar +5 Volt getrokken.

Vervolgens schrijft het programma een "0" naar beide poorten. Dit heeft geen effect, totdat de betreffende poort als output geconfigureerd wordt. Dan gaat de betreffende output-fet in de PIC geleiden en er komt een "0" op de lijn.

Nullen en enen worden nu gemaakt door de poort steeds om te programmeren van output naar input. Het lezen van de datalijn (Sda) is nu ook eenvoudig, eerst zorgen dat hij als input geconfigureerd staat, dan kan de actuele waarde worden ingelezen.

In serie met de i2c lijnen vinden we nog 330 ohm weerstanden. Deze zijn bedoeld om schade aan de chips te voorkomen door kortsluiting of statische lading.

I2C Software

De routines zijn ontleend aan een application-note van Microchip, te vinden op hun website.

De subroutine start_tx activeert de bus, stop_tx geeft het einde van een i2c boodschap aan.

tx_data verzendt de eigenlijke data. Deze data dient van te voren in het tdata-register te worden geplaatst. Bij de aanroep van tx_data wordt een enkel byte verstuurd. Door na het verzenden de carry flag van het status register te checken kunnen we zien of de geadresseerde slave chip (in dit geval de TSA5055) een acknowledge bit heeft gegeven. We weten dan zeker dat de byte is aangekomen.

De routine rx_data kan een enkele databyte lezen van de bus. Dit databyte wordt in het tdata register geplaatst.

De i2c_err routine tenslotte genereert een foutmelding als de ack-puls niet komt.

In deze software wordt daarmee een simpele foutmelding getoond.

Hoe wordt dit in de praktijk gebruikt?

De routine set_syn laat zien hoe de 4 registers van de TSA beschreven worden.

Eerst wordt de i2c startconditie gemaakt, vervolgens het adres van de TSA opgehaald en verzonden. De ack-puls wordt dan getest en zonodig een foutmelding gegenereerd.

Dan worden de 4 databytes verzonden. Tenslotte volgt de i2c stopconditie. Uiteindelijk blijft de bus in rust met beide i2c lijnen "hoog"

De TSA kan werken met verschillende i2c adressen, (in hex) C0, C2, C4, en C6. Een TSA reageert altijd op adres C2, de andere adressen kunnen worden gekozen door een bepaald DC niveau op pin 10 te zetten. Zo kunnen in een systeem maximaal 3 TSA's onafhankelijk van elkaar bestuurd worden. Hier wordt geen gebruik gemaakt van die mogelijkheid en het algemene adres C2 wordt gebruikt.

Programmeren van de TSA:

De TSA bevat vier acht-bits registers:

synthesiser low byte

synthesiser high byte (samen een 16 bits register voor het synthesiser-deeltal)

control byte (hardware configuratie)

ports byte (besturen I/O poorten van de TSA)

Bij een volledige programmering van de chip worden alle 4 bytes verstuurd. Het interne registeradres wordt tijdens het schrijven automatisch opgehoogd, zodat alleen databytes verstuurd hoeven te worden. (auto-increment, de meeste i2c chips doen dit).

Het deeltal:

Dit is een 16bits getal, gesplitst in een Hi en LO byte. Eerst wordt het HI byte verstuurd, vervolgens het LO byte.

De relatie tussen de referentiefrequentie(kristal), deeltal en VCO uitgangsfrequentie is als volgt:

De minimum stepsize = referentiekristal-frequentie gedeeld door referentiedeler maal de totale prescaler deelfactor >

Stepsize = (F_xtal/Nref)*Npsc = (4000/512)*16=125 kHz.

deelfactor N = Fvco/stepsize = Fvco/0.125 (in MHz) oftewel:

Fvco = stepsize * N

Bij een 4MHz kristal komt het zo uit dat het deeltal gelijk is aan 8x de Fvco frequentie.

Control byte: Zie TSA datasheet (standaard op CE)

Ports:

Met deze byte kunnen de extra i/o lijnen op de TSA bediend worden. Alleen de output lijnen P0 en P4 t/m P7 zijn te gebruiken. Door er een '0' in te schrijven wordt de uitgang naar massa getrokken, met een '1' wordt hij tristate (open drain uitgangen). Met deze uitgangen kunnen we wat schakelen, in dit geval bijvoorbeeld de PTT functie van de zender.

LCD display besturing.

Bij het uni-tx project wordt van een zg. industrie standaard lcd gebruik gemaakt op basis van de bekende Hitachi HD44780 controller. Er bestaan vele varianten van dit display, ze verschillen in aantal karakters op een regel en aantal regels.

De basis routine om ze aan te sturen is echter in alle gevallen hetzelfde. Wel moet de software rekening houden met de specifieke geheugenindeling van het betreffende display.

Het display uit de uni-tx heeft 1 regel met 16 karakters. Intern in het display is de geheugenindeling echter zo dat het over 2 regels van 8 karakters verdeeld is.

Een HD44780 kan in de zg 8-bits en 4-bits mode gebruikt worden. Bij de 8-bits mode wordt de data per byte parallel toegevoerd, hiervoor zijn 8 datalijnen nodig. Verder zijn er nog drie controlelijnen nodig, nl register select (RS) enable (E) en read/write (R/W) Totaal komen we dan op 11 lijnen. Op een eenvoudige kleine controller zijn er meestal niet zoveel lijnen beschikbaar, daarom kan het display ook in de 4-bits mode werken. Er zijn dan nog maar 4 datalijnen nodig, en elk databyte moet dan in twee slagen verstuurd worden.

Samen met de control lines zijn er dan nog maar 7 lijnen nodig.

Deze mode wordt ook in de uni-tx gebruikt. De software zorgt ervoor dat elk databyte in twee nibbles gesplitst en achter elkaar verzonden wordt.

De routines zijn ook hier ontleend aan een microchip application-note (AN587) De routine wordt hier letterlijk gevolgd zodat ik voor een uitvoerige beschrijving naar de microchip site wil verwijzen.

In het kort bevat de routine de volgende delen:

Init: het display wordt in de juiste mode gezet (4-bits) en het aantal regels en type cursor e.d. wordt ingesteld.

Send_char: deze subroutine verzendt 1 enkel karakter naar de lcd, de routine verzorgd de opsplitsing van de databyte in twee 4 bits delen. en checkt de ready-flag van het display.

Send_cmd: als boven, maar nu voor besturingscommando's van de lcd. Enige verschil met send_char is het niveau op de register select lijn.

busy_check:

test of het busy bit door de lcd actief gemaakt is, dan kan hij geen data ontvangen en moet worden gewacht tot het display klaar is. Dit type lcd displays is helaas vrij traag. Zeker commando's als clear display duren aardig lang.

dispmsg:

Met deze routine wordt een tekststring naar het display gestuurd. De string staat ergens in het geheugen van de controller en met een '0' aan het einde weet de routine dat het laatste karakter verzonden is.

Onder het label 'table' staan de diverse vaste teksten, elk eindigend met een'0'.

Andere typen displays.

Een veel gehoorde vraag is: Ik heb hier nog een display met die en die maten liggen, kan ik die ook gebruiken?

In principe zijn alle HD44780 compatible displays te gebruiken, alleen moet de initialisatie worden aangepast en er moet voor gezorgd worden dat het programma naar de juiste cursorposities schrijft.

 

Initialisatie:

Het hieronder afgebeelde stuk code verzorgt de initialisatie, met name de hex-waarde in de eerste regel (0x28h) moet dan worden aangepast. (zie datasheet van het te gebruiken display)

; Command sequence for 2 lines of 5x7 characters =0x28h

;

; Busy Flag should be valid after this point

;

movlw 0x28

call SEND_CMD

MOVLW DISP_OFF ;

CALL SEND_CMD ;

MOVLW CLR_DISP ;

CALL SEND_CMD ;

MOVLW ENTRY_INC ;

CALL SEND_CMD ;

; MOVLW DD_RAM_ADDR ;

; CALL SEND_CMD ;

return

Cursorpositie:

Op verschillende plaatsen in het programma is de cursorpositie vast ingebakken. Dit is niet zo'n fraaie werkwijze maar het programma was nooit bedoeld voor afwijkende displays.

Deze cursorposities moeten dan met de hand aangepast worden in de sourcecode.

Kijk hiervoor in de routines:

freqtxt

dis_freq

dis_hex

set_up_var

De meeste displays beginnen op cursoradres 0x80h (links vooraan) Dit adres kan dan ongewijzigd blijven. De adressen beginnend met 0xCxh moeten dan worden aangepast in overeenstemming met de datasheet van het te gebruiken display.

Nieuwe software >>

Vanaf tx13c zijn de display mode (aantal regels) en cursoradressen in de headerfile "LCD.H" gezet. Dit is gedaan om het gebruik van afwijkende displays makkelijker te maken.

Nu hoeft alleen de headerfile nog maar te worden aangepast.

De Main loop:

Na het opstarten en initialisatie belandt het programma bij Main.

Eerst wordt gecheckt op het ingedrukt houden van toets 2. Is dit het geval dan wordt er naar de set-up routine gesprongen, een aparte tak van het programma.

Zo niet dan worden de laatst gebruikte waarden uit de eeprom gehaald (read_setup), de synthesiser wordt op frequentie gezet en interrupts worden enabled.

Van hier af blijft het programma in een eindloze lus draaien. Door interrupts ("timer" en "on RB port") wordt een specifieke taak verricht, waarna de lus wordt vervolgd.

In de lus wordt de waarde van de sequencer-klok (TX_teller) vergeleken met de in de header-file opgegeven waarden TX1, TX2 en TX3. Als zo'n waarde bereikt is dan wordt de bijbehorende stap gezet in de routines set-coax, set-tx en set-pa.

TX_teller staat aan het begin v/d lus op 0. Als de zender aangezet wordt (met toets 1, de Ptt toets) dan loopt TX_teller op in de timer-interrupt routine, tot het maximum (TX3) is bereikt. Intussen worden de schakelacties set-coax, set tx en set_pa uitgevoerd op de respectievelijke tijdstippen.

Als de zender weer wordt uitgezet met toets1 loopt TX_teller weer naar 0 en coax,tx en pa worden in omgekeerde volgorde weer uitgeschakeld.

De TX_teller blijft op 0 hangen totdat de zender weer aangezet wordt.

Verder zit er nog een routine "check_pll" in de lus. Deze routine test de pll-lock flag in de TSA5055, een bitje dat aangeeft dat de pll gelockt is. Hiervoor moet de TSA worden uitgelezen, dit gebeurt in "read_syn". Helaas blijkt het dat de modulatiezwaai bij gebruik als videozender zo groot is dat de lock-indicator meestal op unlocked staat.

Zodoende lukt het niet om bij video-zwaai hier zinnige info uit te halen, reden waarom dit deel van de software nog niet goed werkt en uitgeschakeld is. (Bij gebruik als ontvanger kan het wel werken)

Wel gebeuren er in read_syn nog twee interresante dingen:

Als er een toets-interrupt is geweest ( bijvoorbeeld frequentie verdraaid door de gebruiker) dan wordt de "toetsaktiviteit-vlag" RP1 geset.

Dit wordt hier getest en zo ja, dan wordt de nieuwe frequentie in de eeprom opgeslagen. Dit gebeurt zodoende alleen maar als de frequentie veranderd is, zodat er zomin mogelijk in de eeprom geschreven wordt. Dit omdat het aantal keren dat de eeprom beschreven mag worden beperkt is (100000 keer of zoiets)

Dit lijkt erg vaak maar als de software het bijvoorbeeld elke millisec zou doen dan is dit aantal al in 100 seconden bereikt.

Ook wordt de frequentie nogmaals naar de TSA gestuurd. Dit gebeurt elke twee seconden zodat er geen kans bestaat dat de frequentie door een stoorpuls op de voeding verloren gaat.

Dit is speciaal gedaan voor langdurig onbewaakt gebruik.

Routines Up en dwn;

De rotary encoder wordt getest (op ports B6 en B7)

Eerst wordt gekeken of de puls die de oorzaak was dat we hier belandden er nog is. Zo niet dan eindigt de routine meteen zonder iets te doen. (was een stoorpuls of zo)

Als de puls er nog staat, dan wordt er gewacht op een puls op het andere pootje (b7). Komt deze inderdaad na b6 dan is er sprake van een omhoogdraai actie(rechtsom).

de dwn routine is hetzelfde, maar dan komt de puls het eerst aan bij b7 en later bij b6, een omlaagdraai actie.

Beide routines verwijzen door naar resp. freq_up en freq_dwn.

Routines freq_up en dwn

Hier gebeurt het echte werk.

In het 16bits register freq_hi en freq_lo wordt de aktuele frequentie bewaard. Deze waarde wordt hier opgehoogd of verlaagd met de aktuele stepsize.

De stepsize kan twee waarden hebben, die in het set-up menu worden vastgelegd. Door het indrukken van toets2 wordt tussen de ene en de andere stepsize gekozen.

Tevens worden bij het verhogen of verlagen gecheckt of de minimum en maximum waarde van de freq niet wordt overschreden. Ook deze waarden waren tijdens de set-up vastgelegd.

Dit gebeurt door naar een aparte routine chk_min of chk_max te springen.

Aan het eind wordt de routine verlaten via up_dwn_1, waar nog even de nieuwe freq. naar de synthesiser en het display wordt gestuurd.

Routine Reken

Hier wordt uit de frequentie het deeltal bepaald dat naar de synthesiser wordt gestuurd.

De meeste verschillen tussen de programma's voor zender en ontvangen en/of 10GHz versies zijn allen hier te vinden.

In de standaard uitvoering bevat het register freq een waarde van 4x de echte frequentie.

Omdat in de normale uitvoering het deeltal 8x de frequentie moet zijn, hoeft hier alleen nog maar met 2 te worden vermenigvuldigd.

Routine Set_syn

Hier worden de vier databytes te weten deeltal_hi , deeltal_lo, control-byte en ports-byte naar de synthesiser gestuurd met behulp van de I2c routines, die van hier uit worden aangeroepen.

Routine freqtxt

Deze routine zet het niet veranderlijke deel van de tekst op het LCD display.

Routine hex_2_bcd

Deze routine zet hex-getallen om in bcd getallen zodat ze naar het LCD display kunnen worden gestuurd. Later ( in de routine digit) wordt er nog 30hex bij opgeteld om er ascii van te maken.

De routine hex_2_bcd komt ook uit de collectie van Microchip application-notes

 

Routine dis_freq

Hier wordt de frequentie, die in de registers freq_lo en hi staat geschikt gemaakt voor afbeelding op het display.

Dit houdt onder meer in dat de waarde eerst door 4 moet worden gedeeld omdat in freq de viervoudige frequentie staat. Verder moet het 16bits getal in 4 of 5 bcd-cijfers worden uitgesplitst en er moet ascii van gemaakt wordten voor het LCD display.

Aan het begin v/d routine zit een "dirty trick" om het deel achter de komma af te beelden,dit gaat niet via omzetting van getallen maar door een bijpassende tekststring op te zoeken in de tekstentabel. Dit komt o.a. omdat dit er later bijgemaakt is.

 

Routines Key_1,2

Deze routines testen op het indrukken van een toets

Ze worden aangesproken als er een toetsinterrupt is geweest in de main loop routine toets.

Hier wordt dan gekeken welke toets is gedrukt en de passende actie wordt genomen.

Met Key_2 wordt nu niks gedaan.

Routines save_eefreq en lees_eefreq

Deze routines kunnen data plaatsen en ophalen in het 64-byte grote eeprom data deel van de processor. Om per ongeluk wissen te voorkomen moet hier nogal op een speciale manier in geschreven worden. Dit onderwerp is uitgebreid beschreven in de datasheet van de 16F84.

Routines delay_xxx

Een paar verschillende delay routines voor de hier en daar nodige vertragingstijden.

Routine i2c_init

Hier wordt de port A ingesteld voor gebruik als i2c lijnen en tevens een simpele test uitgevoerd of de bus niet kortgesloten is. Deze routine wordt bij het opstarten slechts eenmalig doorlopen.

Routine read_syn

Deze routine is opgenomen in de main-loop en wordt middels de in de main-loop aangebrachte vertragingslus elke 2 seconde doorlopen.

Eerst wordt getest of er sinds de laatste keer nog wat aan de frequentie gedraaid is, zo ja dan wordt de nieuwe waarde in de eeprom gezet. Zo niet dan wordt dit overgeslagen, zo wordt er niet onnodig vaak in de eeprom gerommeld.

Door deze voorziening start de zender altijd op met de laatst gebruikte frequentie.

Vervolgens wordt de pll-lock-vlag uit de synthesiser gelezen en de waarde gecheckt.

Helaas wil dit alleen bij toepassingen met weinig of geen modulatiezwaai omdat anders altijd een uit-lock signaal wordt afgegeven. Daarom is dit deel met komma's in de source code uitgeschakeld.

Bij gebruik als ontvanger kan men dit weer aanzetten door de komma's te verwijderen, maar veel nut heeft het allemaal niet.

Routine set_up_var

Hier wordt alleen naartoe gesprongen als tijdens het opstarten de toets2 vastgehouden wordt. Zie ook het begin van main.

De gebruiker kan hier de minimum , maximum frequentie en de stepsize instellen. De waarden worden in de eeprom gezet en tijdens het gewone gebruik zonodig uitgelezen.

Het is een rommelig deel, waar de inspiratie mij duidelijk ging verlaten.

LET OP! Hier staan ook de uiterste grenzen van het instelbereik in verstopt. Wanneer deze niet goed zijn dan moet het hier worden aangepast.

Routine read_setup

Aan het begin van het programma worden de in eeprom opgeslagen variabelen naar normale werkregisters gekopieerd.

Helemaal aan het einde van de source code file vinden we nog het deel achter org 2007

Hier worden de fuses van de 16F84 ingesteld en de eeprom met default data geladen.

Niet alle programmers ondersteunen deze werkwijze en de eeprom wordt dan niet mee geprogrammeerd.

Ook geeft de assembler MPASM een foutmelding op het adresbereik, maar de code komt wel in de file, dus deze fout kan worden genegeerd.

 

 

U kunt een e-mailbericht met vragen of opmerkingen over deze website verzenden aan [email protected].
Copyright © 2001 R.G. Krijgsman
Laatst bijgewerkt: 01 januari 2002