Help with variables: DMX receiver

Thread Starter

loesvan

Joined Sep 23, 2011
28
Hello,

Can someone help me please. (sorry but my english is not very good I'm Spanish)
I am trying to modify a program that is on the net. It's a program to recive DMX.
What I am trying to do, is to be able to change the DMX channel with a remote control, but the program does not recognize a variable and I can't find the problem.
I am using Picbasic 2.46 and I am mixing basic with assembly.

The circuit has two PICs. The first PIC receives the signal from the IR remote control and sends the information decoded to the next PIC via RS 232. The information received
on this PIC is correct, but when I put the variable in the program it doesn't work.
I have tried defining the variable in basic and in asm but none of them work.


Here is an example in basic:

Rich (BB code):
Dir=1 ; Dir is the variable for the DMX channel

CHAN
 INCF    _Offset
 MOVF    _Offset,W    
 XORLW    _Dir        ; When I put the variable "Dir" on this channel it doesn't work >>
 BTFSC    STATUS,Z    ; but if I put any number (01h or 1) it works Perfectly.
 GOTO    CHAN2
But even if I do it in assembly it doesn't work
Rich (BB code):
Dir equ 020h
 movlw  01h
 movwf  Dir   ; The value of Dir will not change, it remains with 020h.
Here is the complete program:


Rich (BB code):
'-------------------------------------------------------------------------------



@ DEVICE pic16f628a,HS_OSC,MCLR_OFF,PWRT_ON,WDT_OFF,lvp_off,protect_on,CPD_on
INCLUDE "modedefs.bas" 

define OSC 20
 
x   var byte  
Dir var byte
 
OUT1 var PORTA.4     
OUT2 var PORTB.4     
OUT3 var PORTB.5 
OUT4 var PORTB.6 
OUT5 var PORTB.7     
OUT6 var PORTA.1     
OUT7 var PORTB.2 

BREAK var byte
STARTCODE var byte 
ADDR9 var byte
RC9   var byte 

Reg1    var byte
Reg2    var byte
Reg3    var byte
Reg4    var byte
Reg5    var byte
Reg6    var byte
Reg7    var byte

WSAVE  var byte   $20 system      
SSAVE  var byte bank0 system
PSAVE  var byte bank0 system
pwmcounter var byte

DADDR   var byte
RADDR   var byte
Offset  var byte

DEFINE INTHAND ISR   

asm
 
 goto INICIO
ISR
 bcf     INTCON,GIE      
 btfsc   INTCON,GIE      
 GoTo    ISR            
 movwf   WSAVE           
 movf    STATUS,W
 clrf    STATUS          
 movwf   SSAVE           
 movf    PCLATH          
 movwf   PSAVE           
 clrf    PCLATH          
 
 GOTO INTHANDLER

INICIO
endasm
CMCON=7
 
TRISA= %00000000
TRISB= %00001010 

low PortA.2
high PortB.3
pause 100

Loop1:
if PortB.3=0 then goto Loop1
Loop2:
serin PortB.3,T9600,x
if x=0 then goto Loop2  ' It stays here until it receives from other PIC 
                        
write 2,x       
read  2,Dir     

Dir=1             '               Only for test <<<<<<<<<<<<
asm
 movlw 01h
 movwf Dir

endasm 




SPBRG = 4          
TXSTA = %00100100  
PIE1.5=1
RCSTA.6=1          

RCREG=0
RCREG=0
RCREG=0
RCSTA = $90 
RCSTA.7=1
INTCON.6=1   
INTCON.7=1

Reg1=0
Reg2=0
Reg3=0
Reg4=0
Reg5=0
Reg6=0
Reg7=0
DADDR=0
ADDR9=0    

MAIN:
'low RX
pwmcounter=255
OUT1=0 
OUT2=0
OUT3=0
OUT4=0
OUT5=0
OUT6=0
OUT7=0
@ call PWM_CYCLE
goto MAIN

asm
PWM_CYCLE 
 
 MOVF    _Reg1,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT1
 MOVF    _Reg2,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT2
 MOVF    _Reg3,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT3
 MOVF    _Reg4,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT4
 MOVF    _Reg5,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT5
 MOVF    _Reg6,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT6
 MOVF    _Reg7,W
 XORWF    _pwmcounter,W
 BTFSC    STATUS,Z
 BSF    _OUT7 
 
 DECFSZ    _pwmcounter
 GOTO    PWM_CYCLE
 RETURN
  
INTRETURN 
 MOVF    PSAVE,W    
 MOVWF    PCLATH
 MOVF    SSAVE,W
 MOVWF    STATUS
 SWAPF    WSAVE,F  
 SWAPF    WSAVE,W
 RETFIE         

INTHANDLER 
 BTFSS    PIR1,RCIF
 GOTO    INTRETURN
 GOTO    DMX

DMX
 BSF    PORTA,2  
 BTFSC    RCSTA,OERR
 GOTO    OVERRUN

 BTFSC     RCSTA,FERR
 GOTO     FRAME

 BTFSS     _BREAK
 GOTO     RET
 
 BTFSS    _STARTCODE    
 
 GOTO    SC             
 BTFSC    _STARTCODE
 GOTO    CHANNEL

RET 
 MOVF    RCREG,W
 GOTO    INTRETURN

OVERRUN
 BCF    RCSTA,SPEN
 BSF    RCSTA,SPEN
 MOVF    RCREG,W
 GOTO    LAST

FRAME 
 BCF    _BREAK
 BCF    _STARTCODE
 BCF    _RC9
 CLRF    _RADDR
 CLRF    _Offset
 BTFSS    RCSTA,RX9D
 BSF    _BREAK
 MOVF    RCREG,W
 GOTO    INTRETURN

SC
 MOVF    RCREG,W
 XORLW    00h
 BTFSC    STATUS,Z
 BSF    _STARTCODE
 GOTO    INTRETURN

INCREASE
 INCF    _RADDR    
 BTFSC    STATUS,Z
 BSF    _RC9
 RETURN

CHANNEL 

 MOVF    _Offset,W
 XORLW    00h            
 BTFSS    STATUS,Z
 GOTO    CHAN

 MOVF    _RADDR,W    
 XORWF    _DADDR,W
 BTFSC    STATUS,Z
 GOTO    NINTH        

 CALL    INCREASE
 GOTO    RET

NINTH
 BTFSC    _ADDR9
 GOTO    TRUE
 MOVF    RCREG,W
 GOTO    FALSE

TRUE
 BTFSC    _RC9
 GOTO    CHAN
 CALL    INCREASE
 GOTO    RET

FALSE
 BTFSS    _RC9
 GOTO    CHAN
 CALL    INCREASE
 GOTO    RET

CHAN
 INCF    _Offset
 MOVF    _Offset,W    
 XORLW    _Dir     ; << When I put the variable Dir, it doesn't work. But if I put any
 BTFSC    STATUS,Z ;    number it works perfectly.
 GOTO    CHAN2
 MOVF    _Offset,W
 XORLW    2         ;   ok
 BTFSC    STATUS,Z
 GOTO    CHAN3
 MOVF    _Offset,W
 XORLW    3         ;   ok
 BTFSC    STATUS,Z
 GOTO    CHAN4
 MOVF    _Offset,W
 XORLW    4         ;   ok
 BTFSC    STATUS,Z
 GOTO    CHAN5
 MOVF    _Offset,W
 XORLW    5         ;   ok
 BTFSC    STATUS,Z
 GOTO    CHAN6
 MOVF    _Offset,W
 XORLW    6        ;    ok
 BTFSC    STATUS,Z
 GOTO    CHAN7
 
 MOVF    _Offset,W
 XORLW    0FFh              
 BTFSC    STATUS,Z
 GOTO    LAST

CHAN1
 MOVF    RCREG,W
 MOVWF    _Reg1
 CALL    INCREASE
 GOTO    INTRETURN

CHAN2
 MOVF    RCREG,W
 MOVWF    _Reg2
 CALL    INCREASE
 GOTO    INTRETURN

CHAN3
 MOVF    RCREG,W
 MOVWF    _Reg3
 CALL    INCREASE
 GOTO    INTRETURN

CHAN4
 MOVF    RCREG,W
 MOVWF    _Reg4
 CALL    INCREASE
 GOTO    INTRETURN

CHAN5
 MOVF    RCREG,W
 MOVWF    _Reg5
 CALL    INCREASE
 GOTO    INTRETURN

CHAN6
 MOVF    RCREG,W
 MOVWF    _Reg6
 CALL    INCREASE
 GOTO    INTRETURN

CHAN7
 MOVF    RCREG,W
 MOVWF    _Reg7
 CALL    INCREASE
 GOTO    INTRETURN

LAST 

 BCF    _BREAK
 BCF    _STARTCODE
 CLRF    _Offset
 GOTO    INTRETURN
;-------------------------------------------------------------------------------

endasm

 end

Thank you very much for the help.
 
Last edited by a moderator:

ErnieM

Joined Apr 24, 2011
8,377
Due to it's limited addressing size inside an instruction, PICs spread the register memory over several banks. Thus an address 0x20 exists in banks 0, 1 and 2 for that device.

You need to proceed your instruction to write to Dir with a "banksel Dir" macro instruction. Normally you don't need to mess with that in something like Basic, but since you're mixing assembly and Basic together you need to do it in the assembly code parts.

I'm not sure if your Basic has the banksel macro, it's a standard Microchip MPLAB assembly macro.

Hope that helps. :rolleyes:
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
Thanks for your help but I still have the problem, when I put banksel I get the error opcode expected instead of Dir. I have tried switching to other banks but it doesn't work.
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
Due to it's limited addressing size inside an instruction, PICs spread the register memory over several banks. Thus an address 0x20 exists in banks 0, 1 and 2 for that device.

You need to proceed your instruction to write to Dir with a "banksel Dir" macro instruction. Normally you don't need to mess with that in something like Basic, but since you're mixing assembly and Basic together you need to do it in the assembly code parts.

I'm not sure if your Basic has the banksel macro, it's a standard Microchip MPLAB assembly macro.

Hope that helps. :rolleyes:
Thanks for your help ErnieM, but I sill have the problem. When I put banksel I get
a error opcode inspected instead of Dir. I have tried switching to other banks but it doesn't work.
 

ErnieM

Joined Apr 24, 2011
8,377
Two choices: either figure out how to do bank selection for inline assembler, or change the whole project to assembler.

The bank is set in the Status register by the RP bits.

However, the very top of memory 0x70 - 0X7F appear in all banks and need not be selected. If your compiler doesn't use them you can use one of those instead of address 0x20 to hold Dir_
 

Markd77

Joined Sep 7, 2009
2,806
in your first example you are using xorlw incorrectly, it would xor the memory address of Dir and W.
You should use XORWF _Dir, W (assuming you don't want to change Dir).
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
Two choices: either figure out how to do bank selection for inline assembler, or change the whole project to assembler.

The bank is set in the Status register by the RP bits.

However, the very top of memory 0x70 - 0X7F appear in all banks and need not be selected. If your compiler doesn't use them you can use one of those instead of address 0x20 to hold Dir_
Hi ErnieM,
If I do it all in assembly (without the part in basic just giving a value to Dir) I have the same problem. the Variable Dir is not working.
I will try what you said of the top of memory.
Thanks.
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
in your first example you are using xorlw incorrectly, it would xor the memory address of Dir and W.
You should use XORWF _Dir, W (assuming you don't want to change Dir).
Hi Markd77
If I put XORWF _Dir,W I get a error: extra tokens on end of line.
Thanks for your help.
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
Two choices: either figure out how to do bank selection for inline assembler, or change the whole project to assembler.

The bank is set in the Status register by the RP bits.

However, the very top of memory 0x70 - 0X7F appear in all banks and need not be selected. If your compiler doesn't use them you can use one of those instead of address 0x20 to hold Dir_
Here is how the program looks now, but it's still not woking:



Rich (BB code):
__CONFIG _CP_ON &_PWRTE_ON &_WDT_OFF &_HS_OSC &_LVP_OFF &_MCLRE_OFF ;&_CPD_ON


 list    P=16F628A
 #INCLUDE <P16F628a.INC>

 #DEFINE    OUT1  PORTA,4     
 #DEFINE    OUT2  PORTB,4     
 #DEFINE    OUT3  PORTB,5 
 #DEFINE    OUT4  PORTB,6 
 #DEFINE    OUT5  PORTB,7     
 #DEFINE    OUT6  PORTA,0     
 #DEFINE    OUT7  PORTA,1     

 #DEFINE    BREAK      DMX_reg,0
 #DEFINE    STARTCODE DMX_reg,1
 #DEFINE    MOVED      DMX_reg,2
 #DEFINE    ADDR9      DMX_reg,3
 #DEFINE    RC9      DMX_reg,4

Dir     EQU     0x70 ;   Variable >>>>>>>>>>>>>

DMX_reg EQU     020h
Reg1    EQU     021h
Reg2    EQU     022h
Reg3    EQU    023h
Reg4    EQU    024h
Reg5    EQU    025h
Reg6    EQU    026h
Reg7    EQU    027h
Count    EQU    030h
W_SAVE    EQU    031h
S_SAVE    EQU    032h
P_SAVE    EQU    033h
pwmcounter EQU  034h
flag        EQU    02Ah
D_ADDR   EQU    02Bh
temp       EQU    02Ch
R_ADDR   EQU    02Dh
Offset     EQU    02Eh
temp2     EQU    02Fh

 ORG 00h
 GOTO INIT

 ORG 04h
 MOVWF    W_SAVE      ;save context,
 MOVF    STATUS,W  ;save  STATUS, PCLATH & W
 MOVWF    S_SAVE
 MOVF PCLATH,W
 MOVWF P_SAVE
 GOTO INTHANDLER
INIT 

 MOVLW    0x07    ;turn analog comparators off
 MOVWF    CMCON
 CLRF    PORTA
 CLRF    PORTB

 BSF    STATUS,RP0 ;Select Bank1
 CLRF    TRISA       ;porta output
 CLRF    TRISB       ;portb output
 BSF    TRISB,1       ;B1 input (UART Recieve)

 MOVLW 01h    
 MOVWF Dir    ; Dir = 1 >>>>>>>>>>>>>>>>>>>>>>>>




 MOVLW    04h
 MOVWF    SPBRG            ;Set baud rate
 BSF    TXSTA,BRGH    ;high speed
 BCF    TXSTA,SYNC    ;Async connection
 CLRF    PIE1            ;clear other interrupts
 BSF    PIE1,RCIE    ;Set recieve interrupt
 BCF    STATUS,RP0    ;Return to bank0
 BSF    RCSTA,RX9    ;Enable 9bit data

 MOVF    RCREG,W    ;clear RCREG FIFO
 MOVF    RCREG,W
 MOVF    RCREG,W
 BSF    RCSTA,CREN    ;Enable recieve
 BSF    RCSTA,SPEN    ;Enable UART
 BSF    INTCON,PEIE    ;Enable interrupts
 BSF    INTCON,GIE

 CLRF    Reg1
 CLRF    Reg2
 CLRF    Reg3
 CLRF    Reg4
 CLRF    Reg5
 CLRF    Reg6
 CLRF    Reg7
 ;CLRF    Reg8
 ;CLRF    Reg9
 CLRF    D_ADDR    ;set our dmx adress to 0
 BCF    ADDR9

 GOTO MAIN
MAIN 
 MOVLW    0FFh
 MOVWF    pwmcounter
 BCF    OUT1 
 BCF    OUT2
 BCF    OUT3
 BCF    OUT4
 BCF    OUT5
 BCF    OUT6
 BCF    OUT7

 CALL    PWM_CYCLE

 GOTO    MAIN

PWM_CYCLE
 MOVF    Reg1,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT1
 MOVF    Reg2,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT2
 MOVF    Reg3,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT3
 MOVF    Reg4,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT4
 MOVF    Reg5,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT5
 MOVF    Reg6,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT6
 MOVF    Reg7,W
 XORWF    pwmcounter,W
 BTFSC    STATUS,Z
 BSF    OUT7

 DECFSZ    pwmcounter
 GOTO    PWM_CYCLE
 RETURN

INTRETURN 
 MOVF    P_SAVE,W    ;restore context
 MOVWF    PCLATH
 MOVF    S_SAVE,W
 MOVWF    STATUS
 SWAPF    W_SAVE,F
 SWAPF    W_SAVE,W
 RETFIE

INTHANDLER 
 BTFSS    PIR1,RCIF
 GOTO    INTRETURN
 GOTO    DMX

DMX
 BTFSC    RCSTA,OERR
 GOTO    OVERRUN

 BTFSC     RCSTA,FERR
 GOTO     FRAME

 BTFSS     BREAK
 GOTO     RET
 
 BTFSS    STARTCODE    ;has a startcode passed ?
 
 GOTO    SC            ;yes: go check for valid startcode
  
 BTFSC    STARTCODE
 
 GOTO    CHANNEL

RET 
 MOVF    RCREG,W
 GOTO    INTRETURN

OVERRUN
 BCF    RCSTA,SPEN
 BSF    RCSTA,SPEN
 MOVF    RCREG,W
 ;BSF    ERRLED
 GOTO    LAST

FRAME 
 BCF    BREAK
 BCF    STARTCODE
 BCF    RC9
 CLRF    R_ADDR
 CLRF    Offset
 BTFSS    RCSTA,RX9D
 BSF    BREAK
 MOVF    RCREG,W
 GOTO    INTRETURN

SC
 MOVF    RCREG,W
 XORLW    00h
 BTFSC    STATUS,Z
 BSF    STARTCODE
 GOTO    INTRETURN

INCREASE
 INCF    R_ADDR    
 BTFSC    STATUS,Z
 BSF    RC9
 RETURN

CHANNEL 

 MOVF    Offset,W
 XORLW    00h        ;check if offset != 0
 BTFSS    STATUS,Z
 GOTO    CHAN

 MOVF    R_ADDR,W    ;else: check if chans match
 XORWF    D_ADDR,W
 BTFSC    STATUS,Z
 GOTO    NINTH        ;if so: check for 9th bit

 CALL    INCREASE
 GOTO    RET

NINTH
 BTFSC    ADDR9
 GOTO    TRUE
 MOVF    RCREG,W
 GOTO    FALSE

TRUE
 BTFSC    RC9
 GOTO    CHAN
 CALL    INCREASE
 GOTO    RET

FALSE 
 BTFSS    RC9
 GOTO    CHAN
 CALL    INCREASE
 GOTO    RET

CHAN 
 INCF    Offset
 MOVF    Offset,W
 XORLW    Dir        ; Not working >>>>>>>>>>>>>>>>>>>>>>
 BTFSC    STATUS,Z
 GOTO    CHAN2

 MOVF    Offset,W
 XORLW    02h
 BTFSC    STATUS,Z
 GOTO    CHAN3

 MOVF    Offset,W
 XORLW    03h
 BTFSC    STATUS,Z
 GOTO    CHAN4

 MOVF    Offset,W
 XORLW    04h
 BTFSC    STATUS,Z
 GOTO    CHAN5

 MOVF    Offset,W
 XORLW    05h
 BTFSC    STATUS,Z
 GOTO    CHAN6

 MOVF    Offset,W
 XORLW    06h
 BTFSC    STATUS,Z
 GOTO    CHAN7

 MOVF    Offset,W
 XORLW    0FFh
 BTFSC    STATUS,Z
 GOTO    LAST

CHAN1
 MOVF    RCREG,W
 MOVWF    Reg1
 CALL    INCREASE
 GOTO    INTRETURN

CHAN2
 MOVF    RCREG,W
 MOVWF    Reg2
 CALL    INCREASE
 GOTO    INTRETURN

CHAN3
 MOVF    RCREG,W
 MOVWF    Reg3
 CALL    INCREASE
 GOTO    INTRETURN

CHAN4
 MOVF    RCREG,W
 MOVWF    Reg4
 CALL    INCREASE
 GOTO    INTRETURN

CHAN5
 MOVF    RCREG,W
 MOVWF    Reg5
 CALL    INCREASE
 GOTO    INTRETURN

CHAN6
 MOVF    RCREG,W
 MOVWF    Reg6
 CALL    INCREASE
 GOTO    INTRETURN

CHAN7
 MOVF    RCREG,W
 MOVWF    Reg7
 CALL    INCREASE
 GOTO    INTRETURN

LAST 

 BCF    BREAK
 BCF    STARTCODE
 CLRF    Offset
 GOTO    INTRETURN
 END
 

Thread Starter

loesvan

Joined Sep 23, 2011
28
Now that you've changed to all assembler and presumably are using MPLAB, the suggestion I made should work.
Hello Markd77,

I am using the note book to make the asm file and Mpasmwin to compile, when I put XORLW Dir,W I get this error: Error[108] : Illegal character (,)
 
Top