TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Mako22 en 13 de Febrero de 2004, 09:29:00
-
Podría hacer alguien el fabor de pasarme el siguiente fichero a HEX para introducirlo en un 16F84.
A mi me da errores cuando intento pasarlo con el Mpasmwin, y no se por que es. Mis conocimientos no llegan ya que soy novato.
Gracias de antemano.
;*****************************************************************************
;
; This program reads the Philips RC5 remote control codes from a
; handheld infrared remote control, and displays the decoded
; data words on an LCD.
;
; IMPORTANT NOTE: This code may be used for private purposes only.
; Anyone contemplating commercial use of this code should check
; with Philips Corporation for possible limitations and
; restrictions on the use of their RC5 remote control code format.
;
; The interface works with a Hitachi HD66702- or 44780-based LC-Display
; This is a 2 line * 20 characters display module.
;
; Program READRC5.ASM
; Last update SEPT. 15, 1996
; Author Brian Aase
; Thanks to Peer Ouwehand for the enhanced LCD driver routines and demo code.
;
;*****************************************************************************
;Mod info: This version assumes RA3 idling at high level so that Sharp
;IR pickup can be connected directly.
;
;*****************************************************************************
; Fosc = 4MHz
; Cycle_time = 1/Fosc / 4
; = 1/(4*10^6) / 4
; = 1uSec
;*****************************************************************************
LIST P=16C84
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
RADIX DEC
include <c:mplabp16c84.inc>
;*****************************************************************************
; Equates, I/O, vars
;*****************************************************************************
RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt Vector
OSC_FREQ EQU D"4000000" ; Oscillator Frequency is 4 MHz
LCD_DATA EQU PORTB ; LCD data lines interface
LCD_DATA_TRIS EQU TRISB
LCD_CTRL EQU PORTA ; LCD control lines interface
LCD_LINE0 EQU 0x000
LCD_LINE1 EQU 0x040
LCD_LINE2 EQU 0x014
LCD_LINE3 EQU 0x054
; PORTA bits
DATA_IN EQU 3 ; Input data from IR pickup
LCD_E EQU 2 ; LCD Enable control line
LCD_RW EQU 1 ; LCD Read/Write control line
LCD_RS EQU 0 ; LCD Register-Select control line
; PORTB bits
DB7 EQU 7 ; LCD dataline 7 (MSB)
DB6 EQU 6 ; LCD dataline 6
DB5 EQU 5 ; LCD dataline 5
DB4 EQU 4 ; LCD dataline 4
DB3 EQU 3 ; LCD dataline 3
DB2 EQU 2 ; LCD dataline 2
DB1 EQU 1 ; LCD dataline 1
DB0 EQU 0 ; LCD dataline 0 (LSB)
; misc.
#DEFINE RAMstart 0x0C ; For 16C84
LCD_TEMP EQU RAMstart ; LCD subroutines internal use
COUNT EQU RAMstart+1 ; A counter, used multiple places
DELAY EQU RAMstart+2 ; Used in DELAYxxx routines
X_DELAY EQU RAMstart+3 ; Used in X_DELAYxxx routines
TOGGLE EQU RAMstart+4 ; The RC5 Toggle bit
SYSTEM EQU RAMstart+5 ; The RC5 System word
COMND EQU RAMstart+6 ; The RC5 Command word
MZDATA EQU RAMstart+7 ; The RC5 extra Data word
POINTER EQU RAMstart+8 ; Used in TABLE_MSG subroutine
ASCII_O EQU RAMstart+9 ; ASCII One"s digit to print
ASCII_T EQU RAMstart+10 ; ASCII Ten"s digit to print
ASCII_H EQU RAMstart+11 ; ASCII Hundred"s digit to print
BIT_COUNT EQU RAMstart+12 ; Counter for incoming bits
BYTE_COUNT EQU RAMstart+13 ; Counter for buffer bytes
TEMP EQU RAMstart+14 ; Used by PARSE to hold the 2-bit pattern
SERIAL_BUF EQU RAMstart+15 ; Buffer for incoming bitstream
SERIAL_2 EQU RAMstart+16
SERIAL_3 EQU RAMstart+17
SERIAL_4 EQU RAMstart+18
SERIAL_5 EQU RAMstart+19
SERIAL_6 EQU RAMstart+20
FIELD EQU RAMstart+21 ; Temporary storage for field bit
PARSE_FLAGS EQU RAMstart+22 ; DECODE returns its data in this
MZ_FLAG EQU RAMstart+23 ; Set if there is an extra data word
; in the bitstream
w EQU 0
f EQU 1
ONE EQU B"00000001" ; 2-bit incoming pattern matches
ZERO EQU B"00000010"
;*****************************************************************************
; Program start
;*****************************************************************************
ORG RESET_V ; RESET vector location
RESET GOTO START
;*****************************************************************************
; This is the Periperal Interrupt routine. Should NOT get here
;*****************************************************************************
ORG ISR_V ; Interrupt vector location
INTERRUPT BCF STATUS, RP0 ; Select bank 0
GOTO INTERRUPT
;=============================================================================
; Table message to display: kept right up front to avoid crossing 0xff boundary
;=============================================================================
TABLE_ST MOVWF PCL
MSG_T RETLW "T"
RETLW "O"
RETLW "G"
RETLW " "
RETLW "="
RETLW " "
RETLW 0x00
MSG_S RETLW "S"
RETLW "Y"
RETLW "S"
RETLW "T"
RETLW "E"
RETLW "M"
RETLW " "
RETLW "="
RETLW " "
RETLW 0x00
MSG_C RETLW "C"
RETLW "O"
RETLW "M"
RETLW "N"
RETLW "D"
RETLW " "
RETLW "="
RETLW " "
RETLW 0x00
MSG_D RETLW "D"
RETLW "A"
RETLW "T"
RETLW "A"
RETLW " "
RETLW "="
RETLW 0x00
MSG_Y RETLW "D" ; Place your debug messages here
RETLW "E"
RETLW "B"
RETLW "U"
RETLW "G"
RETLW " "
RETLW "M"
RETLW "E"
RETLW "S"
RETLW "S"
RETLW "A"
RETLW "G"
RETLW "E"
RETLW " "
RETLW "1"
RETLW 0x00
MSG_Z RETLW "M"
RETLW "E"
RETLW "S"
RETLW "S"
RETLW "A"
RETLW "G"
RETLW "E"
RETLW " "
RETLW "2"
TABLE_END RETLW 0X00
IF ( (TABLE_ST & 0x0FF) >= (TABLE_END & 0x0FF) )
MESSG "Warning - Message table "TABLE_ST" crosses page boundary"
ENDIF
;*****************************************************************************
; Initialize processor registers
;*****************************************************************************
START ; POWER_ON Reset (Beginning of program)
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
CLRF PCLATH ; Keep in lower 2KByte
CLRF PORTA ; ALL PORT outputs should output Low.
CLRF PORTB
BSF STATUS, RP0 ; Select bank 1
MOVLW 0x0F8 ; RA2-0 outputs, RA5-3 inputs
MOVWF TRISA
MOVLW 0x000 ; RB7-0 outputs
MOVWF TRISB
MOVLW B"11010001" ; Option register setup:
; No RB Pullups
; TMR0 fed from internal clock
; Assign prescaler to TMR0
; use 1:4 prescaling ratio
MOVWF OPTION_REG
BCF STATUS, RP0 ; Select bank 0
CALL LCDINIT ; Initialize LCDisplay
;***************************************************************************
; Look at RA4 to invoke debug routine instead of regular program
;***************************************************************************
POLL_RA4 BTFSS PORTA,4
GOTO POLL_RA3 ; Start regular program if RA4 is low
MOVLW LCD_LINE0 ;
CALL LCDSDDA ; Set to first line
MOVLW MSG_Y ; Point to first message string
CALL TABLE_MSG ; Display it
MOVLW LCD_LINE1 ;
CALL LCDSDDA ; Set to second line
MOVLW MSG_Z ; Point to next message string
CALL TABLE_MSG ; Display it
DB_LOOP GOTO DB_LOOP ; Hang here forever
;***************************************************************************
; When power is applied, wait for data on RA3 before proceeding
; Remember the Sharp IR pickup has an active-low output
;***************************************************************************
POLL_RA3 BTFSC PORTA, DATA_IN ; The pickup module has inverse logic
GOTO POLL_RA3 ; High is idle, low is active
MOVLW D"147" ; Found data, load timer for 444 uS
; minus 11 overhead = 433 cycles
; 255-147=108 counts x 4 prescaled
MOVWF TMR0 ; Which creates a 1/4 bit wait
BCF INTCON,T0IF ; Clear timer overflow flag
BCF STATUS,C ; Initialize the carry flag
CALL READ ; Read the data stream
BTFSC STATUS,C ; Carry flag set means bogus data
GOTO POLL_RA3 ; Start over if bad datastream
CALL PARSE ; Parse the data
BTFSC STATUS,C ; Carry flag set means no success
GOTO POLL_RA3 ; Start over if bad parse
;*****************************************************************************
; Display the data we gathered
;
;*****************************************************************************
MOVLW LCD_LINE0 ; 0x00
CALL LCDSDDA ; Position cursor leftmost on first line
MOVLW MSG_T ; Point to Toggle message
CALL TABLE_MSG ; Display message
MOVF TOGGLE,w ; Load the toggle bit to display
MOVWF ASCII_O ; Send data to conversion routine
CALL HEX_TO_ASC ; Convert to ascii
MOVF ASCII_O,w ; Ones digit is in ascii_o
CALL LCDPUTCHAR ; Display toggle data
MOVLW LCD_LINE0 + 0x009 ; Position 9
CALL LCDSDDA ; Position cursor
MOVLW MSG_S ; Point to System message
CALL TABLE_MSG ; Display message
MOVF SYSTEM,w ; Load the system byte to display
MOVWF ASCII_O ; Send data to conversion routine
CALL HEX_TO_ASC ; Convert to ascii
MOVF ASCII_T,w ; Tens digit
CALL LCDPUTCHAR ; Display it
MOVF ASCII_O,w ; Ones digit
CALL LCDPUTCHAR ; Display it
MOVLW LCD_LINE1 ; 0x40
CALL LCDSDDA ; Set cursor leftmost on line 2
MOVLW MSG_C ; Point to Command message
CALL TABLE_MSG ; Display the message
MOVF COMND,w ; Load the command byte to display
MOVWF ASCII_O ; Send data to conversion routine
CALL HEX_TO_ASC ; Convert to ascii
MOVF ASCII_H,w ; Hundreds digit
CALL LCDPUTCHAR ; Display it
MOVF ASCII_T,w ; Tens digit
CALL LCDPUTCHAR ; Display it
MOVF ASCII_O,w ; Ones digit
CALL LCDPUTCHAR ; Display it
MOVLW LCD_LINE1 + 0x00C ; Position 12
CALL LCDSDDA ; Set cursor
MOVLW MSG_D ; Point to Data message
CALL TABLE_MSG ; Display the message
BTFSS MZ_FLAG,0 ; Is there a data word to display?
GOTO NO_DATA ; No
MOVF MZDATA,w ; Load the data byte to display
MOVWF ASCII_O ; Send data to conversion routine
CALL HEX_TO_ASC ; Convert to ascii
MOVF ASCII_T,w ; Tens digit
CALL LCDPUTCHAR ; Display it
MOVF ASCII_O,w ; Ones digit
CALL LCDPUTCHAR ; Display it
GOTO POLL_RA3 ; Wait for incoming again
NO_DATA MOVLW " " ; Print spaces instead of data value
CALL LCDPUTCHAR
MOVLW " "
CALL LCDPUTCHAR
GOTO POLL_RA3 ; Wait for incoming again
;*****************************************************************************
; Main program ends here
;
;*****************************************************************************
;*****************************************************************************
; Send a message using a table to output the message
;
;*****************************************************************************
TABLE_MSG
MOVWF POINTER ; Point to the first char. we want
LOOP_WR
MOVFW POINTER ; Renew the pointer
CALL TABLE_ST ; Initiate table lookup
XORLW 0x00 ; Is this the terminating char?
BTFSC STATUS,Z
GOTO END_WR
CALL LCDPUTCHAR ; Actually put the char on display
INCF POINTER,f ; Point to the next char
GOTO LOOP_WR ; Do next character
END_WR
RETURN
;*****************************************************************************
; LCD Module Subroutines
;*****************************************************************************
;
;=============================================================================
; LCDINIT
; Initilize LC-Display Module
; This code sets up the Optrex DMC50218 (2x20)
;=============================================================================
LCDINIT
; Busy-flag is not yet valid
CLRF LCD_CTRL ; ALL PORT output should output Low.
; power-up delay
MOVLW 0x01E
CALL X_DELAY500 ; 30 * 0.5mS = 15mS
; Busy Flag should be valid from here
MOVLW 0x038 ; 8-bit-interface, 2-lines
CALL LCDPUTCMD
MOVLW 0x000 ; disp.off, curs.off, no-blink
CALL LCDDMODE
CALL LCDCLEAR
MOVLW 0x004 ; disp.on, curs.off
CALL LCDDMODE
MOVLW 0x002 ; auto-inc (shift-cursor)
CALL LCDEMODE
RETURN
;=============================================================================
; LCD_ENABLE
; Pulses LCD enable pin
;=============================================================================
LCD_ENABLE
BSF LCD_CTRL, LCD_E ; LCD E-line High
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;=============================================================================
; LCDBUSY
; Returns when LCD busy-flag is inactive
;=============================================================================
LCDBUSY
BSF STATUS,RP0 ; Select Register page 1
MOVLW 0x0FF ; Set PORTB for input
MOVWF LCD_DATA_TRIS
BCF STATUS, RP0 ; Select Register page 0
BCF LCD_CTRL, LCD_RS; Set LCD for command mode
BSF LCD_CTRL, LCD_RW; Setup to read busy flag
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_DATA, W ; Read busy flag + DDram address
BCF LCD_CTRL, LCD_E ; LCD E-line Low
ANDLW 0x80 ; Check Busy flag, High = Busy
BTFSS STATUS, Z
GOTO LCDBUSY
LCDNOTBUSY BCF LCD_CTRL, LCD_RW
BSF STATUS, RP0 ; Select Register page 1
MOVLW 0x000
MOVWF LCD_DATA_TRIS ; Set PORTB for output
BCF STATUS, RP0 ; Select Register page 0
RETURN
;=============================================================================
; LCDCLEAR
; Clears display and returns cursor to home position (upper-left corner).
;=============================================================================
LCDCLEAR
MOVLW 0x001
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDHOME
; Returns cursor to home position.
; Returns display to original position (when shifted).
;=============================================================================
LCDHOME
MOVLW 0x002
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDEMODE
; Sets entry mode of display.
; Required entry mode must be set in W
; b0 : 0 = no display shift 1 = display shift
; b1 : 0 = auto-decrement 1 = auto-increment
; b2-7 : don"t care
;=============================================================================
LCDEMODE
ANDLW 0x003 ; Strip upper bits
IORLW 0x004 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDDMODE
; Sets display control.
; Required display mode must be set in W
; b0 : 0 = cursor blink off 1 = cursor blink on
; b1 : 0 = cursor off 1 = cursor on
; b2 : 0 = display off 1 = display on (display data remains in DDRAM)
; b3-7 : don"t care
;=============================================================================
LCDDMODE
ANDLW 0x007 ; Strip upper bits
IORLW 0x008 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDSCGA
; Sets Character-Generator-RAM address. CGRAM is read/written after
; this setting.
; Required CGRAM address must be set in W
; b0-5 : required CGRAM address
; b6-7 : don"t care
;=============================================================================
LCDSCGA
ANDLW 0x03F ; Strip upper bits
IORLW 0x040 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDSDDA
; Sets the Display-Data-RAM address. DDRAM data is read/written after
; this setting.
; Required DDRAM address must be set in W
; b0-6 : required DDRAM address
; b7 : don"t care
;=============================================================================
LCDSDDA
IORLW 0x080 ; Function set
CALL LCDPUTCMD
RETURN
;=============================================================================
; LCDGADDR
; Returns address counter contents, used for both DDRAM and CGRAM.
; RAM address is returned in W
;=============================================================================
LCDGADDR
BSF STATUS,RP0 ; Select Register page 1
MOVLW 0x0FF ; Set PORTB for input
MOVWF LCD_DATA_TRIS
BCF STATUS, RP0 ; Select Register page 0
BCF LCD_CTRL, LCD_RS; Set LCD for command mode
BSF LCD_CTRL, LCD_RW; Setup to read busy flag
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_DATA, W ; Read busy flag + RAM address
BCF LCD_CTRL, LCD_E ; LCD E-line Low
ANDLW 0x07F ; Strip upper bit
BCF LCD_CTRL, LCD_RW
BSF STATUS, RP0 ; Select Register page 1
MOVLW 0x000
MOVWF LCD_DATA_TRIS ; Set PORTB for output
BCF STATUS, RP0 ; Select Register page 0
RETURN
;=============================================================================
; LCDPUTCHAR
; Sends character to LCD
; Required character must be in W
;=============================================================================
LCDPUTCHAR
MOVWF LCD_TEMP ; Character to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BSF LCD_CTRL, LCD_RS; Set LCD in data mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;=============================================================================
; LCDPUTCMD
; Sends command to LCD
; Required command must be in W
;=============================================================================
LCDPUTCMD
MOVWF LCD_TEMP ; Command to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;*****************************************************************************
; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; i.e. (@ 4MHz crystal)
; Delay_time = ((32 * 3) + 4) * 1uSec
; = 100uSec
; DELAY_value = (500uSec - 4) / 3
; = 165.33
; = 165
;*****************************************************************************
DELAY500 MOVLW D"165" ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
DELAY500_END RETURN ; +3 2 cycles
;
;
X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
X_DELAY500_END RETURN ; +2 2 cycles
;===========================================================================
; HEX_TO_ASC .. Converts a hex digit to three ASCII characters
; Enter with the hex digit in ASCII_O
; Exit with Hundreds ascii digit in ASCII_H,
; Tens ascii digit in ASCII_T,
; and Ones ascii digit in ASCII_O.
; The incoming byte is not preserved.
;===========================================================================
HEX_TO_ASC MOVLW "0" ; Preload a zero into 10"s & 100"s
MOVWF ASCII_T
MOVWF ASCII_H
DO_100s MOVLW D"100"
SUBWF ASCII_O,w ; Subtract 100 to test size
BNC DO_10s ; It"s less than 100, so branch
MOVWF ASCII_O ; It was bigger, so decrement it
INCF ASCII_H,f ; Bump up the 100"s digit
GOTO DO_100s ; Loop again till < 100
DO_10s MOVLW D"10"
SUBWF ASCII_O,w ; Subtract 10 to test size
BNC ADJUST ; It"s less than 10, so branch
MOVWF ASCII_O ; It was bigger, so decrement it
INCF ASCII_T,f ; Bump up the 10"s digit
GOTO DO_10s ; Loop again till < 10
ADJUST MOVLW "0" ; The # in ASCII_O is now < 10
ADDWF ASCII_O,f ; Turn it into an ASCII character
BLANK_ZEROS MOVLW "0"
XORWF ASCII_H,w ; Is the 100"s char a 0?
BTFSS STATUS,Z
GOTO HEX_DONE ; No.
MOVLW " " ; Yes,
MOVWF ASCII_H ; So replace it with a space.
MOVLW "0"
XORWF ASCII_T,w ; Is the 10"s char a 0?
BTFSS STATUS,Z
GOTO HEX_DONE ; No.
MOVLW " " ; Yes,
MOVWF ASCII_T ; So replace it with a space
HEX_DONE RETURN
;****************************************************************************
;READ .. reads the incoming data stream and saves it into a 6-byte buffer
; Remember again that the IR pickup output is active low
;****************************************************************************
READ ; First, zero all storage
MOVLW SERIAL_BUF ; Start of RAM buffer
MOVWF FSR ; Load indirect register
RD_LOOP1 CLRF INDF ; Zero out the buffer
INCF FSR,f ; Increment to next byte
MOVLW SERIAL_BUF+6 ; Test for 6 bytes done
XORWF FSR,w
BTFSS STATUS,Z
GOTO RD_LOOP1 ; Loop till done
CLRF BIT_COUNT
CLRF BYTE_COUNT
MOVLW SERIAL_BUF ; Reset the indirect pointer back
MOVWF FSR ; to the start of the buffer space
RD_LOOP2 BTFSS INTCON, T0IF ; Wait till timer goes 444 Usec
GOTO RD_LOOP2
CALL RESTART_TMR0 ; Reset timer for 888 uSec
BTFSC PORTA,3 ; Check RA3 signal (i.e. debounce)
GOTO BAD_DATA ; If it"s high (logic 0), bail out
RD_LOOP3 BTFSS INTCON, T0IF ; Wait till timer goes 888 uSec
GOTO RD_LOOP3
CALL RESTART_TMR0 ; Restart 888 uSec timer
INCF BIT_COUNT,f
MOVLW D"43" ; See if we"ve done all 42 bits
XORWF BIT_COUNT,w
BTFSC STATUS,Z
GOTO RD_FINISH ; We"ve done all 42 bits
BSF STATUS,C ; Preset the carry bit
BTFSC PORTA,3 ; Test RA3
BCF STATUS,C ; Input bit is high (logic 0) so change carry
; Now the input bit is in the carry flag
RLF INDF,f ; Rotate it into the buffer
INCF BYTE_COUNT,f ;
BTFSC BYTE_COUNT,3 ; See if all 8 bits are filled
CALL NEXT_BYTE ; Yes, use next buffer byte
GOTO RD_LOOP3 ; Loop back & do the rest of the bits
RD_FINISH BCF STATUS,C ;
RLF INDF,f ; The last buffer byte has only 2
RLF INDF,f ; bits loaded.
RLF INDF,f ; So we shift them up to the top
RLF INDF,f ; the hard way.
RLF INDF,f
RLF INDF,f
BCF STATUS,C ; Clear carry to show a successful capture
RETURN
;****************************************************************************
;NEXT_BYTE .. Increment the FSR and clear the counter
;
;****************************************************************************
NEXT_BYTE INCF FSR,f
CLRF BYTE_COUNT
RETURN
;****************************************************************************
;RESTART_TMR0 .. Restart the timer with an 888 uSec delay
; and refresh the overflow flag.
; MPLAB stopwatch says there is a loop overhead of
; 14 cycles, thus we need it to run for 888-14=874 uSec
;****************************************************************************
RESTART_TMR0
BCF INTCON, T0IF ; Clear the overflow flag
MOVLW D"37" ; 255 - 37 = 218 x 4 = 872 uSec
MOVWF TMR0
RETURN
;****************************************************************************
;PARSE .. decodes the saved datastream into the various
; RC5 words and flags.
;****************************************************************************
PARSE
MOVLW SERIAL_BUF ; Put buffer start address into
MOVWF FSR ; the FSR
CLRF TEMP ; Initialize variables
CLRF BYTE_COUNT ;
CLRF MZ_FLAG ;
CLRF FIELD ;
CLRF TOGGLE ;
CLRF SYSTEM ;
CLRF COMND ;
CLRF MZDATA ;
; First one is the field bit
RLF INDF,f ; First bit into carry
RLF TEMP,f ; Put it into TEMP for decoding
RLF INDF,f ; Second bit
RLF TEMP,f ; ditto
INCF BYTE_COUNT,f ; Start keeping track of INDF bit position
CALL DECODE
BTFSC PARSE_FLAGS,2 ; Illegal pattern found
GOTO BAD_DATA
; Must have found a good bit
RRF PARSE_FLAGS,f ; Put field bit into Carry
RLF FIELD,f ; Move it into FIELD
CLRF TEMP ; Next one is the toggle bit
RLF INDF,f ; First bit into carry
RLF TEMP,f ; Put it into TEMP for decoding
RLF INDF,f ; Second bit
RLF TEMP,f ; ditto
INCF BYTE_COUNT,f ; keep track of INDF bit position
CALL DECODE
BTFSC PARSE_FLAGS,2 ; Illegal pattern found
GOTO BAD_DATA
; Must have found a good bit
RRF PARSE_FLAGS,f ; Put toggle bit into Carry
RLF TOGGLE,f ; Move it into TOGGLE
MOVLW 0x05 ; Next one is the system byte, 5 bits
MOVWF COUNT
SYS_1 CLRF TEMP
RLF INDF,f ; First bit into carry
RLF TEMP,f ; Put it into TEMP for decoding
RLF INDF,f ; Second bit
RLF TEMP,f ; ditto
INCF BYTE_COUNT,f ; keep track of INDF bit position
BTFSC BYTE_COUNT,2 ; (there are two rotates per count)
CALL NEXT_BYTE ; Go to next buffer byte when count=4
CALL DECODE
BTFSC PARSE_FLAGS,2 ; Illegal pattern found
GOTO BAD_DATA
; Must have found a good bit
RRF PARSE_FLAGS,f ; Put bit into Carry
RLF SYSTEM,f ; Move it into SYSTEM
DECFSZ COUNT,f ; Have we done all 5 bits?
GOTO SYS_1 ; No, not yet
; Here we test for the two spaces
; present in the extended data format.
; If they appear, we set a flag
; and skip over them to the command
; word.
MOVLW B"11000000" ; Mask for 2nd buffer byte
ANDWF SERIAL_2,w ; Are the 2 top bits zero?
BTFSS STATUS,Z ;
GOTO PHILIPS ; No space found
CALL NEXT_BYTE ; Skip over first space
RLF INDF,f ; Skip over second space
RLF INDF,f ;
INCF BYTE_COUNT,f
MOVLW 0x01
MOVWF MZ_FLAG ; Set the flag
PHILIPS MOVLW 0x06 ; Next one is the command byte, 6 bits
MOVWF COUNT
CMD_1 CLRF TEMP
RLF INDF,f ; First bit into carry
RLF TEMP,f ; Put it into TEMP for decoding
RLF INDF,f ; Second bit
RLF TEMP,f ; ditto
INCF BYTE_COUNT,f ; keep track of INDF bit position
BTFSC BYTE_COUNT,2 ; (there are two rotates per count)
CALL NEXT_BYTE ; Go to next buffer byte when count=4
CALL DECODE
BTFSC PARSE_FLAGS,2 ; Illegal pattern found
GOTO BAD_DATA
; Must have found a good bit
RRF PARSE_FLAGS,f ; Put bit into Carry
RLF COMND,f ; Move it into COMND
DECFSZ COUNT,f ; Have we done all 6 bits?
GOTO CMD_1 ; No, not yet
BTFSS FIELD,0 ; If field bit=0 then comnd=comnd+64
BSF COMND,6
BTFSC MZ_FLAG,0 ; Test for extra data word
GOTO MDAT_1 ; Parse extra data word
RETURN ; Finish here if Philips format
MDAT_1 MOVLW 0x06 ; Next one is the data byte, 6 bits
MOVWF COUNT
MDAT_2 CLRF TEMP
RLF INDF,f ; First bit into carry
RLF TEMP,f ; Put it into TEMP for decoding
RLF INDF,f ; Second bit
RLF TEMP,f ; ditto
INCF BYTE_COUNT,f ; keep track of INDF bit position
BTFSC BYTE_COUNT,2 ; (there are two rotates per count)
CALL NEXT_BYTE ; Go to next buffer byte when count=4
CALL DECODE
BTFSC PARSE_FLAGS,2 ; Illegal pattern found
GOTO BAD_DATA
; Must have found a good bit
RRF PARSE_FLAGS,f ; Put bit into Carry
RLF MZDATA,f ; Move it into MZDATA
DECFSZ COUNT,f ; Have we done all 6 bits?
GOTO MDAT_2 ; No, not yet
PARSE_DONE RETURN
;****************************************************************************
; DECODE .. enter with two-bit data in TEMP
; return with result code in PARSE_FLAGS, thus
; PARSE_FLAGS<0> = valid data, one or zero
; PARSE_FLAGS<1> = unused
; PARSE_FLAGS<2> = set if data is invalid
;****************************************************************************
DECODE
CLRF PARSE_FLAGS
MOVLW ONE
XORWF TEMP,w ; Compare to bit pattern "01"
BZ ONE_EXIT
MOVLW ZERO
XORWF TEMP,w ; compare to bit pattern "10"
BZ ZERO_EXIT
BAD_EXIT BSF PARSE_FLAGS,2 ; bit pattern neither 01 nor 10
RETURN
ONE_EXIT BSF PARSE_FLAGS,0 ; Return with valid data in LSB
ZERO_EXIT RETURN ; of the PARSE_FLAGS variable
;****************************************************************************
; BAD_DATA .. Exit if Read or Parse doesn"t like what it finds.
; The Carry flag is set as an error message.
;****************************************************************************
BAD_DATA
BSF STATUS,C ; Set the carry flag to show error
RETURN
;****************************************************************************
END ; End of program
-
Hola te mando los ficheros a tu privado no puedo subirlos aqui,ahi tenes los dos el original corregido,fijate bien el encabezado que le puse ,tenias mal asignado el camino para encontrar el pic 16f84.inc
que necesita el MPLAB y ademas el .hex
Saludos
khasistos
-
Muchisimas gracias por tu rapidez y efectividad.
Saludos
-
Una pregunta:
el PIC es nuevo recien comprado, me ha grabado tu fichero sin ningún problema, pero cuando lo pongo en su zocalo ( o fuera directamente ) al ponerle la alimentación, esta se viene a 1,22V y el PIC se calienta un poco.
¿ Crees que debe estar malo ya de nuevo ?
He provado a borrarlo, y volverlo a grabar y funciona, bien pero luego ???????
Salu2
-
Hola.
sospècho que lo estas alimentando con una fuente de mas de 5 volts o sin que sea regulada,es decir todo se soluciona poniendole un 7805 .No creo que este malo la tension debe ser 5 VOLTS .NO LO ESTARAS ALIMENTANDO CON 12???
Saludos
khasistos
-
Bueno, resulta que el listorro que hizo el esquema, li hizo muy bonito, pero puso la alimentación del PIC "AL REVES", con lo cual ya me funciona.
Salu2
-
Quisiera si no te es mucha molestia hacerte una nueva consulta.
El circuito ya me funciona bien, lo he montado con la finalidad de capturar los codigos que proceden de un mando a distacia Philips (RC5).
He montado el reloj giratorio que hay por este foro, por el cual tambien ando, y este se tiene que controlar desde un mando con estas carácteristicas, pero mi problema es el siguiente.
Mi nuevo circuito me muestra en el LCD por cada tecla apretada lo siguiente, solo que variando los valores para cada tecla:
TOC=0
SYSTEM=7
COMMAND=112
te pasaré por correo los tres ficheros. Dos originales del reloj y uno con todos los comandos que yo he obtenido con este circuito.
¿Puedes decirme como adapto mi mando a distancia con los comandos obtenidos a los ficheros originales?
Gracias
-
Hola:
Realmente no estoy en ese tema especifico ,pero si tu dices que el reloj debe ser controlado con un mando a distancia con codigo RC-5 ello no implica que tu transmisor Philips este generando la orden que espera el reloj,No confundir protocolo de transmision con ordenes especificas transmitidas CON ESE PROTOCOLO.El protocolo contempla una serie de parametros de bytes que deben ser respetados dentro de esos bytes esta la orden especifica que tu reloj espera ,pero repito esto no implica que tu transmisor la este enviando tal cual el reloj la espera,es decir tu remoto puede transmitir un PLAY(en RC/5) pero ello no indica que el reloj entienda esa orden a menos que este diseñado para ser operado con un remoto philips.Ademas tu no podras modificar el transmisor es decir las ordenes emitidas dado que estan preprogramadas en el chip.Tendras que generalas tu mismo con un pic o modificar el programa del reloj para que decodifique ESAS ordenes del philips y las translade a la funcion requerida.
Saludos
khasistos
-
Ok ! gracias postearé en el foro general a ver si alguien se ha encontrado con el tema y lo ha solucionado antes.
Salu2