Coding a digital timer on PIC18f4550

Thread Starter

corsair

Joined Mar 6, 2010
51
Hi guys,

This is my first post so forgive me if I'm not thorough enough. For my class, we are using a PIC18f4550 microcontroller. Through the SPP ports, we have a 4-digit, 7-segment display. I will do a lot of explaining for those who do not know much about the 7-segment display.

The problem is as follows:
Write a program which will display elapsed time from start of program in hundredths of a second (no decimal point). The four-digit display should be refreshed at a rate of 250 Hz (e.g. 1 msec/digit).
For the sake of brevity, I developed binary definitions for selecting the digits (either 1,2,3, or 4 on the display), and binary definitions for the segment patterns. In addition, I created a "display(x,y)" macro and a "delay_1ms" function. When the "display(x,y)" macro is called, it will display x on y. Ex. display(seg3,digit2) will show up as [x,3,x,x] where x is denoted as nothing. The delay_1ms function will do exactly as described, and do a bunch of "nops."

However, having one microcontroller only allows one display at a time. So in order to display 4 digits simultaneously, say "7312" on the display, I would have to do the following:

Rich (BB code):
Main:
     display  seg7,digit1
     call      delay_1ms
     display  seg3,digit2
     call      delay_1ms
     display  seg1,digit3
     call      delay_1ms
     display  seg2,digit4
     call      delay_1ms
     bra       Main
Now that I am done explaining how this works, this is the real problem. My code for a digital timer does not fit inside the memory of the PIC18 microcontroller. I don't think I am approaching this correctly, and if there is a much simpler way to do this, I would greatly appreciate it. Here is my code:

Rich (BB code):
main:
		local	d1 = 0
		local	d2 = 0
		local	d3 = 0
		local	d4 = 4

		while d1 <= 9	
d2 = 0
			while d2 <= 9
d3 = 0
				while d3 <= 9
d4 = 0			
					while d4 <= 9
						display seg#v(d1),digit1
						call	delay_1ms
						display	seg#v(d2),digit2
						call 	delay_1ms
						display seg#v(d3),digit3
						call	delay_1ms
						display seg#v(d4),digit4
						call	delay_1ms
d4 += 1
					endw
d3 += 1
				endw
d2 += 1
			endw
d1 += 1
		endw

stop	bra	stop
Again, any help would be greatly appreciated. This code does NOT work, and after taking almost 3 hours to compile, it gave me a bunch of "warnings" with this message: Address exceeds maximum range for this processor.

Perhaps there is a much easier way to do this with registers?
 

139742

Joined Apr 5, 2010
5
Hi,

Just in case this is still not working, one approach is to get rid of the while loops and replace them with goto or bra. The while loops are too expensive and won't fit in the programmable space. If you break up the nested while loops and have a goto, like loop through the ones, then if is greater than 9, goto the code to increment the tens, and then jump back to the ones, and so on.
 

139742

Joined Apr 5, 2010
5
Also, I have a similar problem to work on. How did you write your display macro? I do not understand how to access the common anode lines so I don't know how to choose which digit I would like to have my number displayed on.
 

Thread Starter

corsair

Joined Mar 6, 2010
51
ah yes, this problem has been fixed for a while, but thanks for the reply

anyways, the way my board is set up, i access this through the SPP (streaming parallel port) registers. the anode is located at address 0x0, and the cathode is located at address 0x1.

displaying something on the 7seg display requires 4 steps:
1) select the anode by loading the address (0x0) into SPPEPS
2) write data into the anode by putting data into SPPDATA
3) select the cathode by loading the address (0x1) into SPPEPS
4) write data into the cathode by putting data into SPPDATA

however, you will have to find/create mappings for these, meaning find a hex number that represents digit1,2,3,4 and a hex number that represents how they are displayed. you could also use the display's datasheet and try to figure it out that way =)

to get you started, here is step 1:
movlw 0x0 ; anode address
movwf SPPEPS ; select anode by writing the address into this register
btfsc SPPEPS, 0x4 ; testing SPPEPS if busy, will wait until it's finished
goto $-2

anyways i hope this helps! btw, im doing a class for this, and this was the way my board was wired. since i'm only 2 months in, i dont have any other experience, so i cant tell you if hooking up a display to the SPP ports is conventional. my guess is that it is, and perhaps someone else could verify. well, gl with everything!
 
Top