PIC Assembly Program Help

Markd77

Joined Sep 7, 2009
2,806
I'll have a look at the code tomorrow.
This isn't an error but a little odd:
Rich (BB code):
S_145        EQU    H'28'
S_150        EQU    H'29'
S_155        EQU    H'30'
S_160        EQU    H'31'
S_165        EQU    H'32'
What happened to 2A, 2B, 2C, 2D, 2E and 2F? :)
I find it easier to use this format, the assembler gives them incrementing numbers starting at 0x20 (or whatever you pick).

Rich (BB code):
CBLOCK 0x20
S_145
S_150
S_155
S_160
S_165
ENDC
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
Just to make sure I didn't misunderstand when you said 2A, 2B, etc that was the same as H'42',H'43', etc?

I didn't know about the cblock, that makes things much simpler however I'm getting warnings about invalid ram locations which I assume means I've used it incorrectly. I've updated the code here and here are the warnings I'm getting:

Rich (BB code):
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 88 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 89 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 117 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 118 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 120 : Invalid RAM location specified.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 152 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 157 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 160 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 163 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 176 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 287 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 305 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 315 : Invalid RAM location specified.
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 371 : Argument out of range.  Least significant bits used.
Message[305] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 374 : Using default destination of 1 (file).
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 374 : Invalid RAM location specified.
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 439 : Argument out of range.  Least significant bits used.
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 447 : Argument out of range.  Least significant bits used.
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 451 : Argument out of range.  Least significant bits used.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 456 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 466 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 470 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 480 : Invalid RAM location specified.
Warning[219] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 597 : Invalid RAM location specified.
 

Markd77

Joined Sep 7, 2009
2,806
I've made a few changes at the start which makes it better. Cblock is only really for files and isn't good for defining constants.
H' ' or 0x are hexadecimal and D' ' is for decimal so I was expecting to see values like 2A, 2B etc - you were only defining 10 out of every 16 files available, but those definitions are gone now.


Rich (BB code):
    Motor_On equ 0                ;Motor is turned on and off using RA0
    Direction    equ 1            ;Motor direction is controlled by RA1
    IN1    equ 1                ;RA2 is input 1
    IN2    equ 2                ;RA3 is input 2
    IN3    equ 3                ;RA4 is input 3


    CBLOCK 0x20                ;Start at H'20'
    TIMER1                    ;Used in delay routine
    TIMER2                    ; "    "    "
Later on in the code where you are getting the warnings like:
Rich (BB code):
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 439 : Argument out of range.  Least significant bits used.
it is because of lines like this:
Rich (BB code):
            MOVLW    d'280'
where 280 is bigger than the maximum value of 255 for an 8 bit file. The assembler is using the least significant 8 bits of the value so the number it is using is 24.

The number in bold is the line number of the error which you can display to the left of the code with one of the options or see in the disassembly listing from the view menu. You can also double click the error or warning message and it takes you to the line.
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
Okay I've made the suggestion's like you suggested and the majority of the warnings have disappeared, I'm down to:

Rich (BB code):
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 150 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 155 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 158 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 161 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Warning[202] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 369 : Argument out of range.  Least significant bits used.
Message[305] F:\VELLEMAN\K8048\RC COBRA NEW\RC COBRA.ASM 372 : Using default destination of 1 (file).
The first 4 I don't think are important, is that right? The second two however relate to the code below:

Rich (BB code):
;**** IN2 Servo Pulse Test ****
IN2_Test	movf    IN3_S,W		;**** Servo ****
    		subwf   S_210,count    		
t1		bsf	PORTB,	6
		call	Servo_Delay
		decfsz 	count
		goto 	t1
		bcf	PORTB,	6
What I'm trying to do here is get the length of the pulse because I measure down from 210 as I record the pulse i.e. if the pulse is 1.2ms long I record a value of 90. So what I was trying to do here was subtract my stored pulse length (IN3_S) from 210 (S_210) and use send that to the servo.

Am I right in thinking that count should be W in the subwf line and that is what's causing the error?
 

Markd77

Joined Sep 7, 2009
2,806
The first 4 errors can be ignored, you can stop them being shown if you want by putting:
ERRORLEVEL -302
at the top of the listing.

Yes, the first occurence of "count" should be replaced by "W" or "F" and the second "count" should have ",W" or ",F" after it.

Is it behaving properly now?
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
Okay would this be right now:

Rich (BB code):
;**** IN2 Servo Pulse Test ****
IN2_Test	movf    IN3_S,W		;**** Servo ****
    		subwf   S_210,W    		
t1		bsf	PORTB,	6
		call	Servo_Delay
		decfsz 	count, W
		goto 	t1
		bcf	PORTB,	6
What is happening exactly there, is it doing the subtraction and storing the result in W?

then by adding the ,W to the count puts the value into count?

I don't have the set up with me to test at the minute, Sunday will be the soonest I can test it I'm afraid.
 

Markd77

