-----Original Message----- From: pic microcontroller discussion list [mailto:PICLIST@MITVMA.MIT.EDU] On Behalf Of Richard S Sent: Sunday, March 14, 2004 10:24 AM To: PICLIST@MITVMA.MIT.EDU Subject: [PIC:] Better understanding of basic assembly code commands needed I appreciate all the tremendous help. I have some great examples and tutorials from piclist and some from others that are invaluable to me in trying to learn the right way to program assembly. I have now had a chance to get through my first pass of the Data sheet for my 16f876 and now can understand a good deal of it given the great help here. This raised a few questions that I can't answer myself as they are related to "thinking ahead" to more complex programs something only experience can give you. Now that all of you helped me get my binary counter working with two different code examples I have a few questions. Although I know these are simple I am trying to understand the basic foundation of "good practice" and "plan for the future" to avoid problems. Please also correct any misstatements I may have made based on my "understanding" I can see how these both do the same thing by telling the compiler to switch to bank1 where the trisa register is. I verified for myself that indeed the program does not work without this information First method: banksel trisa ;switch to bank1 sets status to b'01' Second method: BSF STATUS,RP0 ;switch to bank1 sets status to b'01' Question: I could not find reference to where someone knew to use the "banksel trisa" line of code where does this come from? Wondering if there are other such commands that are useful? Is there an advantage/importance of one way over the other? ********* I think that banksel is just an assembler macro that automates the process of finding the bank of a given variable and setting the RP1:0 bits accordingly. I think it always sets or clears both bits even if it is unnecessary, so it is probably very slightly less efficient than doing it intelligently by hand, but the risk of error is also very significantly less. I have never used it myself but probably unless you have a specific reason not to (need to save every last cycle) it is best to use banksel. ********** Both of the following work for my simple binary counter: First method: incf portb_tmp,w ;inc portb_tmp and move to W. movwf portb_tmp ;save incremented value movwf portb ; move to LEDs. Second method: incf portb,f ;add 1 to port B, (next binary byte) Question I see many talk about the use of shadow variables like "portb_tmp" but not sure when it should be used? It was explaind some to me before but I just still do not understand but know it must be important in more complex programs. ******* The problem with doing these kinds of instructions directly to a PORT register is that the instruction is a RMW (read-modify-write). That is, it READs the value from the port _pins_ (not the registers), MODIFIES it, and WRITES it back. You can get into trouble if for example you are driving a capacitive load (voltage changes slowly b/c the capacitance needs to be charged as the voltage increases and discharged as voltage decreases) if you do two of these instructions in quick succession. Say the first will tell the PIC to drive a given pin high that is currently low. If you run another instruction to do something else to the port before the PIC has had time to charge the capacitance connected to the pin that is being driven high, that pin will be sampled LOW and it will act as if your first instruction never ran. Example: ; setup clrf PORTB banksel TRISB clrf TRISB banksel PORTB ; PORTB is setup with all pins LOW ; problem area bsf PORTB,0 ; PIC reads all zeroes and will start to drive RB0 high. If ; there is a capacitive load on the pin this may take awhile bsf PORTB,1 ; If RB0 hasn't been driven high yet, your PIC will still read ; all zeroes from PORTB (remember it reads the PINS not the ; latches) and start to drive RB1 high. ; Here you would like to have PORTB = 00000011 but if there ; is enough of a capacitive load on RB0 you will likely end up with ; PORTB = 00000010 If you want to experiment try running the above code with an LED + resistor connected to RB0 and RB1 and also with a (approx) 1uF capacitor from the RB0 pin to ground and from the RB1 pin to ground. Unless your PIC is running really slowly you should end up with only RB1 lit. One thing you can do in this instance (doesn't work with your incf question) is test the pin and WAIT for it to get to your desired value before running the next instruction. i.e. bsf PORTB,0 btfss PORTB,0 goto $-1 ; goes back one instruction (to btfss PORTB,0) This will loop until the pin is sampled high. I usually will then wait a little longer just to make sure things have settled before going on. If you have much of this happening, shadow registers are probably the way to go though and if you are doing something other than bsf,bcf instructions shadows are probably the only way to fly. And they will always be faster than waiting around (in my last app I didn't care as I was powering up external peripherals so it was really an advantage to wait until the pin was high before continuing). ********** Now I think I know this one but want to make sure. Both of the following do the same thing if all I want to do is set all PORTA pins to all outputs so there is no advantage of one of these over the other in this case. Is this correct? The first method would allow for me to set some of the PORTA as input by using say movlw B'00001111' so I am not setting all PORTA as output where "clrf trisa" I can not do this. Method 1: movlw B'00000000' BSF STATUS,RP0 ;switch to bank1 sets status to b'01' MOVWF TRISA ; make all bit of PORT A outputs Method 2: banksel trisa ;switch to bank1 clrf trisa ;set as all outputs ****** I think you are on this one. Clrf uses one less instruction in the case where you want to use all zeroes, but it lacks flexibility. One cycle probably isn't the end of the world so you might just want to be consistent and use movlw/movwf all the time, but I don't think there's a clear answer either way on this one. Personal preference rules here. ****** Thanks for the help sorry for so many basic questions. I just want to make sure I have a sound foundation to move on with. Regards, Richard -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details. -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.