;аа Routines for FSK 1200 bps modem with a PIC16C84

;аа -----------------------------------------------


;аа Free software by Rildo Pragana

;ааааа e-mail:а rpragana@truenet.com.br

;ааааа s-mail: Caixa Postal 7440 Recife 50,630-970 Brasil

;аа partially based on software by Eric Smith, dtmf.asm (Thanks Eric)


;аааа Dedicated to all that do not spare computational power, by

; requesting more powerful machines and more memory, and in despite

; of this can make efficient devices to serve mankind.а It is

; for YOU, PIC programmer :-)

;аа If you like PIC, Linux, and GNU software, you are not alone!


;Some notes:


;а This software sends a buffer full (with option for a single byte

;answer) each time, because of timing constraints.а You can use

;a simple protocol to exchange data between two similar devices,

;by framing each data chunk with STX, ETX, and answering with

;single byte messages (ACK, NAK).

;аааа If you need the (analog) circuits for the phne line, please

;ask me by e-mail.а I used this in a circuit for logging data from

;a PABX which sends to a "printer" each phone call done.

;аа "connect" routine dial a phone number and waits for an answer

;(single byte ENQ).а FRSIZ lets you choose if the message is long

;or short.а You may change buffer size to suit your needs.

;а "tframe" frames a message and sends it (must be connected before).

;а "rxline" waits for a message arriving.

;а Notice that some variables are reused, but not at the same time.



ааааааа LISTааа p=16C84 ;target processor

ааааааа INCLUDE p16c84.inc

ааааааа __CONFIG 019hаа ;CP off, PWRTE on, WDTE off, XT osc

ааааааа radix DEC


wаааааа equаааа 0

fаааааа equаааа 1


#define _cааааа STATUS,C

#define _zааааа STATUS,Z

#define _rp0ааа STATUS,RP0

#define _t0ifаа INTCON,2

#define _pwmааа PORTA,3

#define _rxmааа PORTA,4

#define _rlyааа PORTA,2

#define _rngааа PORTB,2

#define ABRTааа rflags,0

#define STOPBаа rflags,1

#define STBITаа rflags,2

#define INOLDаа rflags,3

#define SYNCааа rflags,4

#define FRSIZаа rflags,5

#define BITOааа rflags,6

#define RBITааа rflags,7


;<---------------------- rflags ------------------------->




; FRSIZ = 0 --> single byte , 1 --> full buffer


clockrateаааааа equаааа .6144000ааааааа ;crystal frequency

fclkааааааааааа equаааа clockrate/4аааа ;processor instruction rate


rflagsа equаааа 0ch

trdetаа equаааа 11hаааа ;time since last input transition

timoutа equаааа 12h


countаа equаааа 0dhаааа ;general use counter

delayаа equаааа 0ehаааа ;delay counter

digitаа equаааа 11h

delayms equаааа 12hаааа ;delay in ms


bitcntа equаааа 0dhаааа ;bit counter

smpcntа equаааа 0ehаааа ;sample counter

oldsmpа equаааа 0fhаааа ;last sample

dphaseа equаааа 10hаааа ;phase difference

phaseаа equаааа 11hаааа ;current phase

sampleа equаааа 12hаааа ;current sample

bytcntа equаааа 13hаааа ;byte counter


bufаааа equаааа 17h

bufdatа equаааа buf+3

buflimа equаааа 2ch

bccаааа equаааа buflim

tmpаааа equаааа bccаааа ;usado somente em pstore e psnum

tmcntаа equаааа buf+1аа ;usado como contador para armazenamento do buffer


ааааааа constant FULLBIT = 36

ааааааа constant HALFBIT = 17 ;FULLBIT/2

ааааааа constant STRTBIT = 58 ;(3 * FULLBIT)/2 + (1/8)FULLBIT = (13/8)FULLBIT

ааааааа constant HIWIN = 11

ааааааа constant SYNCBYTE = 56h ;sync byte


ааааааа constant PHMASKа = 0fh

ааааааа constant LODPHаа = 1

ааа ааааconstant HIDPHаа = 2

ааааааа constant ENQ = 05h

ааааааа constant STX = 02h

ааааааа constant ETX = 03h

ааааааа constant EOT = 04h

