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.

Do help me analyze this program in PIC16F84A,,

Status
Not open for further replies.
You code looks fine except for the missing include file.

If it is working in the simulator and not in hardware then the problem could be your external oscillator. Have you got the correct resistor/capacitor combination to get a 4MHz oscillator. I'm not even sure if an RC oscillator can go that fast.

The other thing that may be wrong is you may not be waiting long enough. Isn't your delay routine 5 minutes long? I would change this to 1 second until you get something working.

Mike.


Why not use internal oscillator....? That way you don't have to bother with the external clock, and associated circuit.
 
-I have here a handbook,, Am I right if I say that the other pin of the crystal is to be supplied with 5V, connect it with the +of the 0.1uf capacitor. Then to the 14th pin of the PIC, then ground the leg of the capacitor? And the other pin of the crystal is to pin 16 of the PIC.
That should be fine as long as you connect to the correct pins on the oscillator. By ground, I'll assume you know that it connects to pin 5 of the PIC also. The 4th pin of the oscillator may be a tuning pin. It depends on the type of oscillator. If you have problems, post the part number of the oscillator. The datasheet is on the net somewhere for me to see.
-Was that all? Also changing the config..
-Mine is 4 Mhz crystal oscillator.
That should be fine. I believe the code you have was written for a PIC with a 4Mhz oscillator.
RobertD said:
Why not use internal oscillator....?
Yes, that would be the simplest thing. But the 16F84A doesn't have that option. The 16F628A does and is a drop in replacement for the 16F84A with some minor code changes. There is so much code on the net for the classic F84 that noobs still get tricked into using it. :D Even the 16F628A is getting a little long in the tooth.
 
Last edited:
-I have not tried to connect a clock oscillator,, I have an crystal oscillator here. Is clock oscillator the same as crystal? In the handbook the clock oscillator has 4 pins but the crystal has only two.. Do I need other things for it to work?
My mistake. I thought you said you had an oscillator. You have a crystal if it only has 2 pins. When combined with the internal circuitry of the PIC and some caps, you have a crystal oscillator. For a 4Mhz crystal you would connect it like this:
**broken link removed**
You could use 15-33pf capacitors if that's what you have in junk box. Just make the pair the same value.
Use this config instead:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

Original config I gave you:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

4Mhz is on the borderline between using the HS config and the XT.
 
Last edited:
If your oscillator has two pins then you don't have an oscillator, you have a crystal. This is good, you connect your crystal to pins 15 and 16 and connect two small (30pf) capacitor from pins 15 and 16 to ground.

Edit, kcriste beat me to it and he remembered the config setting which I forgot.:eek:

Mike.
 
Last edited:
I'm just going to add comments into the code to make it really, blindingly clear what's going on. Painstakingly commented for your pleasure. Some scrolling may be necessary.

Code:
d1	equ	0x0D     //Making d1 equal 13
d2	equ	0x0E     //Making d2 equal 14
d3	equ	0x0F     //Making d3 equal 15
d4	equ	0x10     //Making d4 equal 16

	org	0X000   //Set the following code to start at Address 0
	goto	Init       //Jump to the beginning of the code. 
                           //Mainly done as an interrupt thing, but not *really* 
                           //needed unless you use interrupts
	org	0X004   //Setting the code to start at Address 4
	retfie            //If an interrupt flag is set, it automatically jumps to 4.
                           //Not really needed if you're careful and make sure you're
                           //not setting up any Interrupts.
Init	
	
	bsf	STATUS,RP0 //Switch to bank 1
	clrf	TRISB          //Set all PORTB pins to output
	clrf	TRISA          //Set all PORTA pins to output
	bcf	STATUS,RP0 //Switch back to bank 0.

	clrf	PORTA	 //Make sure PORTA pins are pulled low.
	clrf	PORTB        //And PORTB pins, too.

Main	
	
	bsf	PORTB,0     //Pull PORTB's first pin (RB0) high.
	call	Del5M        //Call the Del5M subroutine. Skip the rest of Main for
                                //now.
	bcf	PORTB,0     //Welcome back to Main. Assuming all the dX registers
                                //(d1, d2, d3, and d4) are zeroed out, pull RB0 low
                                //again.
	call	Del5M        //And now we go back to set up all the values and
                                //do that decfsz nonsense again. This time when it's
	goto	Main          //done, we go back to the beginning of Main and
                                //pull RB0 high again. And it just repeats that like
                                //indefinitely.
Del5M	

	movlw	0x54  //Move the decimal 84 into W
	movwf	d1     //Move W into address defined in the EQU directive.
	movlw	0xA1  //Just more moving values
	movwf	d2     //into registers. Doot de doo.
	movlw	0xFD  //Yep, more of the same.
	movwf	d3      //Weather's pretty nice today.
	movlw	0x02  //Maybe I should mow the lawn.
	movwf	d4     //Okay, this part is done now.

