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.

Code help Please 16F88

Status
Not open for further replies.

dons21

New Member
Hello All.

My goal is to make a 4 digit 7 Segment voltage display. I have learnt several things so far, A/D, Delays, Tables, flash leds, read ports etc...

This is the route I wish to take to learn along the way.

1 Get 7 seg display to count 0-9 in on sec increments.
2 Get 7 seg display to go 0-9 with pot on A/D
3 Get 7 seg display to count 0-99 using an interrupt

And continue along the way until I have the code for a volt meter.

But my code for step one does not work, and I can not work out what is wrong with it.

Please could you have a look and advise.
Code:
;******************************************************************************
;                                                                             *
;    Filename:   7 Seg Count.asm                                              *
;******************************************************************************
;       Segment 1 Enable (RA2) 1	18 (RA1)		      _A_				  *	
;       Segment 2 Enable (RA3) 2     17 (RA0)		   F|	   | B				  *
;				 (RA4) 3	16 (RA7)		   F|_G_| B				  *
;				 (RA5) 4	15 (RA6)		   E|     | C				  *
;				 (VSS) 5	14 (VDD)		   E|_  _| C				  *
;		         Seg G (RB0) 6    13 (RB7) Seg DP		 D
;                        Seg F (RB1) 7    12 (RB6) Seg A						    
;                        Seg E (RB2) 8	11 (RB5) Seg B							  
;		         Seg D (RB3) 9	10 (RB4) Seg C 							  
;******************************************************************************
;                                                                             *
;    Revision History:     0.1                                                *
;                                                                             *
;******************************************************************************

;------------------------------------------------------------------------------
; PROCESSOR DECLARATION
;------------------------------------------------------------------------------
	
    LIST      p=16F88              ; list directive to define processor
    #INCLUDE <P16F88.INC>          ; processor specific variable definitions
	ERRORLEVEL	0,	-302		   ;suppress bank selection messages
;------------------------------------------------------------------------------
; CONFIGURATION WORD SETUP
;------------------------------------------------------------------------------

	__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF


	CBLOCK	0x20 				 ;GPR variable registers allocated contiguously
    		Ones
			Tens
			d1
			d2
			d3
	ENDC


RESET	ORG     0x0000            ; processor reset vector

		movlw	0x07
		movwf	CMCON			;turn comparators off 

 	  
 	  	bsf 	STATUS,		RP0	;select bank 1
  	 	movlw 	b'00000000'		;set PortB all outputs
	   	movwf 	TRISB
		movlw	b'01100000'		;Set up clock speed mhz4
		movwf	OSCCON			;
		movlw	b'11110011'		;set ra2&3 to digital
		movwf	ANSEL
		movlw	b'11110011'		;set RA2&3 to output
		movwf	TRISA
		bcf		STATUS,		RP0
		clrf	PORTB
		clrf	PORTA
		bsf		PORTA,2
		goto    START             ; go to beginning of program



START
			

		
Count	Call	Delay
One		incf 	Ones,f			;increment file Ones (add 1 to file Ones)
		movfw	Ones			;Move file Ones to W register 
		Call	Table
		movwf	PORTB
		sublw	.10				;Subtract '0x0A' '.10' '1010' from W register
		btfss	STATUS,Z		;Check If 0. If Z=1 Skip next instruction. If Z=0 continue	
		goto	Count			;Result is not 0 goto one
		clrf	Ones			;File Ones has reached 10, Clear file to 0
;Ten	incf	Tens,f			;increment file Tens (add 1 to file Tens)
;		movfw	Tens			;Move file Ones to W register 
;		sublw	.10				;Subtract '0x0A' '.10' '1010' from W register
;		btfss	STATUS,Z		;Check If 0. If Z=1 Skip next instruction. If Z=0 continue
;		goto	Count				;
;		clrf	Tens			;File Tens has reached 10, Clear file to 0
		
		goto    Count			;						

Table	ADDWF   PCL, f			;data table for bit pattern
		
        retlw   b'01111110'		;0
        retlw   b'10110000'		;1
        retlw   b'01101101'		;2
        retlw   b'11111001'		;3
        retlw   b'00110011'		;4
        retlw   b'11011011'		;5	
        retlw   b'01011111'		;6
        retlw   b'11110000'		;7
        retlw   b'01111111'		;8
        retlw   b'11110011'		;9
		
		return

