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.

(PIC16f877a) 00-99 seven segment Counter ,Assembly language

Status
Not open for further replies.

sniper1400

New Member
Hi I have been working on This project for a few days now and i am having some issues with it working if someone can take a look at the program and see if there is something im not doing right. everything builds in mplab but when i implement it on the chip i don't get the numbers

Here is the Code I am using:
Code:
 ;7 segment LED display - count up from zero

	LIST	p=16F877a		;tell assembler what chip we are using
	include "P16F877a.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages



		cblock	0x20			;start of general purpose registers
			count			;used in looping routines
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			tmp1			;temporary storage
			tmp2
			p_temp			;save register
			s_temp			;save register
			w_temp			;save register
			tens			;tens storage
			ones			;ones storage
		endc

SEG_PORT	Equ	PORTB			;7 segment port
SEG_TRIS	Equ	TRISB


		org	0x0000
		goto	Initialise

;**************************************************************************	
;			     	Interrupt routine
;**************************************************************************



; 	Interrupt routine handles TMR2 which generates a 1ms tick

;	Interrupt vector

	ORG	0x0004


INT
		movwf	w_temp		; Save W register
		swapf	STATUS,W	; Swap status to be saved into W
		movwf	s_temp		; Save STATUS register
		movfw	PCLATH
		movwf	p_temp		; Save PCLATH 
	
		btfss	PIR1,TMR2IF	; Flag set if TMR2 interrupt
		goto	INTX		; Jump if not timed out

		; Timer (TMR2) timeout every 1 milli second
	

		bcf	PIR1,TMR2IF	; Clear the calling flag


		btfss	SEG_PORT, 7	;check which LED was last
		goto	Do_tens
		movfw	ones
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		andlw	0x7F		;set to correct LED
		movwf	SEG_PORT
		goto	INTX

Do_tens		movfw	tens
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		iorlw	0x80		;set to correct LED
		movwf	SEG_PORT



INTX
		movfw	p_temp
		movwf	PCLATH		; Restore PCLATH
		swapf	s_temp,W
		movwf	STATUS		; Restore STATUS register - restores bank
		swapf	w_temp,F
		swapf	w_temp,W	; Restore W register
		retfie

LED_Table  	ADDWF   PCL       , f
            	RETLW   b'10001000'		;0
            	RETLW   b'10111011'		;1
            	RETLW   b'11000001'		;2
            	RETLW   b'10010001'		;3
            	RETLW   b'10110010'		;4
            	RETLW   b'10010100'		;5
            	RETLW   b'10000100'		;6
            	RETLW   b'10111001'		;7
            	RETLW   b'10000000'		;8
            	RETLW   b'10110000'		;9
            	RETLW   b'11111111'		;blank
            	RETLW   b'11111111'		;blank
            	RETLW   b'11111111'		;blank
            	RETLW   b'11111111'		;blank
            	RETLW   b'11111111'		;blank
            	RETLW   b'11111111'		;blank


Initialise	movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)
		bsf 	STATUS,		RP0	;select bank 1
		movlw	b'00000000'		;Set port data directions, data output
		movwf	SEG_TRIS
		bcf 	STATUS,		RP0	;select bank 0
	

		;	Set up Timer 2.
	
		;movlw	b'01111110'		; Post scale /16, pre scale /16, TMR2 ON
		;uncomment previous line, and comment next line, to slow multiplexing speed
		;so you can see the multiplexing happening
		movlw	b'00010110'		; Post scale /4, pre scale /16, TMR2 ON
		movwf	T2CON

		bsf 	STATUS,		RP0	;select bank 1

		movlw	.249			; Set up comparator
		movwf	PR2

		bsf	PIE1,TMR2IE		; Enable TMR2 interrupt

		bcf 	STATUS,		RP0	;select bank 0

		; Global interrupt enable

		bsf	INTCON,PEIE		; Enable all peripheral interrupts
		bsf	INTCON,GIE		; Global interrupt enable

		bcf 	STATUS,		RP0	;select bank 0
	
		clrf	tens
		clrf	ones

	

Main
		call	Delay255
		call	Delay255
		call	Delay255
		call	Delay255
		incf	ones,	f
		movf	ones, 	w		;test first digit
		sublw	0x0A
		btfss	STATUS, Z
		goto	Main
		clrf	ones
		incf	tens,	f
		movf	tens, 	w		;test second digit
		sublw	0x0A
		btfss	STATUS, Z
		goto	Main
		clrf	tens
		goto	Main			;loop for ever


Delay255	movlw	0xff			;delay 255 mS
		goto	d0
Delay100	movlw	d'100'			;delay 100mS
		goto	d0
Delay50		movlw	d'50'			;delay 50mS
		goto	d0
Delay20		movlw	d'20'			;delay 20mS
		goto	d0
Delay5		movlw	0x05			;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7			;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

	END
 
Last edited:
The code looks fine. When you say it's not working, what is it doing?

One thing, which is not your problem but may cause problems later, the temporary variables (w_temp etc) need to be in the common area at 0x70 - 0x7f.

