p IC 12C508 DTMF Dialer
; | Name: MAIN.ASM |
; | Description: DTMF -> RS232 converter (for use with PC NummerViser)|
; | Detects DTMF and ringing, and transmits to a std. |
; | RS232 port, at 2400 baud. |
; | | |
; +--------------------------------------------------------------------+
; | Platform: PIC12C508(A) (using internal 4MHz RC-oscillator) |
; | Uses: 90-342W/512W program-mem (all ’switches’ set to 0/1) |
; | 6B/25B data-mem |
; | Assembler: MPASM 2.20 (MPLAB 4.00.00) |
; | Comments: - |
; +====================================================================+
TITLE ’DTMF to RS232 converter’
PROCESSOR 12C508
__CONFIG _CP_OFF & _MCLRE_OFF & _IntRC_OSC & _WDT_ON
INCLUDE
RADIX DEC
__IDLOCS h’0104’
OTP SET 1 ;Use factory-stored cal.-value (on OneTimeProgrammable)
TMR0CLK SET 1 ;Use TMR0 external clock at 3,579545MHz (instead of IntRC).
PARITY SET 1 ;Use even parity-bit when transmitting to the serial port.
CLIONLY SET 1 ;Transmits CLI (A-numbers) only.
RING SET 1 ;Transmits ringing.
IDENTTX SET 1 ;Transmits ’ident’ when pressing ’***’ (DTMF).
PWRUPID SET 1 ;Transmits short ’ident’ at powerup.
ASCII SET 1 ;Transmits ASCII-chars instead of binary:
;Digit ASCII Binary Digit ASCII Binary
;0 0 (48d) 00000000 9 9 (57d) 00001001
;1 1 (49d) 00000001 A A (65d) 00001010
;2 2 (50d) 00000010 B B (66d) 00001011
;3 3 (51d) 00000011 C C (67d) 00001100
;4 4 (52d) 00000100 D D (68d) 00001101
;5 5 (53d) 00000101 * * (42d) 00001110
;6 6 (54d) 00000110 # # (35d) 00001111
;7 7 (55d) 00000111 Ring R (82d) 00010000
;8 8 (56d) 00001000
;---+++*** Constants ***+++---
IF TMR0CLK == 0 ;Internal oscillator
OPTION_REG equ b’10000001’ ;’Default’ timer/prescaler setup
ENDIF
IF TMR0CLK == 1 ;External TMR0 source (3,579545MHz)
OPTION_REG equ b’10100011’ ;’Default’ timer/prescaler setup
ENDIF
#define DTMF0 GPIO, 0 ;Bit0 (LSB) from MT8870
#define DTMF1 GPIO, 1 ;Bit1 from MT8870
#define DTMF2 GPIO, 3 ;Bit2 from MT8870 / _Ring-detector
#define DTMF3 GPIO, 4 ;Bit3 from MT8870 / TxD-output (high = sPACe)
#define DTMFOK GPIO, 5 ;DTMF detected, and ready at DTMF0-3
;---+++*** Variable declaration ***+++---
cblock 0Ch
DTMFval
identval
misc
temp1, temp2, teMP3 ;Temp-variables
endc
#define CLIP misc, 0 ;Set when CLIP detected
#define CLIPend misc, 1 ;Set by CLIPdet when # received
#define IdentOK misc, 2 ;Set when ’ident’ detected (***)
;---+++*** Reset vector ***+++---
ORG 0h
rst_vector:
MOVwf OSCCAL ;Set oscillator calibration.
call init
IF PWRUPID == 1
goto pwrupident
pwrupidentreturn:
ENDIF
goto main
;---+++*** Identity (located ’low’ because of no CP < 64b) ***+++---
identtable:
IF IDENTTX == 1
addwf PCL, F
dt " +++ PC NummerViser +++ ", 13
dt " Firmware v1.04 ", 13, 13
dt " JaCOB BlichfELDt ’98 ", 13, 13, 13, 0
ENDIF
pwrupidenttable:
IF PWRUPID == 1
addwf PCL, F
dt "DTMFTORS232", 60, "0104", 62, 0
ENDIF
;---+++*** Initialization ***+++---
init:
; Setup I/O-direction (GP0-3, 5 = input, GP4 = output)
MOVlw b’11101111’
tris GPIO
; TxD = Space (GP4 = low)
MOVlw b’00000000’
MOVwf GPIO
; Enable port B pull-up, dISAble wake-up on PIN change
; Setup T0 = inc. on either OSC. or TMR0, prescaler = 4/16 (depends on TMR0CLK)
clrwdt
MOVlw OPTION_REG
option
clrf misc
clrf identval
retlw 0
;---+++*** Power-up identity transmission ***+++---
IF PWRUPID == 1
pwrupident:
MOVlw 4 ;wait approx. 1 second
MOVwf temp3
pwrup11: clrf temp2
pwrup12 clrf temp1
pwrup13: clrwdt
decfsz temp1, F
goto pwrup13
decfsz temp2, F
goto pwrup12
decfsz temp3, F
goto pwrup11
MOVlw h’0FF’
MOVwf temp3
pwrup2: clrwdt
incf temp3, F
MOVf temp3, W
call pwrupidenttable ;Fetch text
clrf temp2
subwf temp2, F
btfsc STATUS, Z ;End of table?
goto pwrupend
call txser
goto pwrup2
pwrupend:
goto pwrupidentreturn
ENDIF
;---+++*** Main ***+++---
main: goto DTMFdet
DTMFdetreturn:
goto ringdet
ringdetreturn:
goto main ;Repeat main
; Read DTMF-bits from 8870, converts to nibble, and returns in W.
readDTMF:
MOVf GPIO, W
andlw b’00000011’ ;Get bit0-1
MOVwf DTMFval
bsf DTMFval, 2 ;Get bit 2
btfss DTMF2
bcf DTMFval, 2
MOVlw b’11111111’ ;Get bit 3 (DTMF3 = input)
bcf DTMFval, 3
tris GPIO
MOVlw b’11101111’
btfsc DTMF3
bsf DTMFval, 3
tris GPIO ;DTMF3 = Output
bcf DTMF3
MOVf DTMFval, W ;Convert from 8870 -> ’normal’
andlw b’00001111’
call DTMFtable
MOVwf DTMFval
retlw 0
DTMFtable:
addwf PCL, F
retlw b’00001101’ ;DTMF ’D’
retlw b’00000001’ ;DTMF ’1’
retlw b’00000010’ ;DTMF ’2’
retlw b’00000011’ ;DTMF ’3’
retlw b’00000100’ ;DTMF ’4’
retlw b’00000101’ ;DTMF ’5’
retlw b’00000110’ ;DTMF ’6’
retlw b’00000111’ ;DTMF ’7’
retlw b’00001000’ ;DTMF ’8’
retlw b’00001001’ ;DTMF ’9’
retlw b’00000000’ ;DTMF ’0’
retlw b’00001110’ ;DTMF ’*’
retlw b’00001111’ ;DTMF ’#’
retlw b’00001010’ ;DTMF ’A’
retlw b’00001011’ ;DTMF ’B’
retlw b’00001100’ ;DTMF ’C’
; Converts received DTMF to ASCII (returns in W)
conASCII:
IF ASCII == 1
addwf PCL, F
retlw A’0’
retlw A’1’
retlw A’2’
retlw A’3’
retlw A’4’
retlw A’5’
retlw A’6’
retlw A’7’
retlw A’8’
retlw A’9’
retlw A’A’
retlw A’B’
retlw A’C’
retlw A’D’
retlw A’*’
retlw A’#’
ENDIF
; Tests for 3 subsequent ’*’.
ident:
IF IDENTTX == 1
bcf IdentOK
MOVlw b’00001110’ ;DTMF ’*’
subwf DTMFval, W
btfss STATUS, Z
goto ident1
incf identval, F
MOVlw d’3’
subwf identval, W
btfss STATUS, Z
goto identend
bsf IdentOK
ident1: clrf identval
identend:
retlw 0
ENDIF
; Transmits W at 2400bps/std. RS232. Calculates parity-bit. Returns when done.
txser:
MOVwf temp1
bcf STATUS, C ;Transmit start-bit
call txcarry
MOVlw d’8’ ;Transmit 8 databits
MOVwf temp2
txbits: clrwdt
rrf temp1, F
call txcarry
decfsz temp2, F
goto txbits
IF PARITY == 1
rrf temp1, F ;calculate parity (even)
swapf temp1, W
xorwf temp1, W
MOVwf temp1
rrf temp1, F
rrf temp1, F
xorwf temp1, F
rrf temp1, W
xorwf temp1, F
bcf STATUS, C
btfsc temp1, 0
bsf STATUS, C
call txcarry
ENDIF
bsf STATUS, C ;Transmit 2*stop-bit
call txcarry
bsf STATUS, C
call txcarry
retlw 0
;transmit carry-flag
IF TMR0CLK == 0
txcarry:MOVlw (256-104) ;2400 = 416,666us = 1666,666c/16 = 104,17
ENDIF
IF TMR0CLK == 1
txcarry:MOVlw (256-93) ;2400 = 416,666us = 1491,477c/16 = 93,22
ENDIF
txndone:btfsc TMR0, 7 ;Last bit transmitted (TMR0 ovfl.)?
goto txndone
bsf DTMF3 ;Space
btfsc STATUS,C ;Set to mark (-12 V) if Carry = 1
;(RS232 inverts output)
bcf DTMF3 ;Mark
MOVwf TMR0
retlw 0
; Recognizes CLIP (DTMF received in A), and sets/clears CLIP.
IF CLIONLY == 1
CLIPdet:
MOVwf temp1
MOVlw b’00001010’ ;DTMF ’A’
subwf temp1, W
btfss STATUS, Z
goto CLIPdet2
bsf CLIP
goto CLIPdetend
CLIPdet2:MOVlw b’00001101’ ;DTMF ’D’
subwf temp1, W
btfss STATUS, Z
goto CLIPdet3
bsf CLIP
goto CLIPdetend
CLIPdet3:btfss CLIP
goto CLIPdetend
MOVlw b’00001111’ ;DTMF ’#’
subwf temp1, W
btfss STATUS, Z
goto CLIPdetend
bcf CLIP
bsf CLIPend
CLIPdetend:
retlw 0
ENDIF
; DTMF-detection - Calls readDTMF, CLIPdet, conASCII and txser if DTMF is present.
; Returns when DTMF is reMOVed.
DTMFdet:clrwdt
btfss DTMFOK
goto DTMFdetreturn
goto $+1 ;Double nop
btfss DTMFOK
goto DTMFdetreturn
call readDTMF ;DTMF present, read!
IF IDENTTX == 1 ;Transmit ident if ’***’ received
call ident
btfss IdentOK
goto DTMFdet2
MOVlw h’0FF’
MOVwf temp3
DTMFdet1:clrwdt
incf temp3, F
MOVf temp3, W
call identtable ;Fetch text
clrf temp2
subwf temp2, F
btfsc STATUS, Z ;End of table?
goto DTMFdet2
call txser
goto DTMFdet1
ENDIF
DTMFdet2:
MOVf DTMFval, W
IF CLIONLY == 1 ;Transmit only CLI
call CLIPdet
btfss CLIPend ;Last digit in CLI (#)?
goto DTMFdet21
bcf CLIPend
goto DTMFdet22
DTMFdet21:
btfss CLIP
goto DTMFoff
DTMFdet22:
MOVf DTMFval, W
ENDIF
IF ASCII == 1 ;Convert to ASCII
MOVf DTMFval, W
call conASCII
ENDIF
call txser ;Transmit to serial port
DTMFoff:clrwdt ;Wait for DTMF to stop
btfsc DTMFOK
goto DTMFoff
DTMFend:goto DTMFdetreturn
; Ring-detection - If ringing is present, calls txser with W = (ascii) ’R’.
; Returns when ringing ends or DTMF is present.
ringdet:clrwdt
IF RING == 1
btfsc DTMF2
goto ringend
ringdet2: ;Wait for ringing-pulse to
clrwdt ;stop (or DTMF present).
btfsc DTMFOK
goto ringend
btfss DTMF2
goto ringdet2
MOVlw b’10000111’ ;Setup timer: 50ms before overflow.
option
MOVlw d’50’
MOVwf TMR0
ringdet3:clrwdt ;Wait for new ringing-pulse
MOVlw 0
subwf TMR0, W
btfsc STATUS, Z
goto ringend
btfsc DTMF2
goto ringdet3
;New pulse present.
MOVlw OPTION_REG ;Restore old prescaler
option
MOVlw A’R’ ;Transmit ’R’
call txser
bcf CLIP ;Terminate CLIP-sequence (ring det.)
MOVlw b’10000111’ ;Setup timer: 50ms before overflow.
option
ringdet4:MOVlw d’50’
MOVwf TMR0
ringdet5:clrwdt ;Wait for ringing to end
btfss DTMF2
goto ringdet4
MOVlw 0
subwf TMR0, W
btfsc STATUS, Z
goto ringend
btfss DTMFOK
goto ringdet5
ringend: MOVlw OPTION_REG ;Restore old prescaler
option
ENDIF
goto ringdetreturn
IF OTP == 0
ORG h’1FF’ ;(old 12C508 calibration-val.)
MOVlw h’0A0’
ENDIF
END
+---------------------------------------------------------------------+
| History |
+---------------------------------------------------------------------+
Rev. Change Reason Date
--------------------------------------------------------------------------------
0.0a Source-file created. - 24.03.98
0.5a Hierarchisch diagram finished. - 25.03.98
1.0a Everything implemented, ready for test. - 26.03.98
1.0b Tested in ’real life’... Everything ok, - 27.03.98
(minor bugs reMOVed).
1.0 First version, ’in use’. - 27.03.98
1.01 Fixed ’#’ not transmitted when CLIP=1. - 29.03.98
Fixed ’D’-sequences not recognized as
CLIP (not transmitted when CLIP=1).
Implemented PwrUpIdent. Gives possibility of
auto-detection, and
FW-version detection.
1.02 Implemented possibility of using ext. More precise than 09.04.98
TMR0 source, as timebase for RS232- internal RC-oscillator.
communication.
Bugfixed CLIPdet. ASCII-table located in
upper page when all
switches = 1.
1.03r +++ First ’public’ release. +++ In case the CLI- 02.05.98
Break CLIP-sequence if ring detected. sequence is not termi-
nated probably (because
of linenoise etc.)
1.04r Minor changes/bugfixes: 18.03.99
Changed TX-timing. Transmitted at ~2325bps.
Changed format from 8E1 to 8E2 Enables receiver to re-
(2 stopbits). syncronize between each
byte, thereby supressing
framing-errors.
Minimized ’read-DTMF’ timing. ReMOVes unwanted 10us
glitch on TX just before
transmitting a digit.
Ideas/future changes:
-------------------------------------------------------------------------------
Add EEPROM and change power-supply, to enable reception/storing of DTMF, when
the PC is turned off.
Add offhook detector, to enable ’length of conversation’, and ’answered/not
answered call’ logging.
Previous article:Infrared remote control receiving program made by PIC
Next article:pic16f874 stepper motor program
Recommended ReadingLatest update time:2024-11-17 14:25
- Popular Resources
- Popular amplifiers
- Digital Signal Processing Theory and Applications 3rd Edition (by Yu Yibiao)
- Example interpretation of 51 single chip microcomputer complete learning and application
- Digital Signal Processing: Theory and Applications (3rd Edition) (Yu Yibiao and Sun Bing)
- Example interpretation of 51 single chip microcomputer complete learning and application
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- [National Technology N32 Bluetooth chip development package] --N32WB03x series
- ESD
- Watch the video to win a 50-yuan Jingdong card | Taixiang's actual test of Shui Ge's secrets, the fourth issue
- Analysis of millimeter wave terminal technology and test solutions
- Have you seen it? The heat sink symbol in the schematic diagram
- [Raspberry Pi Pico Review]——by fxyc87
- What issues regarding antenna isolation should we pay attention to?
- A Brief Analysis of UWB Ultra-Wideband Indoor Positioning Technology
- What is the special purpose of inductors wound with silk wire?
- Analysis of mixers and modulators for high-speed communications