Delay_0

	decfsz	d1, f //Here we decrease the value in the given register
                               //(d1 in this case). the ",f" afterwards just tells it
                               //to store the result back in the register it changed.
                               //If the register, however, is zero, the instruction
                               //makes the PIC skip the next instruction
	goto	$+2          //This instruction just says to jump two instructions.
                               //The $ value just means "current address", so one
                               //could also say "goto $-3" to go back 3 addresses,
                               //if the code needed that.
	decfsz	d2, f //Same old decfsz. Kind of a weird program flow going
	goto	$+2          //on here, but whatever floats their boat.
	decfsz	d3, f //It's early, I should probably get some breakfast.
	goto	$+2          //I've got some strawberry poptarts, that might do.
	decfsz	d4, f //Okay, almost done with this part.
	goto	Delay_0     //If d4 isn't zero yet, you have to go back to the
                               //beginning of this block of code and keep decfsz-ing
                               //until everything is zero. Then we move onto the
                               //next part.
			;5 cycles
	goto	$+1          //These are just junk instructions, used because they
	goto	$+1          //take up 2 cycles each,
	nop                  //when NOP only takes up 1 cycle and also does
	return               //nothing. Our Return here just makes us jump back
                         //to the main block. Let's go, shall we? Go back up.

	end
 
Code:
	movlw	0xA1  //Just more moving values
	movwf	d2     //into registers. Doot de doo.
	movlw	0xFD  //Yep, more of the same.
	movwf	d3      //Weather's pretty nice today.
	movlw	0x02  //Maybe I should mow the lawn.
	movwf	d4     //Okay, this part is done now.
Just checking to see if anyone is paying attention eh? ;)
 
-Thanks I get it,, I'll try to do the circuit and load the program,, I'll post message if whatever happens.
-Thanks for the link... it made all things clear of what Pommie is saying.

My mistake. I thought you said you had an oscillator. You have a crystal if it only has 2 pins. When combined with the internal circuitry of the PIC and some caps, you have a crystal oscillator. For a 4Mhz crystal you would connect it like this:
**broken link removed**
You could use 15-33pf capacitors if that's what you have in junk box. Just make the pair the same value.
Use this config instead:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

Original config I gave you:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

4Mhz is on the borderline between using the HS config and the XT.
 
connection of crystal

-So this two pins thing is only a crystal and not an oscillator,, I could make a crystal oscillator if I make the circuit base on KCHRISTE's link as enforcement of the circuit.

-Thank you very much..

If your oscillator has two pins then you don't have an oscillator, you have a crystal. This is good, you connect your crystal to pins 15 and 16 and connect two small (30pf) capacitor from pins 15 and 16 to ground.

Edit, kcriste beat me to it and he remembered the config setting which I forgot.:eek:

Mike.
 
comments on codes

-Thanks Artemis for the comments on the codes. Some codes are familiar to me,, most are my first time (honestly). I'll go over with the codes and study them.

-I hope the codes are running correctly in hardware.

-More thanks also to those who help in making the crystal circuit.

I'm just going to add comments into the code to make it really, blindingly clear what's going on. Painstakingly commented for your pleasure. Some scrolling may be necessary.

Code:
d1	equ	0x0D     //Making d1 equal 13
d2	equ	0x0E     //Making d2 equal 14
d3	equ	0x0F     //Making d3 equal 15
d4	equ	0x10     //Making d4 equal 16

	org	0X000   //Set the following code to start at Address 0
	goto	Init       //Jump to the beginning of the code. 
                           //Mainly done as an interrupt thing, but not *really* 
                           //needed unless you use interrupts
	org	0X004   //Setting the code to start at Address 4
	retfie            //If an interrupt flag is set, it automatically jumps to 4.
                           //Not really needed if you're careful and make sure you're
                           //not setting up any Interrupts.
Init	
	
	bsf	STATUS,RP0 //Switch to bank 1
	clrf	TRISB          //Set all PORTB pins to output
	clrf	TRISA          //Set all PORTA pins to output
	bcf	STATUS,RP0 //Switch back to bank 0.

	clrf	PORTA	 //Make sure PORTA pins are pulled low.
	clrf	PORTB        //And PORTB pins, too.