Mike.
For anyone interested, here is the tidied up version.
Code:
;7 segment LED display - count up from zero  

		LIST	p=16F877a	;tell assembler what chip we are using
include		"P16F877a.inc" 		;include the defaults for the chip
		ERRORLEVEL 0,-302	;suppress bank selection messages



		cblock	0x20		;start of general purpose registers
count					;used in looping routines 
count1					;used in delay routine 
counta					;used in delay routine 
countb					;used in delay routine 
tmp1					;temporary storage 
tmp2
p_temp					;save register 
s_temp					;save register 
w_temp					;save register 
tens					;tens storage 
ones					;ones storage 
		endc

SEG_PORT	Equ	PORTB		;7 segment port
SEG_TRIS	Equ	TRISB


		org	0x0000
		goto	Initialise

;************************************************* *************************	  
;	 Interrupt routine  
;************************************************* *************************  



; Interrupt routine handles TMR2 which generates a 1ms tick  

;	Interrupt vector  

		ORG	0x0004


INT
		movwf	w_temp		; Save W register
		swapf	STATUS,W	; Swap status to be saved into W
		movwf	s_temp		; Save STATUS register
		movfw	PCLATH
		movwf	p_temp		; Save PCLATH 

		btfss	PIR1,TMR2IF	; Flag set if TMR2 interrupt
		goto	INTX		; Jump if not timed out

; Timer (TMR2) timeout every 1 milli second  


		bcf	PIR1,TMR2IF	; Clear the calling flag


		btfss	SEG_PORT,7	;check which LED was last
		goto	Do_tens
		movfw	ones
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		andlw	0x7F		;set to correct LED
		movwf	SEG_PORT
		goto	INTX

Do_tens		movfw	tens
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		iorlw	0x80		;set to correct LED
		movwf	SEG_PORT



INTX
		movfw	p_temp
		movwf	PCLATH		; Restore PCLATH
		swapf	s_temp,W
		movwf	STATUS		; Restore STATUS register - restores bank
		swapf	w_temp,F
		swapf	w_temp,W	; Restore W register
		retfie

LED_Table	ADDWF	PCL , f
		RETLW	b'10001000'	;0
		RETLW	b'10111011'	;1
		RETLW	b'11000001'	;2
		RETLW	b'10010001'	;3
		RETLW	b'10110010'	;4
		RETLW	b'10010100'	;5
		RETLW	b'10000100'	;6
		RETLW	b'10111001'	;7
		RETLW	b'10000000'	;8
		RETLW	b'10110000'	;9
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank


Initialise	movlw	0x07
		movwf	CMCON		;turn comparators off (make it like a 16F84)
		bsf	STATUS,RP0	;select bank 1
		movlw	b'00000000'	;Set port data directions, data output
		movwf	SEG_TRIS
		bcf	STATUS,RP0	;select bank 0


;	Set up Timer 2.  

;movlw	b'01111110'	 ; Post scale /16, pre scale /16, TMR2 ON  
;uncomment previous line, and comment next line, to slow multiplexing speed  
;so you can see the multiplexing happening  
		movlw	b'00010110'	; Post scale /4, pre scale /16, TMR2 ON
		movwf	T2CON

		bsf	STATUS,RP0	;select bank 1

		movlw	.249		; Set up comparator
		movwf	PR2

		bsf	PIE1,TMR2IE	; Enable TMR2 interrupt

		bcf	STATUS,RP0	;select bank 0

; Global interrupt enable  

		bsf	INTCON,PEIE	; Enable all peripheral interrupts
		bsf	INTCON,GIE	; Global interrupt enable

		bcf	STATUS,RP0	;select bank 0

		clrf	tens
		clrf	ones



Main
		call	Delay255
		call	Delay255
		call	Delay255
		call	Delay255
		incf	ones,	f
		movf	ones,w		;test first digit
		sublw	0x0A
		btfss	STATUS, Z
		goto	Main
		clrf	ones
		incf	tens,	f
		movf	tens,w		;test second digit
		sublw	0x0A
		btfss	STATUS, Z
		goto	Main
		clrf	tens
		goto	Main		;loop for ever


Delay255	movlw	0xff		;delay 255 mS
		goto	d0
Delay100	movlw	d'100'		;delay 100mS
		goto	d0
Delay50		movlw	d'50'		;delay 50mS
		goto	d0
Delay20		movlw	d'20'		;delay 20mS
		goto	d0
Delay5		movlw	0x05		;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7		;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00
 
When I put it on my pic16f877a It wont count from 00-99. I have tried figuring out how to set up multiplexing and i thought it was in the program but i guess its a hardware issue, In that case do you happen to know a schematic? here is a parts list that i thought i could use to perform this my 2-digit seven segment display(HDSP-523G SERIES)common cathode

Parts List:
-Pic16f877a
-2x 2n3904 (NPN) transistors
-7x 330kohm resistors
-1xpushbutton
-3x1kohm resistor

I appreciate the help
 
I noticed that you are not defining your fuses in your code, check that you have them set correctly in your programmer. I always prefer to define them in code so I know at a glance what is being set or not. Also, Mike is spot on, make sure your context registers are saved and restored from the common register bank beginning at 0x70 :)
 