ааааааа constant SUB = 1ah

ааааааа constant ACK = 06h

ааааааа constant NAK = 15h


ааааааа orgаааа H'2100'

phoneаа deааааа "0~2224023",0аааааааа ;phone number (dialing string)


ааааааа org 0

ааааааа goto start


msgаааа addwfаа PCL,f

ааааааа dtааааа "FSK modem test",0

waveааа addwfаа PCL,fаааааааааа ;2+2+2 (addwf+call+return)

ааааааа dtааааа 20h,2ch,37h,3dh,3fh,3bh,32h,26h,19h,0dh,04h,00h,02h,08h,13h,20h



; Send single char messageаа === DON'T MOVE ===


putansа movwfаа bufdat

ааааааа bcfаааа FRSIZ


;Prepare header,bcc and transmit buffer's message


tframeа callааа ldcntf

ааааааа clrw

putbcc2 xorwfаа INDF,w

ааааааа incfааа FSR,f

ааааааа decfszа tmcnt,f

ааааааа gotoааа putbcc2

ааааааа movwfаа bcc

ааааааа movlwаа buf

ааааааа movwfаа FSR

ааааааа movlwа а0ffhааааааааааа ;PAD

ааааааа callааа putch

ааааааа callааа putch

ааааааа movlwаа SYNCBYTEааааааа ;synchronization char

ааааааа callааа putch


;аааааа MODEM transmission


txlineа movlwаа 5аааааааааааааа ;header+char+bcc

ааааааа btfscаа FRSIZ

ааааааа movlwаа buflim-buf+1ааа ;total buffer's size

ааааааа movwfаа bytcnt

ааааааа bcfаааа ABRT

ааааааа movlwаа .15

ааааааа movwfаа smpcnt

ааааааа movlwаа .11

ааааааа movwfаа bitcnt

ааааааа clrfааа dphase

ааааааа movlwаа 20h

ааааааа movwfаа phase

ааааааа clrfааа sample

ааааааа bcfаааа _pwm

ааааааа movlwаа bufаааааааааааа ;buffer's beginning (incl. header)

ааааааа movwfаа FSR

xmblkаа btfscаа ABRTааааааааааа ;2

ааааааа return

ааааааа movfааа sample,wааааааа ;1

ааааааа movwfаа oldsmpааааааааа ;1

ааааааа bsfаааа _pwmааааааааааа ;1

ааааааа swapfаа oldsmp,wааааааа ;1

ааааааа andlwаа 3аааааааааааааа ;1

ааааааа addwfаа PCL,fаааааааааа ;2+2

ааааааа gotoааа samp3

ааааааа gotoааа samp2

ааааааа gotoааа samp1

ааааааа gotoааа samp0

samp0аа callааа pulseаааааааааа ;27

ааааааа callааа nxsmpаааааааааа ;16

ааааааа callааа nxbitаааааааааа ;16

ааааааа callааа nxbyteааааааааа ;16

ааааааа gotoааа xmblkаааааааааа ;2

samp1аа callааа nxsmpаааааааааа ;16

ааааааа callааа pulseаааааааааа ;27

ааааааа callааа nxbitаааааааааа ;16

ааааааа callааа nxbyteааааааааа ;16

ааааааа gotoааа xmblkаааааааааа ;2

samp2аа callааа nxsmpаааааааааа ;16

ааааааа callааа nxbitаааааааааа ;16

аааа аааcallааа pulseаааааааааа ;27

ааааааа callааа nxbyteааааааааа ;16

ааааааа gotoааа xmblkаааааааааа ;2

samp3аа callааа nxsmpаааааааааа ;16

ааааааа callааа nxbitаааааааааа ;16

ааааааа callааа nxbyteааааааааа ;16

ааааааа callааа pulseаааааааааа ;27

ааааааа gotoааа xmblkаааааааааа ;2


pulseаа movfааа oldsmp,wааааааа ;1+2

ааааааа andlwаа 0fhаааааааааааа ;1

ааааааа addwfаа PCL,fаааааааааа ;2

ааааааа nopаааааааааааааааааааа ;0 ~ 15

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа nop

ааааааа bcfаааа _pwmаааааа ;1

ааааааа xorlwаа 0fhаааааааааааа ;1

