Jump to content

Namely for the PIC16F887. I know x86, but PIC seems to be quite different. I have it set up correctly, but I need to know how to send a signal from certain ports to light up an LED. Can anybody help? All examples online use C, but that's not an option right now.

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to comment
https://linustechtips.com/topic/835593-does-anybody-here-know-pic-assembly/
Share on other sites

Link to post
Share on other sites

A crash course, here goes:

 

The instruction set is quite simple, consisting out of only about 35 instructions with easy to remember mnemonics. The real gotcha's are in the periphery and memory layout. For example, the RAM is divided into banks, 256 bytes each, and it's up to you to make sure you're in the right bank when accessing a RAM address. Some devices might require turning off some peripherals that are turned on by default, such as analog comparators, in order to access the corresponding IO pins in the normal way as these peripherals will take control of the pins when activated.

 

The instruction set is documented in detail in chapter 15 of the datasheet.

 

As you're probably already aware, this is a 8-bit device so all operations work on a single byte.

First, there is the one and only CPU register, called 'W'.

Secondly, RAM addresses that are free for general use are called 'File' in the microchip slang.

RAM addresses that map some hardware peripheral are called 'Special function registers', or 'SFR'.

 

Many instructions come in duo's, one to work with variable data and one to work with a literal. For example

'MOVFW' moves the contents of a file to W. While 'MOVLW' moves a literal to W.

 

Branches are performed with a test instruction that skips the next instruction when a condition is met. For example 'BTFSS' Bit test file skip if set tests a bit in the given file and skips the next instruction if the bit is set.

 

This allows you to test the flags of the CPU status register in order to perform certain functions that have their own instruction on x86. For example, testing if 2 variables are equal could be performed by XOR'ing them and then testing the Zero status flag, because XOR'ing 2 equal numbers results in 0.

 

For driving a LED we must first know that the PIC's IO pins can be Tri-stated. Which means a IO pin can have any of 3 states (there are exceptions, some pins can only sink current for example and not source it):

  • A output - driven high (to VCC)
  • A output - driven low (to VSS)
  • A input - high impedance

At startup, all IO pins default to inputs. In order to drive a led we must first make the required IO pins outputs. This is done by clearing the corresponding bit in the IO port's TRIS register. Only then can we control the pin using the PORT register.

 

A small example:

    LIST	p=16F887		;inform assembler which device we're using.
#include "P16F887.INC"			;include file lets us use names in stead of raw addresses and magic numbers.
 
 org 0x0000				;All code that follows to be placed at program memory address 0,
					;The device's reset vector.
 
    BANKSEL TRISB			;Generates bank selection code for bank 1 - refer to datasheet figure 2-6
    BCF TRISB, 4			;Bit Clear File - clears bit 4 in TRISB, making PORTB4 a output.
    BANKSEL PORTB			;Generates bank selection code for bank 0 
    BSF PORTB, 4			;Bit Set File - sets bit 4 in PORTB, driving the pin high.
    GOTO $				;$ is shorthand for current address, so this loops endlessly
 
 END

 

This code will make the pin at PORTB 4 high and then loop endlessly.

One important thing to do is to set the correct configuration bits for your project. In MPLABX these are found in 'Window'->'PIC memory views'->'configuration bits'. A window will pop up that'll let you choose your configuration and generate the required source code to paste into your source file. This is important because selecting a incorrect oscillator setting that does not match the actual hardware, will make the device fail to run.

Link to post
Share on other sites

