facemanfacey
New Member
hi i have been working on this code for a while now and i have come to a complete dead end. the following code takes midi data on the rx pin of the usart, saves the 3 bytes of data in the cblock, tests the first byte to see if it is a midi on message (xxxx1001) by masking the upper nibble and subtracting from a constant to see if it equals zero, if so take the next byte, convert it using the lookup table. THEN send this data via ra0 and ra1 in a loop which emulates a ps/2 keyboard after calculating the odd parity bit.
first things first, i wrote the diagnostic LED part which doesn't work, led 1 is constantly ON and led2 flashes on, then off, then is constantly on, AND THEN led 3 won't even come on.
so could you please look through my code to see if there are any faults in my programing or if you think there is probably a circuit design problem?
(the trisa and trisb port setup has been tried with the bytes reversed and it still gives the same problem ie 10100000 instead of 00000101)
thank you in advance for your help!
thomas
first things first, i wrote the diagnostic LED part which doesn't work, led 1 is constantly ON and led2 flashes on, then off, then is constantly on, AND THEN led 3 won't even come on.
so could you please look through my code to see if there are any faults in my programing or if you think there is probably a circuit design problem?
(the trisa and trisb port setup has been tried with the bytes reversed and it still gives the same problem ie 10100000 instead of 00000101)
thank you in advance for your help!
thomas
Code:
;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------
LIST p=16F88 ; list directive to define processor
#INCLUDE <P16F88.INC> ; processor specific variable definitions
;------------------------------------------------------------------------------
; CONFIGURATION WORD SETUP
;------------------------------------------------------------------------------
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
;------------------------------------------------------------------------------
; VARIABLE DEFINITIONS
;------------------------------------------------------------------------------
CBLOCK 0x20 ; data block allocated to data bytes
BYTE1 ; midi byte 1
BYTE2 ; midi byte 2
BYTE3 ; midi byte 3
TEMP_ON ; temp store for testing midi on byte
PARITY_TEMP ; temp store for calculating parity bit
PARITY_BYTE ; whole byte for parity bit storage
PARITY_COUNT ; parity counter to count down from 8
KEYBOARD ; data for transmission
TRANSMIT_COUNT ; counter for transmitted bits
D1 ; temp for delay routine
D2 ; temp for delay routine
D3 ; temp for delay routine
D4 ; temp for delay routine
D5 ; temp for delay routine
D6 ; temp for delay routine
D7 ; temp for delay routine
ENDC
PARITY EQU 0x00 ; single bit defined for parity bit
LSB EQU 0x00 ; LSB of keyboard
LED1 EQU 0X02 ; RA2
LED2 EQU 0X03 ; RA3
LED3 EQU 0X03 ; RB3
CLOCK EQU 0X00 ; RA0
DATALINE EQU 0X01 ; RA1
W_TEMP EQU 0x7D ; w register for context saving (ACCESS)
STATUS_TEMP EQU 0x7E ; status used for context saving (ACCESS)
PCLATH_TEMP EQU 0x7F ; variable used for context saving
;------------------------------------------------------------------------------
; EEPROM INITIALIZATION The 16F88 has 256 bytes of non-volatile EEPROM,
; starting at address 0x2100
;------------------------------------------------------------------------------
DATAEE ORG 0x2100
DE "MCHP" ; Place 'M' 'C' 'H' 'P' at address 0,1,2,3
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG 0x0000 ; processor reset vector
PAGESEL START
GOTO START ; go to beginning of program
;------------------------------------------------------------------------------
; INTERRUPT SERVICE ROUTINE
;------------------------------------------------------------------------------
ISR ORG 0x0004 ; interrupt vector location
; Context saving for ISR
MOVWF W_TEMP ; save off current W register contents
MOVF STATUS,W ; move status register into W register
MOVWF STATUS_TEMP ; save off contents of STATUS register
MOVF PCLATH,W ; move pclath register into W register
MOVWF PCLATH_TEMP ; save off contents of PCLATH register
;------------------------------------------------------------------------------
; USER INTERRUPT SERVICE ROUTINE GOES HERE
;------------------------------------------------------------------------------
; Restore context before returning from interrupt
MOVF PCLATH_TEMP,W ; retrieve copy of PCLATH register
MOVWF PCLATH ; restore pre-isr PCLATH register contents
MOVF STATUS_TEMP,W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF W_TEMP,F
SWAPF W_TEMP,W ; restore pre-isr W register contents
RETFIE ; return from interrupt
;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
START
INITIALIZE_PORTS
CLRF CCP1CON
BCF STATUS,RP1 ; select bank 1
BSF STATUS,RP0
MOVLW B'10100000' ; setting up PORTA
MOVWF TRISA
MOVLW B'00000100' ; setting up PORTB
MOVWF TRISB
MOVLW D'39' ; 31250 baud rate
MOVWF SPBRG
MOVLW B'00000100' ; set up high speed BRGH
MOVWF TXSTA
MOVLW B'10010000' ; set up asynchronous reception
MOVWF RCSTA
DIAGNOSTIC_LEDS
BSF PORTA,LED1 ; blink LED1
CALL DELAY200ms
BCF PORTA,LED1
CALL DELAY200ms
BSF PORTA,LED2 ; blink LED2
CALL DELAY200ms
BCF PORTA,LED2
CALL DELAY200ms
BSF PORTB,LED3 ; blink LED3
CALL DELAY200ms
BCF PORTA,LED3
CALL DELAY200ms
LOOP1
BTFSS PIR1,RCIF ;Wait for RX flag
GOTO LOOP1 ;wait for USART byte
MOVF RCREG,W ;move first midi byte to w
MOVWF BYTE1 ;store in memory location
MOVWF TEMP_ON ;store in temp location for manipulation
LOOP2
BTFSS PIR1,RCIF ;Wait for RX flag
GOTO LOOP2 ;wait for USART byte
MOVF RCREG,W ;move second midi byte to w
MOVWF BYTE2 ;store in memory location to free up RCREG
LOOP3
BTFSS PIR1,RCIF ;Wait for RX flag
GOTO LOOP3 ;wait for USART byte
MOVF RCREG,W ;move third midi byte to w
MOVWF BYTE3 ;store in memory location to free up RCREG
NOTE_ON_TEST
MOVLW TEMP_ON
ANDLW 0x0F
SUBLW B'00001001'
BTFSC STATUS,Z
GOTO NOTE_ON
GOTO DISREGARD
NOTE_ON ;convert byte 2 and move to memory location for transmission
MOVF BYTE2,W
CALL TABLE
MOVWF KEYBOARD
CALL PARITY_CALC
CALL TRANSMIT
DISREGARD ;used to free up RCREG for next midi transmission
CLRF BYTE1
CLRF BYTE2
CLRF BYTE3
GOTO LOOP1
;**********************************************************************************************************************
; Calculates tha parity bit expected from the keyboard
;**********************************************************************************************************************
PARITY_CALC ; This routine counts the number of ones that are in the work reg
movwf PARITY_TEMP ; Save the byte that is to be checked in a file reg
clrf PARITY_COUNT ; Clear result file reg
movlw 0x08
movwf PARITY_COUNT ; Do all 8 bits (set counter)
PARITY_LOOP
rrf PARITY_TEMP, f ; Check next bit
btfsc STATUS, C ; Increase counter if a bit was detected as a one
incf PARITY_COUNT, f
decfsz PARITY_COUNT, f ; Exit loop if all 8 bits done
goto PARITY_LOOP
bcf PARITY_BYTE, PARITY ; Parity-bit for the routine "keyboard" is stored in PARITY_BYTE file
btfss PARITY_COUNT, LSB ; Odd parity
bsf PARITY_BYTE, PARITY
return
;------------------------------------------------------------------------------------------
; emulated PS2 output
;------------------------------------------------------------------------------------------
TRANSMIT
movlw 0x08
movwf TRANSMIT_COUNT
bcf PortB, DATALINE ;Begin transfer (Startcondition)
call DELAY20
bcf PortB, CLOCK
call DELAY20
call DELAY20
TRANSMIT_LOOP
bsf PortB, CLOCK
call DELAY20
btfss KEYBOARD, LSB ;Output character - bit for bit (LSB first)
bcf PortB, DATALINE
btfsc KEYBOARD, LSB
bsf PortB, DATALINE
rrf KEYBOARD, 1
call DELAY20
bcf PortB, CLOCK
call DELAY20
call DELAY20
decfsz TRANSMIT_COUNT, 1
goto TRANSMIT_LOOP
bsf PortB, CLOCK
call DELAY20
btfss PARITY_BYTE, PARITY ;Output parity bit
bcf PortB, DATALINE
btfsc PARITY_BYTE, PARITY
bsf PortB, DATALINE
call DELAY20
bcf PortB, CLOCK
call DELAY20
call DELAY20
bsf PortB, CLOCK
call DELAY20
bsf PortB, DATALINE
call DELAY20
bcf PortB, CLOCK
call DELAY20
call DELAY20
bsf PortB, CLOCK
rrf KEYBOARD, 1 ;Transfer complete
return
;-----------------------------------------------------------------------------
; Delay loops, 20us delay needs 100 instruction cycles
; 0.1s needs 500000 instruction cycles
; 0.2s needs 1000000 instruction cycles
;-----------------------------------------------------------------------------
DELAY20 ;100 cycles
movlw 0x21
movwf D1
DELAY20_0
decfsz D1, f
goto DELAY20_0
return
DELAY200ms ;999990 cycles
movlw 0x07
movwf D2
movlw 0x2F
movwf D3
movlw 0x03
movwf D4
DELAY200ms_0
decfsz D2, f
goto $+2
decfsz D3, f
goto $+2
decfsz D4, f
goto DELAY200ms_0
goto $+1 ;6 cycles
goto $+1
goto $+1
return ;4 cycles
DELAY100ms ;499994 cycles
movlw 0x03
movwf D5
movlw 0x18
movwf D6
movlw 0x02
movwf D7
DELAY100ms_0
decfsz D5, f
goto $+2
decfsz D6, f
goto $+2
decfsz D7, f
goto DELAY100ms_0
goto $+1 ;2 cycles
return ;4 cycles
;-----------------------------------------------------------------------------
; Look up table
;-----------------------------------------------------------------------------
TABLE ADDWF PCL,1
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
RETLW 0x4C
RETLW 0x52
RETLW 0x59
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
RETLW 0x4C
RETLW 0x52
RETLW 0x59
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
RETLW 0x4C
RETLW 0x52
RETLW 0x59
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
RETLW 0x4C
RETLW 0x52
RETLW 0x59
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
RETLW 0x4C
RETLW 0x52
RETLW 0x59
RETLW 0x0E
RETLW 0x0D
RETLW 0x15
RETLW 0x1E
RETLW 0x1D
RETLW 0x26
RETLW 0x24
RETLW 0x2D
RETLW 0x2E
RETLW 0x2C
RETLW 0x36
RETLW 0x35
RETLW 0x3D
RETLW 0x3C
RETLW 0x43
RETLW 0x46
RETLW 0x44
RETLW 0x45
RETLW 0x4D
RETLW 0x54
RETLW 0x55
RETLW 0x5B
RETLW 0x12
RETLW 0x58
RETLW 0x1A
RETLW 0x22
RETLW 0x1B
RETLW 0x21
RETLW 0x23
RETLW 0x2A
RETLW 0x32
RETLW 0x34
RETLW 0x31
RETLW 0x33
RETLW 0x3A
RETLW 0x3B
RETLW 0x41
RETLW 0x49
RETLW 0x4B
RETLW 0x4A
;------------------------------------------------------------------------------
; PLACE USER PROGRAM HERE
;------------------------------------------------------------------------------
GOTO $
END