ааааааа addwfаа PCL,fаааааааааа ;2

waste19 nopаааааааааааааааааааа ;0 ~ 15

waste18 nop

waste17 nop

waste16 nop

waste15 nop

waste14 nop

waste13 nop

waste12 nop

waste11 nop

waste10 nop

waste9а nop

waste8а nop

waste7а nop

waste6а nop

waste5а nop

waste4а returnааааааааааааааааа ;2


nxsmpаа movfааа dphase,wааааааа ;1+2 (call)

ааааааа addwfаа phase,wаааааааа ;1

ааааааа andlwаа PHMASKааааааааа ;1

ааааааа movwfаа phaseаааааааааа ;1

ааааааа callааа waveааааааааааа ;6

ааааааа movwfаа sampleааааааааа ;1

ааааааа decfааа smpcnt,fааааааа ;1

ааааааа returnааааааааааааааааа ;2


nxbitаа movfааа smpcnt,fааааааа ;1+2

ааааааа btfssаа _zааааааааааааа ;2/1

ааааааа gotoааа nxbit1ааааааааа ;2

ааааааа movlwаа LODPHаааааааааа ;1

ааааааа btfssаа BITOааааааааааа ;2

ааааааа movlwаа HIDPHаааааааааа ;

ааааааа movwfаа dphaseааааааааа ;1

ааааааа bsfаааа _cааааааааааааа ;1

ааааааа rrfаааа INDF,fааааааааа ;1

ааааааа bcfаааа BITOааааааааааа ;1

ааааааа btfscаа _cааааааааааааа ;2

ааааааа bsfаааа BITOааааааааааа ;

xreturn returnааааааааааааааааа ;2

nxbit1а incfааа smpcnt,wааааааа ;1+4

ааааааа btfssаа _zаааааааа ааааа;2/1

ааааааа gotoааа waste8ааааааааа ;8

ааааааа movlwаа .15аааааааааааа ;1 samples-1 for each cycle

ааааааа movwfаа smpcntааааааааа ;1

ааааааа decfааа bitcnt,fааааааа ;1

ааааааа gotoааа xreturnаааааааа ;3


nxbyteа movfааа bitcnt,fааааааа ;1+2

ааааааа btfssаа _zааааааааааааа ;2/1

ааааааа gotoааа waste12аааааааа ;12

ааааааа incfааа FSR,fаааааааааа ;1 advance pointer

ааааааа movlwаа .11аааааааааааа ;1

ааааааа movwfаа bitcntааааааааа ;1

ааааааа bcfаааа BITOааааааааааа ;1 start bit

ааааааа decfszа bytcnt,fааааааа ;2/1

ааааааа gotoааа nxbyt1ааааааааа ;2

ааааааа bsfаааа ABRTааааааааааа ;1

nxbyt1а gotoааа xreturnаааааааа ;3



;аааааа MODEM reception


rxansаа bcfаааа FRSIZаааааааааа ;receive single char answer

rxlineа movlwаа 2

ааааааа btfscаа FRSIZ

ааааааа movlwаа buflim-bufdat+1

ааааааа movwfаа bytcntааааааааа ;number of bytes to receive

ааааааа clrfааа trdet

ааааааа clrfааа smpcnt


ааааааааааа bsfаааааа RBIT

ааааааааааа movlwа 11100001b

ааааааа andwfаа rflags,f

ааааааа movlwаа .8ааааааааааааа ;bitcnt=8

ааааааа movwfаа bitcnt

ааааааа callааа fsrdat

ааааааа clrfааа INDFааааааааааа ;received byte=NULL (it may have garbage)

ааааааа callааа waste8ааааааааа ;may be used for other tasks


ааааааа ;movfааа rclk1,wааааааа ;uncomment this if you have a RTC (real-time clock)

ааааааааааааааааааааааааааааааа ;that increments rclk1 each 8 seconds

ааааааа ;addlwаа 4аааааааааааааа ;aprox. 32s time-out

ааааааа ;movwfаа timout


ааааааа gotoааа pllsyn


pllendа incfааа trdet,fаааааааа ;1+7

ааааааа movfааа trdet,wаааааааа ;1

ааааааа sublwаа HIWINаааааааааа ;1 ( HIWIN > trdet ) ==> Carry

