Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F628 ... VERY SIMPLE PROBLEM

Status
Not open for further replies.

micro571

New Member
Hi,

I'm trying to learn the assembler to program PICs. I'm doing alright, largely learning off of Nigel's tutorials.

I wrote a some-what complicated bit of code and it didn't work. So I keep trouble shooting it until I get down to really basic stuff ... and that won't even work.

Someone, please tell me why even this insanely simple bit of code won't work.

tone equ 0x31

sLoop
movlw 0xff
movwf tone
movlw tone ; <<<<<<
movwf PORTA
goto sLoop

I'm just trying to put 0xff into the register tone and then have tone put into PORTA.

If I replace tone with 0xff on the line with the arrows, it works fine. For some reason it won't let me load a value into tone and then use it later.

What am I doing wrong ?

Thanks.
 
As 'csaba911' has pointed out, you're using the totally wrong instruction, MOVLW means 'Move Literal' - a constant value, specified on the rest of the line. 'Tone' is just an equate name, and will have a numeric value (the address of the GPR it points to), this value will be copied to the W register.

What you need is MOVF - 'Move File', as already pointed out 'MOVF Tone, W' will move the contents of the GPR pointed to by Tone into the W register.
 
Thanks Nigel and csaba911.

Just one more bit of code I can't figure out ...
After this I should be fine on my own.

PORTB are all INPUTS and PORTA are all OUTPUTS.

Code:
slit		equ	0x31
sLoop
call count
btfsc slit, 0x01     ;<<<<<<
	call turn_on
btfss slit, 0x01     ;<<<<<<
	call turn_off
goto sLoop


turn_on
	movlw	0xff
	movwf	PORTA			;set all bits on
return

turn_off
	movlw	0x00
	movwf	PORTA			;set all bits off
return

count	
clrf slit ;set slit to 0
	BTFSS  PORTB, 3
		incf slit,1
	BTFSS  PORTB, 4
		incf slit,1
	BTFSS  PORTB, 5
		incf slit,1
	BTFSS  PORTB, 6
		incf slit,1
	BTFSS  PORTB, 7
		incf slit,1
return

What I'd like it do is ... count up the number of switches that are on (grounding the pin) and if 0x0? number of switches are on, then put on the LEDs. So if it were 0x01 it would require 1 switch to be on.

What happens in reality with this code, is if there are 1 or 2 switches on ... the LEDs will be on. 3-5 and the lights are off ... doesn't make sense to me.

Any suggestions would be greatly appreciated.
 
BTFSC and BTFSS check a single bit for being high or low, this isn't what you want to happen!. To check for a particular value in a register you need to either use SUB or XOR on the two values, and check the zero flag to see if they were equal.
 
BTFSC and BTFSS are what I want. I want to see how many switches are activated ... so if there are 4, slit will have a value of 4. If 2, then slit will have a value of 3. It doesn't matter which switches are activated, I just need to know how many there are.
 
micro571 said:
BTFSC and BTFSS are what I want. I want to see how many switches are activated ... so if there are 4, slit will have a value of 4. If 2, then slit will have a value of 3. It doesn't matter which switches are activated, I just need to know how many there are.

I've already explained that BTFSC and BTFSS won't do what you want, they only test a single bit for high or low.
 
If you want to count the number of switches set _low regardless of their order, than your idea works.
Code:
MAIN	
	   BANKSEL	ADCON1
	   MOVLW	  0X06
	   MOVWF	  ADCON1
	   MOVLW	  B'00000000'
	   MOVWF	  TRISA
	   MOVLW	  B'11111111'
	   MOVWF	  TRISB
	   BANKSEL	PORTB
SLOOP CLRF      SLIT                       ;SET SLIT TO 0 
 	  BTFSS  	PORTB, 0 
      	INCF 	SLIT,F 
   	BTFSS  	PORTB, 1 
      	INCF 	SLIT,F 
   	BTFSS  	PORTB, 2 
      	INCF 	SLIT,F 
   	BTFSS  	PORTB, 3 
      	INCF 	SLIT,F 
   	BTFSS  	PORTB, 4 
      	INCF 	SLIT,F 
      MOVF	   SLIT,W
	   MOVWF	  PORTA
	   GOTO	   SLOOP

Good luck
STEVE
 
Thanks for the code steve.

Here's where I'm stuck ...

The count procedure should go through the 5 switches and see how many are on (grounded). Say 3 are on, slit will have a value of 0x03.

Now how do I say if slit = 0x03 then call SuperLoop ?? Because like Nigel mentioned, btfss and btfsc only test a single pin and not actually the register value.

Nigel mentioned something about SUB or XOR? Do I have to have registers pre-filled with 0x01, 0x02, 0x03... then compare the values to slit ??

Any guidance would be greatly appreciated.
Nigel ... I think I misunderstood what you were originally saying. Sorry bout that.
 
there was an earlier topic in here somewhere discussing If Then statments with assembler , but the search dosent seem to be working..
 
Ok. I've got it all figured out. SUB was used.

For future reference ... anyone doing PIC programming, here is how you do an IF REGISTER = ??? THEN ...

In this case ... if slit = ?? then ...

Quick explanation:
The value you are checking is loaded into W and subtracted from your register. If the result is zero, then the Z bit of the status flag becomes '1'. Then we can tell it to call a subroutine. If it isn't equal to the value we just checked, the old value is restored (by adding W to it) and we continue to check it against another value.

Code:
movlw 0x05
subwf slit
btfsc STATUS, Z
	call its_five
addwf slit

movlw 0x04
subwf slit
btfsc STATUS, Z
	call its_four
addwf slit

movlw 0x03
subwf slit
btfsc STATUS, Z
	call its_three
addwf slit

movlw 0x02
subwf slit
btfsc STATUS, Z
	call its_two
addwf slit
 
micro571 said:
Nigel mentioned something about SUB or XOR? Do I have to have registers pre-filled with 0x01, 0x02, 0x03... then compare the values to slit ??

You have a register called Slit, which contains the number of switches that are turned ON - you want to check if either the value equals a certain number, or is greater than a certain number.

Try looking at . These 8 bit examples use ADDLW rather than SUBLW, simply because 12 bit PIC's don't have SUBLW, so they use complement subtraction.

If you check my tutorials, various ones do similar comparisons, check the IR receiver ones - these check the incoming IR code and turn on the respective LED's.
 
One thing I didn't think to mention earlier, you could also do this with a simple 'jump table' - the table would have five entries, each jumping to the routine required for that value.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top