Delay							;999990 cycles
		movlw	.7
		movwf	d1
		movlw	.47
		movwf	d2
		movlw	.3
		movwf	d3
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	$+2
		decfsz	d3, f
		goto	Delay_0

						;6 cycles
		goto	$+1
		goto	$+1
		goto	$+1

						;4 cycles (including call)
		return


	GOTO$	

	END
 
Hi,

Have run your code in MPLAB Simulator and it runs quiet well up to the point where your logic goes wrong.


Have you learnt to use SIM yet ?

Its worthwhile as you can check your delay times with the stopwatch and watch your code in single step mode while monitoring your Registers.

I can tell you where you have gone wrong but perhaps you first might want to Sim the code and spot the error yourself - its a pure logic error.
 
Hi Wp100,

In short no I have not used the MPLAB Simulator or did I know that it existed. Im now off to google to work out how to use the simulator.

Will let you know on my progress.

Cheers

Don
 
Last edited:
It looks like a simple error to me too... A single missing instruction...

If you've been staring at it for hours and can't find it then walk away from it for awhile and come back with fresh eyes. And if you think we're being too mean please let us know and we'll show you the problem right away.

If you're a relative newcomer then I would like to say "well done" on what you've done so far in this program.

Kind regards, Mike
 
Hi,

You should find out how to use MPLAB Sim in MPLAB Help.

Just build you code, select Debugger, MPlab Sim, then use the Single Step controls in the Debugger drop down - have attached a screen shot of how did it.
It also shows the Stopwatch to check your 1 sec delay.
The Watch window to View the System Registers like PortB
The File Registers to view your User register like ONES

Have a go, its a worthwhile tool to use - shout if you are stuck.

As I said if you want to know the error I will tell you but feel sure you will want to find it yourself..
 

Attachments

  • ScreenShot001.jpg
    ScreenShot001.jpg
    190.8 KB · Views: 179
Well I have been using the forums for a lot so that I can learn all about micro controllers.

Thanks for the help and support so far.

Your definitely not being 'too mean'. I have read so many posts where people just ask for the answer straight away without even trying to show what they have learnt.

If I really do get stuck, I will let you know.

But if you tell me the answer I wouldn't have learnt anything, would I?

'Experience gained, is learning by your mistakes'

Regards Don
 
Last edited:
Well I am getting on with MPLAB SIM 8.56 but am stuck with the file registers window. As you can see from the screen shot, I am unable to get the symbol names for my GPR variable registers ones tens d1 etc..

Have you got any Ideas?

I think I have found the problem but pls dont tell me. Just want to get symbol names in file registers window for now.

cheers
 

Attachments

  • mplab.JPG
    mplab.JPG
    114.8 KB · Views: 185
I would use the "watch" window instead...

BTW, I found at least two errors...

Regards, Mike

<added>

May I ask why you're lighting the "dp" segment on some of the numbers? And did you make a mistake on the "9" pattern?

Code:
Table   ADDWF   PCL, f                  ; data table for bit pattern
        retlw   b'01111110'             ; "0"   -|A|B|C|D|E|F|-
        retlw   b'10110000'             ; "1"   P|-|B|C|-|-|-|-
        retlw   b'01101101'             ; "2"   -|A|B|-|D|E|-|G
        retlw   b'11111001'             ; "3"   P|A|B|C|D|-|-|G
        retlw   b'00110011'             ; "4"   -|-|B|C|-|-|F|G
        retlw   b'11011011'             ; "5"   P|A|-|C|D|-|F|G
        retlw   b'01011111'             ; "6"   -|A|-|C|D|E|F|G
        retlw   b'11110000'             ; "7"   P|A|B|C|-|-|-|-
        retlw   b'01111111'             ; "8"   -|A|B|C|D|E|F|G
        retlw   b'11110011'             ; "9"   P|A|B|C|-|-|F|G  <--- ???
 

Attachments

  • Don.PNG
    Don.PNG
    73.1 KB · Views: 200
Last edited:
Hi,

Just tired to reproduce the same but it still comes up like my original screenshot ( which does not show the answer)

Not to worry about that just for the moment, you can watch PortB count up instead.
Just View, Watch Window, then from the drop down window, showing ADCON0 select PortB instead, then click on the ADD SFR button.
It should now show Portb and its value.

You can then single step, F7, though the code, W is on the bottom toolbar.
However your Call Delay will get you stuck in that loop, so for now just ; the Count Call Delay line out.
As you single step and follow though your loop you will see the logic error occur.

Edit -
Opps - yes Mike is right you can Add your Ones by means of the Add Symbol in the Watch window
 