ааааааа btfssаа _cааааааааааааа ;2

ааааааа bsfаааа RBITааааааааааа

ааааааа movfааа trdet,wаааааааа ;1

ааааааа sublwаа FULLBITаааааааа ;1 ( FULLBIT > trdet ) ==> Carry

ааааааа movlwаа HALFBITаааааааа ;1

ааааааа btfscаа _cааааааааааааа ;2/1

ааааааа gotoааа recbitааааааааа ;2

ааааааа movwfаа trdetаааааааааа ;1


ааааааа callааа waste4ааааааааа ; ...or use time-out if you have a

ааааааааааааааааааааааааааааааа ; RTC (real-time clock) in sotware

ааааааа ;movfааа timout,wааааааа ;1

ааааааа ;subwfаа rclk1,wаааааааа ;1

ааааааа ;btfscаа _cааааааааааааа ;2 if carry, rclk1 >= timout

ааааааа ;return

recbitа btfssаа STBITаааааааааа ;2/1+17 waiting start bit?

ааааааа gotoааа recb1аааааааааа ;2

ааааааа decfszа smpcnt,fааааааа ;2/1 time for another sample?

ааааааа gotoааа recb2аааааааааа ;2

ааааааа movlwаа FULLBITаааааааа ;1а new bit window time

ааааааа movwfаа smpcntааааааааа ;1

ааааааа bcfаааа _cааааааааааааа ;1 carry=RBIT

ааааааа btfscаа RBITааааааааааа ;2

ааааааа bsfаааа _c

ааааааа rrfаааа INDF,fааааааааа ;1

ааааааа decfszа bitcnt,fааааа аа;2/1 counts one more received bit

ааааааа gotoааа recb3аааааааааа ;2

ааааааа movlwаа .8ааааааааааааа ;1

ааааааа movwfаа bitcntааааааааа ;1

ааааааа bcfаааа STBITаааааааааа ;1 waits for another start bit (subtot=32)

ааааааа btfssаа SYNCааааааааааа ;2/1

аа аааааgotoааа recb4аааааааааа ;2

ааааааа incfааа FSR,fаааааааааа ;1

ааааааа decfszа bytcnt,fааааааа ;2/1

ааааааа gotoааа $+2аааааааааааа ;2

ааааааа return

ааааааа gotoааа pllsynааааааааа ;2


recb1аа btfssаа STOPBаааааааааа ;2/1+20

ааааааа gotoааа recb1bаа ааааааа;2

ааааааа btfssаа RBITааааааааааа ;2/1

ааааааа gotoааа recb1aааааааааа ;2

ааааааа callааа waste4ааааааааа ;4

recb1cа gotoааа $+1аааааааааааа ;2

ааааааа callааа waste8ааааааааа ;8 may be used for other task

ааааааа gotoааа pllsynааааааааа ;2

recb1bа btfscаа RBITааааааааааа ;2+23

ааааааа bsfаааа STOPBаааааааааа ;

ааааааа callааа waste8ааааааааа ;8 may do something useful instead

ааааааа gotoааа $+1аааааааааааа ;2

ааааааа gotoааа pllsyn1аааааааа ;2

recb1aа bsfаааа STBITаааааааааа ;1+25

ааааааа bcfаааа STOPBаааааааааа ;1

ааааааа movlwаа STRTBITаааааааа ;1

ааааааа movwfаа smpcntааааааааа ;1

ааааааа callааа waste6ааааааааа ;6

ааааааа gotoааа pllsyn1аааааааа ;2

recb2аа callааа waste12аааааааа ;12+23

ааааааа gotoааа pllsyn1ааааааааа ;2

recb3аа gotoаа а$+1аааааааааааа ;2+32

ааааааа nopаааааааааааааааааааа ;1

ааааааа gotoааа pllsyn1ааааааааа ;2

pllsyn1 gotoааа pllsynааааааааа ;2

recb4аа movfааа INDF,wааааааааа ;1+35

ааааааа sublwаа SYNCBYTEааааааа ;1

ааааааа btfscаа _zааааааааааааа ;2

ааааааа bsfаааа SYNCааааааааааа ;1

pllsynа btfssаа _rxmааааааааааа ;2/1