Main	
	
	bsf	PORTB,0     //Pull PORTB's first pin (RB0) high.
	call	Del5M        //Call the Del5M subroutine. Skip the rest of Main for
                                //now.
	bcf	PORTB,0     //Welcome back to Main. Assuming all the dX registers
                                //(d1, d2, d3, and d4) are zeroed out, pull RB0 low
                                //again.
	call	Del5M        //And now we go back to set up all the values and
                                //do that decfsz nonsense again. This time when it's
	goto	Main          //done, we go back to the beginning of Main and
                                //pull RB0 high again. And it just repeats that like
                                //indefinitely.
Del5M	

	movlw	0x54  //Move the decimal 84 into W
	movwf	d1     //Move W into address defined in the EQU directive.
	movlw	0xA1  //Just more moving values
	movwf	d2     //into registers. Doot de doo.
	movlw	0xFD  //Yep, more of the same.
	movwf	d3      //Weather's pretty nice today.
	movlw	0x02  //Maybe I should mow the lawn.
	movwf	d4     //Okay, this part is done now.

Delay_0

	decfsz	d1, f //Here we decrease the value in the given register
                               //(d1 in this case). the ",f" afterwards just tells it
                               //to store the result back in the register it changed.
                               //If the register, however, is zero, the instruction
                               //makes the PIC skip the next instruction
	goto	$+2          //This instruction just says to jump two instructions.
                               //The $ value just means "current address", so one
                               //could also say "goto $-3" to go back 3 addresses,
                               //if the code needed that.
	decfsz	d2, f //Same old decfsz. Kind of a weird program flow going
	goto	$+2          //on here, but whatever floats their boat.
	decfsz	d3, f //It's early, I should probably get some breakfast.
	goto	$+2          //I've got some strawberry poptarts, that might do.
	decfsz	d4, f //Okay, almost done with this part.
	goto	Delay_0     //If d4 isn't zero yet, you have to go back to the
                               //beginning of this block of code and keep decfsz-ing
                               //until everything is zero. Then we move onto the
                               //next part.
			;5 cycles
	goto	$+1          //These are just junk instructions, used because they
	goto	$+1          //take up 2 cycles each,
	nop                  //when NOP only takes up 1 cycle and also does
	return               //nothing. Our Return here just makes us jump back
                         //to the main block. Let's go, shall we? Go back up.

	end
 
-Excuse me Pommie.. when I run the code in the simulator its wrong.. Its said:
Register in operand not in bank 0. Ensure that bank bits are correct.

-Whats seems to be he problem?
 
That is just a warning and is there to remind you that you should have selected bank 1 before the instruction. Once you are sure that you have selected the correct bank then you can get rid of the warning by doing,
Code:
		bsf	STATUS,RP0
		clrf	TRISB[COLOR="Blue"] & 0x7f[/COLOR]
		clrf	TRISA[COLOR="blue"] & 0x7f[/COLOR]
		bcf	STATUS,RP0

Mike.
 
-what did you mean? Should I add & 0x07f in the INIT part at trisb and trisa?
-I did it but its wrong..

That is just a warning and is there to remind you that you should have selected bank 1 before the instruction. Once you are sure that you have selected the correct bank then you can get rid of the warning by doing,
Code:
		bsf	STATUS,RP0
		clrf	TRISB & 0x7f[/COLOR]
		clrf	TRISA[COLOR="blue"] & 0x7f[/COLOR]
		bcf	STATUS,RP0

Mike.
 
The only things that need declaration as far as EQU-ing are variables that you plan to use that aren't already defined in the PIC's Include.
 
-what do you mean to say? Should I declare STATUS, RP0 as movf STATUS,RP0 before the instruction retfie?
 
Last edited:
delay program:

-Whats seems to be lacking in here:
list p=16F84A ; list directive to define processor
#include <p16F84A.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

d1 equ 0x0D ;Making d1 equal 13
d2 equ 0x0E ;Making d2 equal 14
d3 equ 0x0F ;Making d3 equal 15
d4 equ 0x10 ;Making d4 equal 16

;******************************************************************
org 0X000
goto Init

org 0X004
retfie

-should I insert it the codes in here?



That is just a warning and is there to remind you that you should have selected bank 1 before the instruction. Once you are sure that you have selected the correct bank then you can get rid of the warning by doing,
Code:
		bsf	STATUS,RP0
		clrf	TRISB[COLOR="Blue"] & 0x7f[/COLOR]
		clrf	TRISA[COLOR="blue"] & 0x7f[/COLOR]
		bcf	STATUS,RP0

Mike.
 
I uploaded the .hex file I compiled from the original code that was in your first post (if you want to save it, change the extension from .txt to .hex) and it simulates in MPLAB IDE without any problems for me.

And just so it doesn't confuse you, the code will be functionally identical if you remove the
Code:
org 0X000
goto Init

org 0X004
retfie
from the beginning.
 

Attachments

  • problem.txt
    257 bytes · Views: 125
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top