Autor Tema: Pasar ASM a HEX  (Leído 2842 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
Pasar ASM a HEX
« 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


Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: Pasar ASM a HEX
« Respuesta #1 en: 13 de Febrero de 2004, 10:30:00 »
 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

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
RE: Pasar ASM a HEX
« Respuesta #2 en: 13 de Febrero de 2004, 11:58:00 »
Muchisimas gracias por tu rapidez y efectividad.

Saludos

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
RE: Pasar ASM a HEX
« Respuesta #3 en: 13 de Febrero de 2004, 14:10:00 »
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

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: Pasar ASM a HEX
« Respuesta #4 en: 13 de Febrero de 2004, 16:50:00 »
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

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
RE: Pasar ASM a HEX
« Respuesta #5 en: 14 de Febrero de 2004, 04:57:00 »
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

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
RE: Pasar ASM a HEX
« Respuesta #6 en: 14 de Febrero de 2004, 05:11:00 »
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

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: Pasar ASM a HEX
« Respuesta #7 en: 14 de Febrero de 2004, 07:39:00 »
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

Desconectado Mako22

  • PIC12
  • **
  • Mensajes: 77
RE: Pasar ASM a HEX
« Respuesta #8 en: 15 de Febrero de 2004, 23:56:00 »
Ok ! gracias postearé en el foro general a ver si alguien se ha encontrado con el tema y lo ha solucionado antes.

Salu2


 

anything