ааааааа gotoааа pll1ааааааааааа ;2

ааааааа nopаааааааааааааааааааа ;1

ааааааа btfssаа INOLDаааааааааа ;2/1

ааааааа gotoааа plldifaаааааааа ;2

ааааааа gotoааа pllendааааааааа ;2

pll1ааа btfscаа INOLDаааа аааааа;2/1+3

ааааааа gotoааа plldifbаааааааа ;2

ааааааа gotoааа pllendааааааааа ;2

plldifa bsfаааа INOLDаааааааааа ;1

ааааааа gotoааа plldifааааааааа ;2

plldifb bcfаааа INOLDаааааааааа ;1

ааааааа gotoааа plldifааааааааа ;2

plldifа movfааа trdet,wаааааааа ;1+9

ааааааа sublwаа HIWINаааааааааа ;1 ( HIWIN > trdet ) ==> Carry

ааааааа bcfаааа RBITааааааааааа ;1

ааааааа btfssаа _cааааааааааааа ;2

ааааааа bsfаааа RBITааааааааааа ;

ааааааа clrfааа trdetаааааааааа ;1

ааааааа gotoааа recbitааааааааа ;2


; Get/Put char into the buffer


getchаа movfааа INDF,w

ааааааа gotoааа $+2аааааааааааа ;incrementa apontador e volta

putchаа movwfаа INDF

ааааааа incfааа FSR,f

ааааааа return


; Check if BCC is correct -- (only messages with FRSIZ=1)

; returns _z set if BCC is right


chkbccа callааа ldcntf

chkb1аа callааа getch

ааааааа xorwfаа bcc,f

ааааааа decfszа tmcnt,f

ааааааа gotoааа chkb1

ааааааа movfааа bcc,w

ааааааа return


;аааааа Dial Utilities


dialnum bsfаааа _rly

ааааааа movlwаа .20аааааааааааа ;delay 2.5s

ааааааа callааа waitx

ааааааа movlwаа LOW(phone)

ааааааа movwfаа EEADR

dialnu1 callааа emget

ааааааа andlwаа 03fh

ааааааа btfscаа _z

ааааааа return

ааааааа andlwаа 0fhаааа ;dial one digit

ааааааа btfscаа _z

ааааааа movlwаа .10аааа ;dial 10 pulses if digit=0

ааааааа movwfаа digit

ааааааа sublwаа 0ehаааа ;test if digit==0eh (delay) --> '~' == 0x7e

ааааааа btfscаа _z

ааааааа gotoааа digdlyа ;only 1/2 second delay

digloop bcfаааа _rlyааа ;relay open (38ms)

ааааааа movlwаа .38*2

ааааааа callааа waitms

ааааааа bsfаааа _rlyааа ;relay close (62ms)

ааааааа movlwаа .62*2

ааааааа callааа waitms

ааааааа decfszа digit,f

ааааааа gotoааа digloop

ааааааа movlwаа .3ааааа ;interdigit delay 300ms (nominal 375ms)

ааааааа callааа waitx

digdlyа movlwаа .4ааааа ;delay 1/2 s

ааааааа callааа waitx

ааааааа gotoааа dialnu1


; Delay (W = 1/2 milliseconds units)


wait12а clrwааааааааа аааааааааа;delay 128ms

waitmsа movwfаа delayms

ааааааа clrfааа delay


ааааааа callааа waste10аааааааа ;change this if RTC (real-time clock)

ааааааа callааа waste12аааааааа ;is implemented

ааааааа ;callааа rtcupd


waitms1 decfszа delay,fаааааааа ;256*3

а ааааааgotoааа waitms1


ааааааа callааа waste10аааааааа ;see notes 6 lines above

ааааааа callааа waste12

ааааааа ;callааа rtcupdааааааааа ;22


ааааааа decfszа delayms,f

ааааааа gotoааа waitms1

ааааааа return


; w * 1/8 second delay


wait1sа movlwаа 8

waitxаа movwfаа count

waitx1а movlwаа .125*2

ааааааа callааа waitms

ааааааа decfszа count,f

ааааааа gotoааа waitx1

ааааааа return


; Connects and test received ENQ

;аааа returns carry=1 if error


connect callааа dialnum

