Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Timer/Counter problem in PIC16F819 and Proteus model for it

Status
Not open for further replies.

BlackOps

Full Member level 5
Joined
Jan 1, 2005
Messages
279
Helped
14
Reputation
28
Reaction score
3
Trophy points
1,298
Location
AZERBAIJAN
Activity points
2,496
proteus display 7 seg

Hello, first question is where to get PROTEUS library with model of PIC16F819 /818 ?

next, i have programmed my PIC16F819 chip, and connected 7 segment display to it like that:

RB1 - a
RB2 - b
RB3 - c
RB4 - d
RB5 - e
RB6 - f
RB7 - g

VSS connected to Gnd terminal of 7seg as needed.

all connections are OK, programming was successfull.

my program must count from 0 to 9, every second, and display every digit on 7seg display. I did simulation with almost exact copy of this program under PIC16F84 in Proteus, and it worked very fine there. Now i changed the program a little to fit it in my PIC16F819 chip. but after programming, when i connect it to battery, i get only 0 digit on my 7seg display!

normally it must start with zero digit, and go up every second, then again zero..and so on. but it starts with zero digit..and stands like that, doesnt go up.

when it worked in Proteus with Pic16F84, i connected external 20mhz crystal to it.

here in my real circuit with PIC16F819 i dont have any crystal connected to it...cuz it also has an internal oscillator.

i think that my problem has something to do with configuration settings in the beginning of my source code....

i also want to know, if i didnt connect any crystal to my PIC16F819 what would be the default frequency of the oscillator?

now take a look at my source code plz:

Code:
;=====================================================
; File: RB0Int.ASM
; Date: April 22, 2006
; Author: Julio Sanchez
; Processor: 16F84A
;=====================================================
; Description:
; Program to test interrupt on port RB0
; A pushbutton switch is connected to port RB0.
; The pushbutton toggles a LED on port-B, line 7
; 
; 
;=====================================================

;=========================
; setup and configuration
;=========================
;processor 16f84A
#include <p16F819.inc>
 __CONFIG   _CP_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _CCP1_RB2 & _DEBUG_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_IO


; Variables here

	CBLOCK 0x20			; start of ram in 16F84

		bres_hi			; hi byte of our 24bit variable
		bres_mid			; mid byte
		bres_lo			; lo byte
						; (we only need 3 bytes for this system)

		status_temp		; used for interrupt servicing
		w_temp			; used for interrupt servicing
		num
		decnum


	ENDC


;==============================================================================
; Code here

	org 0x000 			; Set program memory base at reset vector 0x000
reset
	goto setup			; set up ints and port stuff

	org 0x004				; Interrupt vector, int handler code comes next.
;==============================================================================