Last edited:
Mike Wp100,
I was just testing the DP to see if it would flash on & off. My problem with the MPLAB SIM and showing my GPRs was due to me building all with a lkr file in the project window. After I removed the lkr file and built again the Add Symbol in the Watch window was no longer greyed out.

Once again Cheers for the help.

Well after a break I found the following problems;:)

movlw 0x07
movwf CMCON ;turn comparators off

This was not inside the bsf bank 1 command.

And this one;
movlw b'11110011'
movwf ANSEL ;set ra2&3 to digital

The value should have been b'10010011 as bits 6 & 5 control RB6 & RB7 :D Doh

I also found some other problems which were to do with the Ones counter, because I incremented the Ones file and then called the lookup table It never displayed a 0, also when the counter got to .10 '1010' I never had any data in the lookup table, so this was then passed to PORTB and lit segments F & D.

So here is my revised code all thanks to the MPLAB SIM
Code:
   LIST      p=16F88              ; list directive to define processor
    #INCLUDE <P16F88.INC>          ; processor specific variable definitions
	ERRORLEVEL	0,	-302		   ;suppress bank selection messages
;------------------------------------------------------------------------------
; CONFIGURATION WORD SETUP
;------------------------------------------------------------------------------

	__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
	__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF


		cblock	0x20						;GPR variable registers allocated contiguously
				Ones
				Tens
				d1
				d2
				d3
		endc 

RESET	ORG		0x0000				; processor reset vector

		bsf		STATUS,		RP0		;select bank 1
		movlw	0x07
		movwf	CMCON				;turn comparators off (WAS NOT INSIDE BANK 1)	
		movlw	b'01100000'			;Set up clock speed mhz4
		movwf	OSCCON	
		movlw	b'10010011'			;set RA2&3 to digital(THIS ALSO CONTROLS RB6 & RB7)!!!
		movwf	ANSEL	
		movlw 	b'00000000'			;set PortB all outputs
		movwf 	TRISB				
		movlw	b'11110011'			;set RA2&3 to output
		movwf	TRISA
		bcf		STATUS,		RP0		;select bank0
		
		clrf	PORTA				;set PORTB ouputs low
		clrf	PORTB				;set PORTA ouputs low
		clrf	Ones				;clear file Ones 
		
		goto	START				; go to beginning of program
				
START
		bsf		PORTA,3				;enable segment 1 of display
		

Count	movfw	Ones			;move file Ones to W
		Call	Table			;Lookup Table to move display patern to W reg
		movwf	PORTB			;Output patern to 7 Seg display
		Call	Delay			;Delay 1 second 999982 Delay Cycles, +18 program Cycles = 1s
One		incf 	Ones,f			;increment file Ones (add 1 to file Ones)
		movfw	Ones			;Move file Ones to W register 
		sublw	.10				;Subtract '0x0A' '.10' '1010' from W register
		btfss	STATUS,Z		;Check If 0. If Z=1 Skip next instruction. If Z=0 continue	
		goto	Count			;Result is not 0 goto one
		clrf	Ones			;File Ones has reached 10, Clear file to 0
		
		goto    Count			;	
		
		
Table	ADDWF	PCL, f			;data table for bit pattern
		retlw	b'01111110'		;0 -|A|B|C|D|E|F|-  
		retlw	b'00110000'		;1 -|-|B|C|-|-|-|-  
		retlw	b'01101101'		;2 -|A|B|-|D|E|-|G  
		retlw	b'01111001'		;3 -|A|B|C|D|-|-|G  
		retlw	b'00110011'		;4 -|-|B|C|-|-|F|G  
		retlw	b'01011011'		;5 -|A|-|C|D|-|F|G  
		retlw	b'01011111'		;6 -|A|-|C|D|E|F|G  
		retlw	b'01110000'		;7 -|A|B|C|-|-|-|-  
		retlw	b'01111111'		;8 -|A|B|C|D|E|F|G  
		retlw	b'01110011'		;9 -|A|B|C|D|E|F|-  
	
	
		return

Delay	movlw	.5				;999982 cycles
		movwf	d1
		movlw	.47
		movwf	d2
		movlw	.3
		movwf	d3
		clrw
Delay_0
		decfsz	d1, f
		goto	$+2
		decfsz	d2, f
		goto	$+2
		decfsz	d3, f
		goto	Delay_0
		
		goto	$+1
		goto	$+1
		nop
		
		return
		
		GOTO$
	END

So this code works much better, there might be a more efficient way of writing this but this is the best I can come up with.

Now problem I have with this is the timing as every time the Ones file reaches .10 and btfss STATUS,Z is executed it add 2 cycles to my delay. So I think I need the counter before the delay call???