Joined Sep 7, 2009
2,806
I think this is probably what you were trying to do. Most operations have the option to put the result into W or into the same (F)ile. There isn't room in the instruction to put the result into a different file, although it is possible on other types of processor.
Rich (BB code):
;**** IN2 Servo Pulse Test ****
IN2_Test    movf    IN3_S,W        ;**** Servo ****
            subwf   S_210,W    
            movwf count        
t1        bsf    PORTB,    6
        call    Servo_Delay
        decfsz     count, F
        goto     t1
        bcf    PORTB,    6
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
I've made the changes like you said but I'm having trouble testing, it would seem my fixed value for the switch is causing some issue's. So what I was think I'd try do was measure each pulse during the start up routine and then for the switch to start with add 5 and subtract 5 from the mid point.

So to clarify, I'd put this code in the start up

Rich (BB code):
;**** Measure Mid Pulse Lenght ****
Pulse    	MOVLW   D'210'
                MOVWF   INPUT1_NEUTRAL_PULSE
                MOVLW   D'210'
                MOVWF   INPUT2_NEUTRAL_PULSE
                MOVLW   D'210'
                MOVWF   INPUT3_NEUTRAL_PULSE 
                
IN1_Check	BTFSS	PORTA,IN1
		goto	IN1_Check
IN1_Check_2	DECF	INPUT1_NEUTRAL_PULSE,F
		call 	Servo_Delay
		BTFSC	PORTA,IN1
		goto	IN1_Check_2
		
IN2_Check	BTFSS	PORTA,IN2
		goto	IN2_Check		
IN2_Check_2	DECF	INPUT2_NEUTRAL_PULSE,F
		call 	Servo_Delay
		BTFSC	PORTA,IN2
		goto	IN2_Check_2
		
IN3_Check	BTFSS	PORTA,IN3			
		goto	IN3_Check
IN3_Check_2	DECF	INPUT3_NEUTRAL_PULSE,F
		call 	Servo_Delay
		BTFSC	PORTA,IN3
		goto	IN3_Check_2
And then work out and store
  • INPUT1_NEUTRAL_PULSE + 5
  • INPUT1_NEUTRAL_PULSE - 5

I would imagine for -5 I could just loop
Rich (BB code):
DECF	INPUT1_NEUTRAL_PULSE,F
5 times but how would I add 5 easily?

Seem's every step forward results in 5 backwards :) And sorry again for the delay, I have less time for my hobby at the minute.
 

Markd77

Joined Sep 7, 2009
2,806
If you want to store the values you can do this:
Rich (BB code):
    movf INPUT1_NEUTRAL_PULSE, W
    addlw 0x05                ;add 5
    movwf INPUT1_NEUTRAL_PULSE_PLUS_5
    addlw -0x0A                ;subtract 10 to give the original -5
    movwf INPUT1_NEUTRAL_PULSE_MINUS_5
However it is is probably as easy to calculate them when they are needed which saves files.
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
Ok got a little bit more done on the auto pulse length setting, what do you think of this

Rich (BB code):
;**** Set Mid Pulse Lenght ****
Pulse    	MOVLW   D'210'
                MOVWF   INPUT1_B
                MOVLW   D'210'
                MOVWF   INPUT2_E
                MOVLW   D'210'
                MOVWF   INPUT3_E 
                
IN1_Check	BTFSS	PORTA,IN1
		goto	IN1_Check
IN1_Check_2	DECF	INPUT1_B,F
		call 	Servo_Delay
		BTFSC	PORTA,IN1
		goto	IN1_Check_2
		
IN2_Check	BTFSS	PORTA,IN2
		goto	IN2_Check		
IN2_Check_2	DECF	INPUT2_E,F
		call 	Servo_Delay
		BTFSC	PORTA,IN2
		goto	IN2_Check_2
		
IN3_Check	BTFSS	PORTA,IN3			
		goto	IN3_Check
IN3_Check_2	DECF	INPUT3_E,F
		call 	Servo_Delay
		BTFSC	PORTA,IN3
		goto	IN3_Check_2

;**** Set Input1 Pulse Values ****
    		movf 	Input1_B, W
    		addlw 	0x05                ;add 5
    		movwf 	Input1_A
    		addlw 	-0x0A                ;subtract 10 to give the original -5
    		movwf	Input1_C

;**** Set Input2 Pulse Values ****		
    		movf 	Input2_E, W
    		addlw 	0x05                ;add 5
    		movwf 	Input2_F
    		addlw 	0x05                ;add 5
    		movwf 	Input2_G
    		addlw 	0x05                ;add 5
    		movwf 	Input2_H
    		addlw 	0x05                ;add 5
    		movwf 	Input2_I
    		addlw 	-0x19               ;subtract 25 to give the original -5
    		movwf	Input2_D
    		addlw 	-0x05               ;subtract -5
    		movwf	Input2_C    		
    		addlw 	-0x05               ;subtract -5
    		movwf	Input2_B    
    		addlw 	-0x05               ;subtract -5
    		movwf	Input2_A    
    		