;******************************************************************************
;  INTERRUPT HANDLER     (runs this code each timer0 interrupt)
;******************************************************************************
;
;------------------
int_handler				;
;------------------

	;-------------------------------------------------
						; first we preserve w and status register

	movwf w_temp      		; save off current W register contents
	movf	STATUS,w          	; move status register into W register
	movwf status_temp       	; save off contents of STATUS register

	;-------------------------------------------------
	; Note! we get here every 256 instructions, we
	; can now do our special one second timing system.				

	; This consists of three main steps;
	; * subtract 256 counts from our 24bit variable
	; * test if we reached the setpoint
	; * if so, add 1,000,000 counts to 24bit variable and generate event.
	;-------------------------------------------------
						; * optimised 24 bit subtract here 
						; This is done with the minimum instructions.
						; We subtract 256 from the 24bit variable
						; by just decrementing the mid byte.

	movf bres_mid,1			; first test for mid==0
	btfsc	STATUS,2				; nz = no underflow needed
	decf bres_hi,f			; z, so is underflow, so dec the msb

	decfsz bres_mid,f		; dec the mid byte (subtract 256)

						; now the full 24bit optimised subtract is done!
						; this is about 4 times faster than a "proper"
						; 24bit subtract.

	goto int_exit			; nz, so definitely not one second yet.
						; in most cases the entire int takes
						; only 16 instructions.
	;------------------------
						; * test if we have reached one second.
						; only gets here when mid==0, it MAY be one second.
						; only gets to here 1 in every 256 times.
						; (this is our best optimised test)
						; it gets here when bres_mid ==0.

	movf bres_hi,1			; test hi for zero too
	btfss	STATUS,2					; z = both hi and mid are zero, is one second!
	goto int_exit			; nz, so not one second yet.

	;-------------------------------------------------
	; Only gets to here if we have reached one second.

	; now we can generate our one second event, like add
	; one second to our clock or whatever.
	; (in this example we toggle a led)

	; The other thing we need to do is add 1,000,000 counts
	; to our 24bit variable and start all over again.
	;-------------------------------------------------
						; Add the 1,000,000 counts first.
						; One second = 1,000,000 = 0F 42 40 (in hex)

						; As we know hi==0 and mid==0 this makes it very fast.
						; This is an optimised 24bit add, because we can
						; just load the top two bytes and only need to do
						; a real add on the bottom byte. This is much quicker
						; than a "proper" 24bit add.

	movlw 0x0F			; get msb value 
	movwf bres_hi			; load in msb

	movlw 0x42			; get mid value
	movwf bres_mid			; load in mid

	movlw 0x40			; lsb value to add
	addwf bres_lo,f		; add it to the remainder already in lsb
	btfss	STATUS,0				; nc = no overflow, so mid is still ok

	incf bres_mid,f		; c, so lsb overflowed, so inc mid
						; this is optimised and relies on mid being known
						; and that mid won't overflow from one inc.

						; that's it! Our optimised 24bit add is done,
						; this is roughly twice as quick as a "proper"
						; 24bit add.
	;-------------------------
						; now we do the "event" that we do every one second.

						; Note! for this example we toggle a led, which
						; will give a flashing led which is on for a second
						; and off for a second.
						; Add your own code here for your one second event.

						; Note! My led is on porta,3
						; your led may be on a different pin.
	;movlw b'00001000'		; mask for bit 3
	;xorwf PORTB,f			; toggle PORTA,bit3 (toggle the led)
	incf	decnum,1
						
	;-------------------------------------------------
	; now our one second event is all done, we can exit the
	; interrupt handler.
	;-------------------------------------------------
						; finally we restore w and status registers.
						; also clears TMRO int flag now we are finished.
int_exit
	BCF INTCON,TMR0IF		; reset the tmr0 interrupt flag

	movf status_temp,w     	; retrieve copy of STATUS register
	movwf STATUS            	; restore pre-isr STATUS register contents
	swapf w_temp,f
	swapf w_temp,w          	; restore pre-isr W register contents
	retfie				; return from interrupt
;------------------------------------------------------------------------------



