Listers, Some time ago I developed some fairly rough and ready code to decode the low speed modem modulation used by Bell 202, V23 and the old Kansas City tape interface. It was primarily developed to allow a PIC to decode Caller ID signals from a phone line but can be used for a variety of different purposes. The technique allows a 16F PIC to receive and decode Caller ID signals, or to allow 2 PICS to communicate over the phone network, or between local nodes strung together with bell-wire, for home automation projects. It allows both the data signal and power to be distributed to all nodes on the network using just 2 wires. I am working on a low cost DIY network for HA projects based on intelligent nodes communicating via wire or low power RF using the popular SNAP protocol www.hth.com How It Works: The technique first uses a high gain amplifier to turn the sinusidal modem tone signal into an approximate squarewave which can then be fed directly into Port B7 set up to interrupt on both rising and falling edges I use Timer 0 to time the period between the signal edges - using interrupt on both edges, and compare these times against an upper and lower threshold value. If greater than the threshold, I set a Port A bit else I clear it. This signal on Port A is effectively the demodulated modem signal as a serial bit stream which can be fed into a terminal program. If anyone is interested in similar techniques - please drop me a line. Meanwhile attached is the rudimentary source code, so you can see what's going on. There is also a Yahoo Group for interested enthusiasts of such techniques - we have about 540 members. Called rat_ring the rat refers to the PIC based node - the Remote Applications Terminal http://groups.yahoo.com/group/rat_ring/ We have source code for DTMF generation and decoding on a PIC16F84A, plus coding and decoding popular modem modulation - again on an F84A. In the members files area you will find constructional details for the rat based projects as well as a 40 page tutorial describing how to safely connect PIC devices to the telephone line and detect and decode Caller ID and other telephone signals. Merry Christmas & Happy New Year, Ken Boak rat_ring |
;********************************************************************************************* ; V23 demodulator code - running with a 3.579545 MHz ceramic resonator ; ; This code uses Timer 0 to time the pulse widths of the signal applied to the B7 pin ; Timer 0 is used with a divide by 4 prescaler ; Each time an edge is detected on pin B7 the routine generates the time period of the last half period. ; If the period is short - then it is a high frequency input, long pepriod = low frequency ; It stores the time (in half clock cycles) in a variable assigned to T0-count ; The count is compared with certain limits to see if the input signal frequency matches ; that of V23 high tone 2100Hz or V23 low tone 1300Hz ; The frequency thresholding is centered around 1700Hz so this will work with any modulation ; which uses frequencies either side of 1700Hz including V23, Bell 202 and ; Kansas City tape interface standards. ; Port pin A1 is set to signify 1300Hz (mark) and cleared to signal 2100Hz (space) ; and can thus be taken as the demodulated serial output, provided the routine controls the bit time ; The demod routine is timed to run in approximately 833uS. This is the bit time for 1200baud comms ; Port A2 is used to examine the output of the demod routine ;********************************************************************************************* demod_init movlw 0FFh movwf ALLONES clrf PORTB ; Init output latches for port B to 0 movlw B'10000001' ; set port B as output except bit 7, 0 tris PORTB ; Set all of PORT B to outputs MOVLW B'00010001' ; Set A0, A4 as inputs, A1, A2, A3 as output tris PORTA ; set up timer 0 with a divide 4 on the prescaler init_rtcc bsf STATUS,RP0 movlw B'11000001' ; weak pull ups off, rising edge interrupts, internal clock/4 movwf OPTION_REG bcf STATUS, RP0 clrf TMR0 ; start timer 0 ; movlw B'10010000' ; enable INT interrupts movlw B'10001000' ; enable port B change interrupts movwf INTCON ; Demodulate the incoming tones into 1200 baud asynchronous serial bits and put them out on port A2 ; The demod routine ( plus an allowance for the ISR) should take 833uS to run, to set the correct ; 1200 baud bit time. This next routine re-times the bits into 833uS chunks demod movlw 120 ; Is sum >165 then mark subwf T0_sum,0 ; 2100Hz gives 106, 1300 Hz gives 172 btfsc STATUS,C ; carry is SET IF T0_count > threshhold bsf PORTA,2 ; set PORTA,2 send the bit to the "Test Pin" btfss STATUS,C ; bcf PORTA,2 ; goto continue ; This next part bit-bangs Port A2 to reconstitute a serial data stream from the ; demodulated data. Connect to hyperterminal or similar running at 1200,8,N,1 to view movfw T0_last subwf T0_count,0 ; if T0_count > T0_last then mark btfsc STATUS,C bsf PORTA,2 ; raise Port A,2 movfw T0_last subwf T0_count,0 ; if T0_count > T0_last then mark btfss STATUS,C bcf PORTA,2 ; lower Port A,2 goto continue nop8 nop ; Some Nops to get the right timing delays nop nop nop nop nop nop nop nop nop continue nop nop nop nop nop movlw 215 ; this gives 833uS delay - put the rest of the user code movwf bit_count ; into this 833uS time slot ; hold the space for 833uS redo_A decfsz bit_count,Same goto redo_A goto demod ; this whole loop goes every 833uS - as near as possible ;*************************************************************************************** ;This is the Interrupt service routine for determining the frequency on pin 13 Port B7 ISR ;********************************************************************** ; ; CONTEXT SAVE ; ;********************************************************************** ;Save STATUS and W registers into RAM before servicing timer interrupt C_SAVE MOVWF W_TEMP SWAPF STATUS,W BCF STATUS,5 ; ENSURE BANK0 SAVE MOVWF STATUS_TEMP ; BTFSS INTCON,INTF ; Test for external interrupt ; GOTO C_RESTORE BTFSS INTCON,RBIF ; Exit ISR if it wasn't a port B change GOTO C_RESTORE ; btfsc PORTB,7 ; Test for rising edge interrupt ; goto clr_rbintf ; exit if falling edge ; The signal applied to pin B7 causes an interrupt on change on both the rising and falling edges. ; On receipt of an interupt we stop the T0 counter and store its value into register T0_count. ; We then clear the counter to set it counting again. We use the divide by 4 prescaler ; 1300Hz gives a half period of 86 in T0_count, 2100Hz gives a T0_count of 53 ; So if we test bit 6 of T0_count we can determine whether the signal is mark or space. ; and set Port A1 pin or flag accordingly. Constant mark will keep the port pin high. ; T0_sum contains the sum of the last 2 half periods - so can be used to qualify the signal frequency ; For this to work well, the signal needs to have close to equal high and low periods. If the signal ; M/S ratio varies too much from 1:1, the 1300Hz low period may be falsely interpreted as 2100Hz etc. Changepin_isr movfw T0_count ; get the last count movwf T0_last ; save it movfw TMR0 ; read Timer 0 movwf T0_count ; save it in T0_count for next time clrf TMR0 ; start the timer again btfsc T0_count,6 ; If T0_count <64 then lower Port A1 - a space bsf PORTA,1 btfss T0_count,6 ; If T0_count >d then raise Port A1 - a mark bcf PORTA,1 addwf T0_last,0 ; get the sum of last and current in W movwf T0_sum ; put it in T0_sum for testing clr_rbintf movf PORTB,1 ; read port b to clear the mismatch BCF INTCON,RBIF ; clear port B changed interrupt bit ; BCF INTCON,INTF ; clear external interrupt bit ;******************************** ; ; Context Restore ; ;******************************** C_RESTORE BCF STATUS,5 ;ENSURE BANK0 RESTORE SWAPF STATUS_TEMP,W MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE END |
|
PIC16F84A decodes Bell 202 and V23
Started by ●December 27, 2002
Reply by ●December 27, 20022002-12-27
>Some time ago I developed some fairly rough and ready code to decode
the low >speed modem modulation used by Bell 202, V23 and the old Kansas City tape >interface. It was primarily developed to allow a PIC to decode Caller ID >signals from a phone line but can be used for a variety of different >purposes. Ken, This is magic. Without looking too deeply it seems almost exactly what I was about to start researching for my next project. Phil Seakins. |