;**** Set Input3 Pulse Values ****		
    		movf 	Input3_E, W
    		addlw 	0x05                ;add 5
    		movwf 	Input3_F
    		addlw 	0x05                ;add 5
    		movwf 	Input3_G
    		addlw 	0x05                ;add 5
    		movwf 	Input3_H
    		addlw 	0x05                ;add 5
    		movwf 	Input3_I
    		addlw 	-0x19               ;subtract 25 to give the original -5
    		movwf	Input3_D
    		addlw 	-0x05               ;subtract -5
    		movwf	Input3_C    		
    		addlw 	-0x05               ;subtract -5
    		movwf	Input3_B    
    		addlw 	-0x05               ;subtract -5
    		movwf	Input3_A    
    		

		MOVLW   D'210'
                MOVWF   S_210
Also I found a cheap rc car with a steering assembly which relies on a motor instead of a servo, which will make it easier to control so hopefully that'll make things a little simpler.
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
I needed to modify this code for the switch so that if the pulse length is between Input1_A and Input1_C it goes to IN2_Test otherwise it goes to LC1. And LC1 is the function which directly follows this code.

Rich (BB code):
;**** Switch Pulse Test ****
IN1_Test	movf    Input1_A,W		;**** X =< Input1_A ****
		subwf   IN1_S,W
		btfsc   STATUS,C
    		goto    LC1

    		movf    Input1_C,W		;**** Input1_A =< X =< Input1_C ****
    		subwf   IN1_S,W
    		btfsc   STATUS,C
    		goto    IN2_Test
Would that look right to you?
 

Markd77

Joined Sep 7, 2009
2,806
Second post first, it works if you swap both the btfsc for btfss.

First post second, looks like it probably works but there is a better way which uses much less files (things get more complicated when you use more than the first bank of files and I think you are getting close).

Instead of storing all the values and then later testing for all of them you can combine the processes in the testing phase.

eg. just store input3, the original value.

When you need to do the tests:
Subtract 20 from input3 (result to W)
Compare that to measured pulse
Do relevant action or continue to next test

Subtract 15 from input3 (result to W)
Compare that to measured pulse
Do relevant action or continue to next test

etc


Servos are easier to control than motors, because you don't need to control the direction or keep track of their position; I'd recommend sticking with the servo unless there is a good reason not to.
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
I got some time this morning and modified the code as you suggested and it is working brilliantly, I have control over the lights and the steering but the motor is struggling.

I changed the code to try have it only have three speeds, no motion, full forward and full reverse. I can hear the motor transition between these three modes as when the joystick is idle the motor is silent and when it in either the forward or reverse position it emits a high pitched squeal like it's trying to move but it can't.

I think the issue is with my PWM code but I can't see whats wrong, I based the code on this and my code is here in full. Maybe I changed it too much from the original but I can't see what's wrong, any suggestions?

And I decided to use the motor steering assembly from the other car because it was already assembled, I don't really need accuracy and I already have the controller built in because the motor controller I'm using has the capability to control two motors.
 

Thread Starter

ozirock

Joined Jan 13, 2011
47
I've found the mistake, the site had got a line reading:

Rich (BB code):
MOVLW    126
Which I think is wrong so I changed it to:

Rich (BB code):
MOVLW    0x7E
and I now have speed steering and lights, all in all a great success!! :)

I have a new conundrum I want to look into before I put it all together and close it up. I'm looking at playing a wav sound through a speaker I've taken from an old mobile phone. I've found this program here which generates a table style code for the sounds you want to play. But I'm struggling to find an example of how to sort of decode it on the pic. I would guess I need a loop that can work through the rows at the same frequency as it was encoded but I've no idea how to do that. Have you ever seen an example like that?

Here's the header of the outputted sound if its useful:

Rich (BB code):
;=====================================================
; AUTO CREATED FILE made by Windows BTc Sound Encoder 
; v2.0    Copyright 2002-2008 - Roman Black
; 
; Hippyware.  
; www.RomanBlack.com 
;=====================================================
;
; File Details:
; Size 3353600 bits     (419200 bytes)
; Sound encoded at 44100 bits/sec 
; using BTc64 1bit Algorithm to be decoded on
; the following circuit:
; 
; 
;             R = 6491 ohms  
;  
; Digital -----------R-----*----- Analogue  
;                          |      out   
;                          |     
;                          |     
;                          C = 0.22 uF    
;                          |     
;                          |     
;                          |     
;                         Gnd     
; 
; 
;=====================================================
; Bitstream data is in PIC .asm table format,
; in blocks of 256 bytes.
; 
; Bits are played from left to right, from ms_bit to
; ls_bit.
;=====================================================


;---------------------------------------------------
     org (1 * 256)   	    ; block = 1  
;---------------------------------------------------


     ;-------------------------  0
     retlw b'11010101'   ; d5 
     retlw b'01010101'   ; 55
 
Top