Need Help Please

Okay so for the past week I have been struggling with getting the 00-99 Counter to work I need someone to help me out I have attached a picture of a flow chart of what the program needs to do I cannot get the program above to work i am using a pic 16f877a configuration 3F73 this needs to be in assembly and use port D Can Someone PLEASE HELP ME?
photo.JPG
 
PLEASE SOMEONE HELP PIC16F877A 00-99 couunter Assembly

I have been working on a counter all week and i have code that isn't working out and I need someone with more knowledge to possibly write it for me as i do not have the skill to do so Below you will find the code i wrote which isn't working. My configuration is 3f73 on a pic16f877a PLEASE HELP ME.
 

Attachments

  • 7_segment_display_trial.asm
    4.4 KB · Views: 797
Last edited:
Trying to debug code without knowing the hardware is extremely difficult. So, do you have a schematic?

Mike.
 
no not really i can take a picture of the board but its kind of messy there are 2 npn transistors bottom left taking care of multiplex port B RB0 is where those transistors are being powered etc...board.JPG
 
How can 1 npn be on and the other off when they are both powered by the same pin?

Mike.
 
When I put it on my pic16f877a It wont count from 00-99. I have tried figuring out how to set up multiplexing and i thought it was in the program but i guess its a hardware issue, In that case do you happen to know a schematic? here is a parts list that i thought i could use to perform this my 2-digit seven segment display(HDSP-523G SERIES)common cathode

Parts List:
-Pic16f877a
-2x 2n3904 (NPN) transistors
-7x 330kohm resistors
-1xpushbutton
-3x1kohm resistor

I appreciate the help

If you are using common cathode LED, your schematic would look like something as attached.

But then your program code was designed to run on common anode LED. As segment to be ON is at logic "0".

Code:
LED_Table	ADDWF	PCL , f
		RETLW	b'10001000'	;0
		RETLW	b'10111011'	;1
		RETLW	b'11000001'	;2
		RETLW	b'10010001'	;3
		RETLW	b'10110010'	;4
		RETLW	b'10010100'	;5
		RETLW	b'10000100'	;6
		RETLW	b'10111001'	;7
		RETLW	b'10000000'	;8
		RETLW	b'10110000'	;9
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank
		RETLW	b'11111111'	;blank

So you need to add 2 instructions here:

Code:
; Timer (TMR2) timeout every 1 milli second  
 
 
		bcf	PIR1,TMR2IF	; Clear the calling flag
 
 
		btfss	SEG_PORT,7	;check which LED was last
		goto	Do_tens
		movfw	ones
		andlw	0x0F		;make sure in range of table
		call	LED_Table
                XORLW     0x7F        ;ADD INSTRUCTION here		
                andlw	0x7F		;set to correct LED
		movwf	SEG_PORT
		goto	INTX
 
Do_tens		movfw	tens
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		XORLW     0x7F         ;ADD INSTRUCTION also here
                iorlw	0x80		;set to correct LED
		movwf	SEG_PORT

-7x 330kohm resistors

Shouldn't this be 330 Ω resistors?

Allen
 

Attachments

  • 877 COUNTER.PNG
    877 COUNTER.PNG
    160.7 KB · Views: 1,465
Last edited:
Except he doesn't list an inverter.

Mike.

Good:) So at least he has to use his brain power a little bit to figure it out.....

Can't just hand over a complete solution on a silver platter to him.:D

Allen
 
Last edited:
The problem i am having is that it isnt showing any numbers on either 7seg its just random i know its hooked up right because i have just a single 0-9 counter on another chip and it works fine when i swap out pics.
 
my mistake i had it that one was being powered by RB0 and other was just to ground

Are you sure it is powered by RB0 and not RB7?

Are you able to understand the schematic that I've posted?

Allen
 
Last edited:
Hi,

Your code is more or less OK. I have got it working with minor tweeks.

Check your config directive.

Check your banksel directives.

Careful where you clear TMR2IF.

I used 2 x 2n7000 mosfets on RB7 to multiplex.

I used common cathode displays (all I had available)


**broken link removed**

Edit:

Had another look at this.
Cut and pasted your original code and it built / ran ok. Only change made was to the lookup table as my cct has CC LEDs
Used 2 x BC337 NPN transistors in place of the 2n7000s
 

Attachments

  • DIPTRACE Capture.JPG
    DIPTRACE Capture.JPG
    267.7 KB · Views: 1,476
Last edited:
Okay so I added the _config '3f73' into the code rather then doing it with my programer i changed my 7-seg display to a double rather then 2 singles and got new NPN transistors. I am now playing around with the delay to find the right speed to count but through out I seem to have a issue with some parts of numbers don't appear (dim/not at all) what would this be from? (does the same thing with my singles so its not the displays) I will attach a video of the 7-seg while its running

Can someone also tell be how you put your code up in those boxes like in the reply's above


Thank you for everyone's help with this I am now going to move on to adding my other parts to this little project I am playing with.
Plan is to have a servo or possibly a dc motor run until a Certain count and then switch to a 50 or 25% duty cycle for the remainder.
 
Last edited by a moderator:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top