ааааааа callааа rxans

ааааааа btfssаа SYNC

ааааааа gotoааа disconnааааааааа ;sem resposta, erro

ааааааа movfааа bufdat,w

ааааааа sublwаа ENQ

ааааааа btfssаа _z

ааааааа gotoааа disconn

retokаа bcfаааа _c

ааааааа return

disconn bcfаааа _rly

reterrа bsfаааа _c

ааааааа return


;Loads FSR pointing to buffer's data area


ldcntfа callааа ldtcnt

fsrdatа movlwаа bufdat

ааааааа movwfаа FSR

ааааааа return


;Loads counter with buffer's data area size


ldtcntа movlwаа buflim-bufdat

ааааааа movwfаа tmcnt

ааааааа return


; Get a byte from EEPROM and advance pointer


emgetаа bsfаааа _rp0ааааааааааа ;get byte and advance pointer

ааааааа bsfаааа EECON1,RD

ааааааа bcfаааа _rp0

ааааааа movfааа EEDATA,w

ааааааа incfааа EEADR,f

ааааааа return




startаа movlwаа 00000001b

ааааааа movwfаа PORTA

ааааааа movlwаа 10111000b

ааааааа movwfаа PORTB

ааааааа clrfааа rflags

ааааааа bsfаааа _rp0

аа аааааmovlwаа 12h

ааааааа movwfаа TRISA

ааааааа movlwаа 07h

ааааааа movwfаа TRISB

ааааааа bcfаааа EECON1,EEIF

ааааааа movlwаа 10000111bаааааа ;starts prescaler,timer0

ааааааа movwfаа OPTION_REG

ааааааа bcfаааа _rp0

ааааааа bcfаааа _t0if


testааа gotoааа testаааааааа ;======аа put your code hereаа ======


;Make two PICs, one for transmitter test, the other for receiver test,

;using something like the routines below: (testorg and testans)


;You may wish to add a trigger signal for the oscilloscope, so add it

;just before 'call tframe' using an unassigned port.а At the receiving

;side you may add 2 leds (green and red) for telling if everything

;arrived. Turn them on at 'ansdone'(green) and 'anserr'(red). Don't

;forget to turn them off at the beginning!


testorg callааа connect

ааааааа btfssаа _c

ааааааа gotoааа orgerr

ааааааа clrfааа count

ааааааа movlwаа bufdatааааааааа ;fill data area with test message

ааааааа movwfаа FSR

mvmemаа movfааа count,w

ааааааа callааа msg

ааааааа andlwаа 0ffhаа ааааааааа;test for W = 0 (end-of-message)

ааааааа btfscаа _z

ааааааа gotoааа mvdone

ааааааа callааа putch

ааааааа incfааа count,f

ааааааа gotoааа mvmem

mvdoneа callааа tframe

ааааааа bcfаааа _rlyааааааааааа ;disconnect, all done

orgloop gotoааа orgloopаааааааа ;stop now

orgerrа gotoааа orgerrааааааааа ;did'nt connect?!


testans btfssаа _rng

ааааааа gotoааа answer

ааааааа gotoааа testans

answerа bsfаааа _rlyааааааа аааа;get "phone"

ааааааа callааа wait1sааааааааа ;some time to get line ready (no noise)

ааааааа movlwаа ENQ

ааааааа callааа putansааааааааа ;send ENQ to the originating part

ааааааа bsfаааа FRSIZаааааааааа ;we'll receive now a full buffer

ааааааа callааа rxline

ааааааа btfssаа SYNCааааааааааа ;if SYNC not found, perhaps a time-out occurred

ааааааа gotoааа anserr

ааааааа callааа chkbccааааааааа ;verifies if BCC is right for the msg received

ааааааа btfssаа _zааааааааааааа ;zero flag set means it's ok

ааааа ааgotoааа anserr

ansdone gotoааа ansdoneаааааааа ;presto! The message received is in the buffer

ааааааааааааааааааааааааааааааа ;(believe it or show it.) You may add some

ааааааааааааааааааааааааааааааа ;simple RS-232 routines to send the buffer

ааааааааа аааааааааааааааааааааа;out to a dumb terminal or PC

anserrа gotoааа anserr


аааа END



Используются технологии uCoz