My advice would be to just download MPLAB X or the ancient MPLAB (you can still download it from microchip's ftp server) and write your code in C  and compile and then just look at the generated assembly code

 

See http://www.microchip.com/development-tools

 

There's plenty of tutorials and guides (and even the datasheets have plenty of examples and information) that teach you how to blink a led without having to write assembly code.

 

 

Link to post
Share on other sites

3 hours ago, Unimportant said:

A crash course, here goes:

 

The instruction set is quite simple, consisting out of only about 35 instructions with easy to remember mnemonics. The real gotcha's are in the periphery and memory layout. For example, the RAM is divided into banks, 256 bytes each, and it's up to you to make sure you're in the right bank when accessing a RAM address. Some devices might require turning off some peripherals that are turned on by default, such as analog comparators, in order to access the corresponding IO pins in the normal way as these peripherals will take control of the pins when activated.

 

The instruction set is documented in detail in chapter 15 of the datasheet.

 

As you're probably already aware, this is a 8-bit device so all operations work on a single byte.

First, there is the one and only CPU register, called 'W'.

Secondly, RAM addresses that are free for general use are called 'File' in the microchip slang.

RAM addresses that map some hardware peripheral are called 'Special function registers', or 'SFR'.

 

Many instructions come in duo's, one to work with variable data and one to work with a literal. For example

'MOVFW' moves the contents of a file to W. While 'MOVLW' moves a literal to W.

 

Branches are performed with a test instruction that skips the next instruction when a condition is met. For example 'BTFSS' Bit test file skip if set tests a bit in the given file and skips the next instruction if the bit is set.

 

This allows you to test the flags of the CPU status register in order to perform certain functions that have their own instruction on x86. For example, testing if 2 variables are equal could be performed by XOR'ing them and then testing the Zero status flag, because XOR'ing 2 equal numbers results in 0.

 

For driving a LED we must first know that the PIC's IO pins can be Tri-stated. Which means a IO pin can have any of 3 states (there are exceptions, some pins can only sink current for example and not source it):

  • A output - driven high (to VCC)
  • A output - driven low (to VSS)
  • A input - high impedance

At startup, all IO pins default to inputs. In order to drive a led we must first make the required IO pins outputs. This is done by clearing the corresponding bit in the IO port's TRIS register. Only then can we control the pin using the PORT register.

 

A small example:


    LIST	p=16F887		;inform assembler which device we're using.
#include "P16F887.INC"			;include file lets us use names in stead of raw addresses and magic numbers.
 
 org 0x0000				;All code that follows to be placed at program memory address 0,
					;The device's reset vector.
 
    BANKSEL TRISB			;Generates bank selection code for bank 1 - refer to datasheet figure 2-6
    BCF TRISB, 4			;Bit Clear File - clears bit 4 in TRISB, making PORTB4 a output.
    BANKSEL PORTB			;Generates bank selection code for bank 0 
    BSF PORTB, 4			;Bit Set File - sets bit 4 in PORTB, driving the pin high.
    GOTO $				;$ is shorthand for current address, so this loops endlessly
 
 END

 

This code will make the pin at PORTB 4 high and then loop endlessly.

One important thing to do is to set the correct configuration bits for your project. In MPLABX these are found in 'Window'->'PIC memory views'->'configuration bits'. A window will pop up that'll let you choose your configuration and generate the required source code to paste into your source file. This is important because selecting a incorrect oscillator setting that does not match the actual hardware, will make the device fail to run.

Thanks for the explanation and example! To switch to RA0, I'd just switch TRISB and PORTB to TRISA and PORTA right?

 

I'd like to add a switch to let's say... RB0 to turn off RA0 when pressed down. How exactly would this be done?
 

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

7 hours ago, Noirgheos said:

 To switch to RA0, I'd just switch TRISB and PORTB to TRISA and PORTA right?

That, and the '4' to '0' off course, yes.

7 hours ago, Noirgheos said:

I'd like to add a switch to let's say... RB0 to turn off RA0 when pressed down. How exactly would this be done?

First, one must know that a high impedance input pin should always be in a known state on the hardware side. That is why your typical pushbutton circuit looks like this:

pullup.png

When the button is pressed the input pin is connected to ground making it '0'. When the switch is released the pin is pulled to VCC by the resistor, making it '1'. Never leave a input pin 'floating', in case you're building the hardware yourself. It also explains why most pushbutton logic is reversed, checking for '0' to detect a press.

 

The code:

    LIST	p=16F887		
#include "P16F887.INC"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL PORTB			 
  
Loop:

    BTFSC PORTB, 0			;Test bit 0 in PORTB, skip next instruction if bit is clear	
    GOTO ButtonPressed

    BSF PORTA, 0			;If button not pressed, set PORTA0 high, turning on the LED
    GOTO Loop

ButtonPressed:

    BCF PORTA, 0			;Otherwise, turn off the LED by making PORTA0 low.
    GOTO Loop		
 
 END

Some considerations:

  • I'm assuming the LED's anode is connected to the output pin thus setting the pin high turns on the LED and setting it low turns it off. But the LED could be connected to the output pin with it's cathode as well, which would invert the function. In that case you'll have to invert the logic in the code.
  • If you're not building the hardware yourself, the kit designer could be relying on the PIC's built in pull up resistors on PORTB. In stead of them using a external resistor to pull-up the push button as per the schematic, they could be relying on a set of pull-ups that is built into the PIC on PORTB for this exact purpose. In this case you'd have to add a few lines of code to enable those pull-ups because they're not enabled by default.
  • Realize that a real push-button has contact bounce. When the switch opens or closes it isn't a clean transition of state but a series of oscillations as the contacts inside the button "bounce". While irrelevant for this little example, it can be relevant if you perform certain logic on the switch input. For example, if you want to count the number of times the button is pressed, you'd have to add code to "debounce" the input, otherwise a single press can register as tens of presses. Debouncing can be as simple as just polling the switch state once every 100ms. The slow polling speed effectively acting like a low pass filter.
Link to post
Share on other sites

4 hours ago, Unimportant said:

That, and the '4' to '0' off course, yes.

First, one must know that a high impedance input pin should always be in a known state on the hardware side. That is why your typical pushbutton circuit looks like this:

pullup.png

When the button is pressed the input pin is connected to ground making it '0'. When the switch is released the pin is pulled to VCC by the resistor, making it '1'. Never leave a input pin 'floating', in case you're building the hardware yourself. It also explains why most pushbutton logic is reversed, checking for '0' to detect a press.

 

The code:


    LIST	p=16F887		
#include "P16F887.INC"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL PORTB			 
  
Loop:

    BTFSC PORTB, 0			;Test bit 0 in PORTB, skip next instruction if bit is clear	
    GOTO ButtonPressed

    BSF PORTA, 0			;If button not pressed, set PORTA0 high, turning on the LED
    GOTO Loop

ButtonPressed:

    BCF PORTA, 0			;Otherwise, turn off the LED by making PORTA0 low.
    GOTO Loop		
 
 END

Some considerations:

  • I'm assuming the LED's anode is connected to the output pin thus setting the pin high turns on the LED and setting it low turns it off. But the LED could be connected to the output pin with it's cathode as well, which would invert the function. In that case you'll have to invert the logic in the code.
  • If you're not building the hardware yourself, the kit designer could be relying on the PIC's built in pull up resistors on PORTB. In stead of them using a external resistor to pull-up the push button as per the schematic, they could be relying on a set of pull-ups that is built into the PIC on PORTB for this exact purpose. In this case you'd have to add a few lines of code to enable those pull-ups because they're not enabled by default.
  • Realize that a real push-button has contact bounce. When the switch opens or closes it isn't a clean transition of state but a series of oscillations as the contacts inside the button "bounce". While irrelevant for this little example, it can be relevant if you perform certain logic on the switch input. For example, if you want to count the number of times the button is pressed, you'd have to add code to "debounce" the input, otherwise a single press can register as tens of presses. Debouncing can be as simple as just polling the switch state once every 100ms. The slow polling speed effectively acting like a low pass filter.

This was my breadboard last I had a PICKIT3 to program it (yesterday). Brown switch has the squiggly purple wire to RB0 and the red wire to ground (will fix later, both colour and placement) and is missing a resistor according to the diagram you posted. The green LED is my RA0 portion. 

 

Unfortunately I won't be able to test this until I could get my hands on a PICKIT3 again. Thanks so much for helping me out.

Snapchat-383578342.jpg

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

9 hours ago, Noirgheos said:

<snip>

Looks good, just needs the extra pull-up resistor on the switch. Something like 100K will be fine and is typical.

 

Since I don't see any oscillator on your breadboard, such as a crystal, I assume you're using the internal RC oscillator. I'd like to make sure you know you have to set the configuration bits for the device correctly to activate the internal oscillator, failing to do so will prevent the device from running at all.

Link to post
Share on other sites

2 minutes ago, Unimportant said:

Looks good, just needs the extra pull-up resistor on the switch. Something like 100K will be fine and is typical.

 

Since I don't see any oscillator on your breadboard, such as a crystal, I assume you're using the internal RC oscillator. I'd like to make sure you know you have to set the configuration bits for the device correctly to activate the internal oscillator, failing to do so will prevent the device from running at all.

I've turned on the internal oscillator with clock output, turned off the Watchdog Timer, turned off Internal/External Switchover, and turned off the Fail-Safe clock monitor. I generated the output and used an oscilloscope and found a square wave, which makes sense. I'll try the code as soon as I have time. 

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

On 9/17/2017 at 5:19 PM, Unimportant said:

Looks good, just needs the extra pull-up resistor on the switch. Something like 100K will be fine and is typical.

 

Since I don't see any oscillator on your breadboard, such as a crystal, I assume you're using the internal RC oscillator. I'd like to make sure you know you have to set the configuration bits for the device correctly to activate the internal oscillator, failing to do so will prevent the device from running at all.

Code didn't work. LED at RA0 stays lit no matter what logic is getting sent from the switch to RB0. I believe it has something to do with ANSEL or not completely setting RB0 up properly?

 

My teacher also told me that it's possible to do in 1-3 lines. Do you have any idea how?

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

15 hours ago, Noirgheos said:

Code didn't work. LED at RA0 stays lit no matter what logic is getting sent from the switch to RB0. I believe it has something to do with ANSEL or not completely setting RB0 up properly?

You're right. I did a little reading in the datasheet and it turns out ANSEL and ANSELH allow choosing between analog input or digital I/O per pin for AN0 - AN13. It's set to analog input by default. According to the datasheet that should make no difference for outputs (AN0 in this case) but it will make digital reads always return 0 (RB0 will always read 0 or "button pressed" in this case).

 

Try following updated code, which clears both ANSEL and ANSELH, turning pins AN0-AN13 into digital I/O.

This code works in the simulator, which is the best I can do, I don't have any 16f887's lying around.

    LIST	p=16F887		
#include "p16f887.inc"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL ANSEL
    CLRF ANSEL				;Disable analog input functionality on AN0-AN7...
    CLRF ANSELH				;and AN8-AN13, making all pins digital I/O.
    BANKSEL PORTB			 
  
Loop:

    BTFSC PORTB, 0			;Test bit 0 in PORTB, skip next instruction if bit is clear	
    GOTO ButtonPressed

    BSF PORTA, 0			;If button not pressed, set PORTA0 high, turning on the LED
    GOTO Loop

ButtonPressed:

    BCF PORTA, 0			;Otherwise, turn off the LED by making PORTA0 low.
    GOTO Loop		
 
 END

 

15 hours ago, Noirgheos said:

My teacher also told me that it's possible to do in 1-3 lines. Do you have any idea how?

The initial 6 setup lines can't be shortened imo. The setup has to be done and the BANKSEL's are required.

 

I don't really see a way to get the loop body any shorter. At least not without taking any shortcuts. Such shortcuts would include affecting pins we're not using:

    LIST	p=16F887		
#include "p16f887.inc"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL ANSEL
    CLRF ANSEL				;Disable analog input functionality on AN0-AN7...
    CLRF ANSELH				;and AN8-AN13, making all pins digital I/O.
    BANKSEL PORTB			 
  
Loop:

    MOVFW PORTA				;Copy PORTA to W.
    XORWF PORTB, W			;XOR W with PORTB, store result in W
    XORLW b'00000001'			;XOR W with binary 00000001, this toggles bit 0.
    XORWF PORTA, F			;WOR W with PORTB, store result in PORTB.
    GOTO Loop
 
 END

It's only 1 instruction shorter but it also possibly affects the other, unused, PORTA pins - that's considered bad style and a possible source of bugs.

If you do find a good way of shortening the program, let me know, I'm curious - I don't see a valid way.

Link to post
Share on other sites

5 hours ago, Unimportant said:

You're right. I did a little reading in the datasheet and it turns out ANSEL and ANSELH allow choosing between analog input or digital I/O per pin for AN0 - AN13. It's set to analog input by default. According to the datasheet that should make no difference for outputs (AN0 in this case) but it will make digital reads always return 0 (RB0 will always read 0 or "button pressed" in this case).

 

Try following updated code, which clears both ANSEL and ANSELH, turning pins AN0-AN13 into digital I/O.

This code works in the simulator, which is the best I can do, I don't have any 16f887's lying around.


    LIST	p=16F887		
#include "p16f887.inc"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL ANSEL
    CLRF ANSEL				;Disable analog input functionality on AN0-AN7...
    CLRF ANSELH				;and AN8-AN13, making all pins digital I/O.
    BANKSEL PORTB			 
  
Loop:

    BTFSC PORTB, 0			;Test bit 0 in PORTB, skip next instruction if bit is clear	
    GOTO ButtonPressed

    BSF PORTA, 0			;If button not pressed, set PORTA0 high, turning on the LED
    GOTO Loop

ButtonPressed:

    BCF PORTA, 0			;Otherwise, turn off the LED by making PORTA0 low.
    GOTO Loop		
 
 END

 

The initial 6 setup lines can't be shortened imo. The setup has to be done and the BANKSEL's are required.

 

I don't really see a way to get the loop body any shorter. At least not without taking any shortcuts. Such shortcuts would include affecting pins we're not using:


    LIST	p=16F887		
#include "p16f887.inc"			
 
 org 0x0000				
 
    BANKSEL TRISA			
    BCF TRISA, 0			;Make pin PORTA0 output, PORTB0 is a input by default.
    BANKSEL ANSEL
    CLRF ANSEL				;Disable analog input functionality on AN0-AN7...
    CLRF ANSELH				;and AN8-AN13, making all pins digital I/O.
    BANKSEL PORTB			 
  
Loop:

    MOVFW PORTA				;Copy PORTA to W.
    XORWF PORTB, W			;XOR W with PORTB, store result in W
    XORLW b'00000001'			;XOR W with binary 00000001, this toggles bit 0.
    XORWF PORTA, F			;WOR W with PORTB, store result in PORTB.
    GOTO Loop
 
 END

It's only 1 instruction shorter but it also possibly affects the other, unused, PORTA pins - that's considered bad style and a possible source of bugs.

If you do find a good way of shortening the program, let me know, I'm curious - I don't see a valid way.

My teacher also told me to make a pull down resistor? Basically as it is in the picture. Am I correct in believing this would slightly change the code?

Snapchat-1009987580.jpg

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

19 hours ago, Noirgheos said:

My teacher also told me to make a pull down resistor? Basically as it is in the picture. Am I correct in believing this would slightly change the code?

In the original, branch based, program it simply means inverting the logic (only loop body shown - we don't have to keep repeating the boilerplate):

Loop:

    BTFSS PORTB, 0			;<== changed from BTFSC, we now skip next instruction if bit is set in stead of clear.
    GOTO NotPressed

    BSF PORTA, 0			
    GOTO Loop

NotPressed:

    BCF PORTA, 0
    GOTO Loop

If you really wanted the shortest solution possible this would now allow simply copying PORTB to PORTA since we no longer need to invert the signal:

Loop:

    MOVFW PORTB				;Copy PORTB to W.
    MOVWF PORTA				;Copy W to PORTA.
    GOTO Loop

If PORTB bit 0 is set, indicating the button is pressed, then after copying PORTA, 0 will also be set - lighting the LED. If PORTB, 0 were clear, indicating the button is not pressed, then after the copy PORTA, 0 will also be cleared, turning off the LED. While this is very short it still has the problem it copies ALL the PORTB bits to PORTA thus affecting all other PORTA pins aswell. That's not a problem is this application, since the other PORTA pins are unused but I still consider it bad style and prefer the first solution which only affects the relevant bits.

Link to post
Share on other sites

3 minutes ago, Unimportant said:

In the original, branch based, program it simply means inverting the logic (only loop body shown - we don't have to keep repeating the boilerplate):


Loop:

    BTFSS PORTB, 0			;<== changed from BTFSC, we now skip next instruction if bit is set in stead of clear.
    GOTO NotPressed

    BSF PORTA, 0			
    GOTO Loop

NotPressed:

    BCF PORTA, 0
    GOTO Loop

If you really wanted the shortest solution possible this would now allow simply copying PORTB to PORTA since we no longer need to invert the signal:


Loop:

    MOVFW PORTB				;Copy PORTB to W.
    MOVWF PORTA				;Copy W to PORTA.
    GOTO Loop

If PORTB bit 0 is set, indicating the button is pressed, then after copying PORTA, 0 will also be set - lighting the LED. If PORTB, 0 were clear, indicating the button is not pressed, then after the copy PORTA, 0 will also be cleared, turning off the LED. While this is very short it still has the problem it copies ALL the PORTB bits to PORTA thus affecting all other PORTA pins aswell. That's not a problem is this application, since the other PORTA pins are unused but I still consider it bad style and prefer the first solution which only affects the relevant bits.

So after all those initial BANKSELs and CLRFs, either one of these should work? I'll be able to try on Monday.

 

BTW, you've been a great help. I'm starting to get MPASM a lot better now. For the future, do you have something like Steam? Where it'd be easy to contact you through? I have a feeling that the more projects I take on, the more questions will arise.

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

5 minutes ago, Noirgheos said:

So after all those initial BANKSELs and CLRFs, either one of these should work? I'll be able to try on Monday.

 

BTW, you've been a great help. I'm starting to get MPASM a lot better now. For the future, do you have something like Steam? Where it'd be easy to contact you through? I have a feeling that the more projects I take on, the more questions will arise.

Both should work yes, they do in the simulator - I don't happen to have any 16f887's, but microchip's simulator has proven to be very reliable.

 

No steam, but this forum allows for private messages.

Link to post
Share on other sites

Just now, Unimportant said:

Both should work yes, they do in the simulator - I don't happen to have any 16f887's, but microchip's simulator has proven to be very reliable.

 

No steam, but this forum allows for private messages.

Alright, thanks! I'll move on to PIC24s later once I feel more comfortable with PIC16. 

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

On 9/23/2017 at 12:07 PM, Unimportant said:

Both should work yes, they do in the simulator - I don't happen to have any 16f887's, but microchip's simulator has proven to be very reliable.

 

No steam, but this forum allows for private messages.

Code still didn't work.

 

This is one that I got working:

 

    BANKSEL ANSEL
    CLRF ANSEL
    BANKSEL ANSELH
    CLRF ANSELH
    BANKSEL TRISA
    CLRF TRISA
    BANKSEL TRISB
    MOVLW 01h
    MOVWF TRISB
    ;BANKSEL PORTA
    ;MOVLW 01h
    ;MOVWF PORTA
LOOP
    BANKSEL PORTB
    BTFSS PORTB, 0
    GOTO ON
    BANKSEL PORTA
    CLRF PORTA
    GOTO LOOP
ON
    BANKSEL PORTA
    MOVLW 01h
    MOVWF PORTA
    
    GOTO LOOP

 

 

i7 6700K @ Stock (Yes I know) ~~~ Corsair H80i GT ~~~ GIGABYTE G1 Gaming Z170X Gaming 7 ~~~ G. Skill Ripjaws V 2x8GB DDR4-2800 ~~~ EVGA ACX 3.0 GTX 1080 SC @ 2GHz ~~~ EVGA P2 850W 80+ Platinum ~~~ Samsung 850 EVO 500GB ~~~ Crucial MX200 250GB ~~~ Crucial M500 240GB ~~~ Phanteks Enthoo Luxe

Link to post
Share on other sites

15 hours ago, Noirgheos said:

Code still didn't work.

 

This is one that I got working:

 

    BANKSEL ANSEL
    CLRF ANSEL
    BANKSEL ANSELH
    CLRF ANSELH
    BANKSEL TRISA
    CLRF TRISA
    BANKSEL TRISB
    MOVLW 01h
    MOVWF TRISB
    ;BANKSEL PORTA
    ;MOVLW 01h
    ;MOVWF PORTA
LOOP
    BANKSEL PORTB
    BTFSS PORTB, 0
    GOTO ON
    BANKSEL PORTA
    CLRF PORTA
    GOTO LOOP
ON
    BANKSEL PORTA
    MOVLW 01h
    MOVWF PORTA
    
    GOTO LOOP

 

 

Good that you got it working :)

 

Extremely weird tough - the working code basically only adds some superfluous banksel's.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×