' Name : GRABRXT.pbp ' Compiler : PICBASIC PRO Compiler 2.6 ' Assembler : PM or MPASM ' Target PIC : PIC16F877-20 ' Hardware : LAB-XT Experimenter Board ' Oscillator : 20MHz external ' Keywords : LCDOUT, LOOKUP ' Description : PICBASIC PRO program for simple DTMF digit-grabber that ' monitors for DTMF on a telephone line and displays any digits received. ' Tracks display position and wraps to first position on new line. ' Press RESET to clear display. ' ' Connect the LAB-XT in series, phone to J3 and line to J4. Define LOADER_USED 1 ' Only required for melabs Loader Define OSC 20 ' Match the crystal on the board ' Define LCD registers and bits Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 led4 Var PORTC.1 ' LED indicator output dtmf_ready Var PORTA.4 ' Ready input from MT8870 select_dtmf Var PORTD.3 ' Enable output to MT8870 dtmf_digit Var Byte ' Stores most recent DTMF digit lcd_position Var Byte ' Stores LCD cursor position (character) lcd_line Var Bit ' Stores LCD cursor position (line) ADCON1 = 7 ' Set PORTA and PORTE to digital TRISD = 0 ' Set all pins on PORTD to output PORTD = 0 Pause 200 ' Wait for LCD to start up lcd_position = 1 ' Set LCD position variable to first character lcd_line = 0 ' Set LCD line variable to first line LCDOut $fe,1 ' Clear display, cursor to line 1 home mainloop: IF dtmf_ready = 0 Then mainloop ' Check for DTMF present, if none loop again ' If DTMF present, continue High led4 ' Light LED while DTMF signal present select_dtmf = 1 ' Enable the data output from the MT8870 Pause 1 ' Pause 1 mS to let data settle dtmf_digit = (PORTB >> 4) ' Read the top nibble of PORTB for DTMF data ' Use LOOKUP to change the DTMF data to an ASCII character LookUp dtmf_digit, ["_1234567890*#ABCD"], dtmf_digit dtmf_wait: IF dtmf_ready Then dtmf_wait ' Loop here until DTMF signal stops select_dtmf = 0 ' Disable the MT8870 data output Low led4 ' Shut off LED (no DTMF present) ' Check the LCD cursor position IF lcd_position > 20 Then ' If the cursor is past the end of a line: lcd_position = 1 ' Set cursor position variable to character 1 lcd_line = ~lcd_line ' Move cursor line variable to the other line ' Move the cursor on the display to match variables IF lcd_line Then LCDOut $fe,$C0 ' Move cursor to line 2, character 1 Else LCDOut $fe,2 ' Move cursor to line 1, character 1 EndIF EndIF LCDOut dtmf_digit ' Send the DTMF character to the LCD lcd_position = lcd_position + 1 ' Increment the position variable GoTo mainloop ' Do it forever End