;******************************************************************************
;  SETUP     (runs this only once at startup)
;******************************************************************************
;
;------------------
setup					; goto label
;------------------

	;-------------------------------------------------
	; Note! 16F84 version.
	; Note! here we set up peripherals and port directions.
	; this will need to be changed for different PICs.
	;-------------------------------------------------
						; OPTION setup
	movlw b'10001000'		;
		;  x-------		; 7, 0=enable, 1=disable, portb pullups
		;  -x------		; 6, 1=/, int edge select bit
		;  --x-----		; 5, timer0 source, 0=internal clock, 1=ext pin.
		;  ---x----		; 4, timer0 ext edge, 1=\
		;  ----x---		; 3, prescaler assign, 1=wdt, 0=timer0
		;  -----x--		; 2,1,0, timer0 prescaler rate select
		;  ------x-		;   000=2, 001=4, 010=8, 011=16, etc.
		;  -------x		; 
						; Note! We set the prescaler to the wdt, so timer0
						; has NO prescaler and will overflow every 256 
						; instructions and make an interrupt.
						;
	banksel OPTION_REG		; go proper reg bank
	movwf OPTION_REG		; load data into OPTION_REG
	banksel 0				; back to normal bank 0
	;-------------------------------------------------
						; PORTB pins direction setup
						; 1=input, 0=output
	clrf PORTB			;
						;
	movlw b'00000000'		; all 8 portb are outputs
						;
	banksel TRISB			; go proper reg bank
	movwf TRISB			; send mask to portb
	banksel 0				; back to normal reg bank
	;-------------------------------------------------
						; PORTA pins direction setup
						; 1=input, 0=output
	clrf PORTA			;
						;
	movlw b'00000000'		; all 5 porta are outputs,
						; (with 16F84 porta only has lower 5 bits)
						;
	banksel TRISB			; go proper reg bank
	movwf TRISA			; send mask to porta
	banksel 0				; back to normal reg bank
	;-------------------------------------------------
						; INTCON setup
						;
						; for this code example, we enable the timer0
						; overflow interrupt.
						;
						; enable interrupts last
						; interrupt setup
	movlw b'10100000'		; GIE=on TOIE=on (timer0 overflow int)
	movwf INTCON			; set up.

	;-------------------------------------------------
	; Note! Now the hardware is set up we need to load the
	; first count for one second into our 24bit bres variable.
	;-------------------------------------------------
						; Note! This example uses 4 MHz clock, which is
						; 1,000,000 counts per second.
						;
						; We require a 1 second period, so we must load
						; 1,000,000 counts each time.
						; 1,000,000 = 0F 42 40 (in hex)
						;
						; We also need to add 256 counts for the first time,
						; so we just add 1 to the mid byte.
						; Check mid overflow if needed.

						; here we load the 24bit variable.
	movlw 0x0F			; get msb value 
	movwf bres_hi			; put in hi

	movlw 0x42 +1			; get mid value (note we added 1 to it)
	movwf bres_mid			; put in mid

	movlw 0x40			; get lsb value
	movwf bres_lo			; put in mid

						; now setup is complete, we can start execution.
	;-------------------------------------------------
	goto main				; start main program

;------------------------------------------------------------------------------



;******************************************************************************
;  MAIN     (main program loop)
;******************************************************************************
;
;------------------
main						; goto label
;------------------
movlw	0
movwf	decnum
	;-------------------------------------------------
	; Note! This example uses the timer0 overflow interrupt.
	; This will interrupt our main program every 256 instructions
	; and do the one second timer system.
	;-------------------------------------------------
main_loop					; 
						; Note! here you have your main program code,
						; or calls to the main program pieces.
						; The interrupt does all the one second timer stuff.
	; stuff
	; stuff
	; stuff
	; stuff
	movf	decnum,0

	call	segment
	
	movwf	num
	rlf		num,0
	movwf	PORTB

	;-------------------------------------------------
	goto main_loop			; keep running the main code.

;------------------------------------------------------------------------------

segment:
addwf PCL,1 ; PCL is program counter latch
retlw 0x3f ; 0 code
retlw 0x06 ; 1
retlw 0x5b ; 2
retlw 0x4f ; 3
retlw 0x66 ; 4
retlw 0x6d ; 5
retlw 0x7d ; 6
retlw 0x07 ; 7
retlw 0x7f ; 8
retlw 0x6f ; 9
;retlw 0x77 ; A
;retlw 0x7c ; B
;retlw 0x39 ; C
;retlw 0x5e ; D
;retlw 0x79 ; E
;retlw 0x71 ; F
;retlw 0x40 ; Just in case all on
;==============================================================================
	end					; no code after this point.
;==============================================================================
 

proteus counter timer

Most of PIC16Fxxx MCUs with internal OSC default frequency is 4MHz after reset.
 

ver tmr0 en proteus

OK, i've found the answer to this problem.

here is how my configuration directives should be:

__config _INTRC_IO & _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFFand here is the code i had to paste before clearing of PORTB:

BANKSEL OSCCON
movlw B'01100000' ; Should be 4 MHz
movwf OSCCON


i had to select manually frequency of internal Oscillator through OSCCON register. thats it.


BUT, i still didnt find any proteus library for PIC16F819 model, who can help in that? or send it to me? i'd appreciate it!

thanks
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top