Once again your advice and pointers.;)
 
Hi,

Great stuff ! :) - you have spotted the errors with no problem - SIM is a very handy tool for checking your logic.

One thing for helping your code in the Banking is the Banksel directive.

banksel TRISB
clrf TRISB

banksel PORTB
clrf PORTB

As for avoiding the 2 cycles the BSFSS uses, well think thats a tough one, does 2 millions of a second matter ?
The other way is to set up a Timer and to have that interrupting every second or so, but you will not be able to do the with a 4meg oscillator as it does not divide down to 1sec, typicaly you use a 32khz timebase.

good luck
 
Last edited:
That looks great and pretty darned efficient too.

You can often change your code and logic ever so slightly to produce cycle accurate (isochronous) loop timing;

Code:
Count
        movf    Ones,W          ; wreg = 'ones', 0..9       |B0
        Call    Table           ; get segment pattern       |B0
        movwf   PORTB           ; update 7-segment display  |B0
        Call    Delay           ; delay 1 second            |B0
One     incf    Ones,f          ; increment 'ones'          |B0
        movfw   Ones            ; wreg = 'ones', 1..10      |B0
        sublw   .10             ; was it 10?                |B0
        btfsc   STATUS,Z        ; no, skip, else            |B0
        clrf    Ones            ; reset 'ones' to 0         |B0
        goto    Count           ; loop                      |B0

Using the banksel pseudo instruction is subjective. I prefer keeping track of banks and manipulating the RP0 and RP1 status bits manually. Use whatever works best for you.

Regards, Mike
 
Last edited:
As for avoiding the 2 cycles the BSFSS uses, well think thats a tough one, does 2 millions of a second matter ?
I suppose it depends on what you're doin'.

You can use timer driven interrupts to refresh a multiplexed display and keep accurate time. If you don't use interrupts you might use isochronous code if you need cycle accurate timing. It's a bit more involved compared to interrupt code but it's not that difficult (example below).

Regards, Mike

Code:
;
;  isochronous 4 msec main program loop (125 Hz refresh rate)
;
        radix   dec
Main
        DelayCy(4*msecs-17)     ; 4 msecs minus 17 cycles         |B0
NewSec  clrf    PORTB           ; blank the display               |B0
        movf    PORTA,W         ;                                 |B0
        xorlw   b'00001100'     ; flip RA3:RA2 digit select bits  |B0
        movwf   PORTA           ; select new digit                |B0
        movf    tens,W          ; W = tens, 0..5                  |B0
        btfss   PORTA,3         ; tens display? yes, skip, else   |B0
        movf    ones,W          ; W = ones, 0..9                  |B0
        call    segtbl          ; get segment data                |B0
        movwf   PORTB           ; display new digit               |B0
        decfsz  sectmr,F        ; 1 second? yes, skip, else       |B0
        goto    Main            ;                                 |B0
;
;  1 second interval
;
        movlw   250             ;                                 |B0
        movwf   sectmr          ; reset 1 second timer            |B0
        incf    ones,F          ; bump 'ones', 1..10              |B0
        movlw   10              ;                                 |B0
        xorwf   ones,W          ; upper limit 10?                 |B0
        skpnz                   ; no, skip, else                  |B0
        clrf    ones            ; reset 'ones' to 0               |B0
        skpnz                   ; update 'tens'? no, skip, else   |B0
        incf    tens,F          ; bump 'tens', 1..6               |B0
        movlw   6               ;                                 |B0
        xorwf   tens,W          ; upper limit 6?                  |B0
        skpnz                   ; no, skip, else                  |B0
        clrf    tens            ; reset 'tens' to 0               |B0
        DelayCy(4*msecs-31)     ; 4 msecs minus 31 cycles         |B0
        goto    NewSec          ;                                 |B0
 
Last edited:
Wp100, no the 2 cycles did not matter at all I was just interested how I could change the code so that it was exactly 1s. But in the end it was very simple to implement with the btfsc.

Thanks for the code Mike, it will keep me busy for a few days, so that I can understand exactly what is happening.

I am now learning about binary maths etc... so that I can manipulate the ADC results and increment the pcl to select the correct pattern to display.

Well thanks again for the help, you will more likely find me bugging you about something on another thread, when I get stuck. It will probably be about binary maths :confused:

Don
 
Hi,

Good to hear you got it all sorted - for now..

You might find this site interesting - lots of ready made converters etc - you don't have to use them but the ideas might help you.
 
Status
Not open for further replies.

Latest threads

Back
Top