Coding a digital timer on PIC18f4550

Discussion in 'Embedded Systems and Microcontrollers' started by corsair, Mar 6, 2010.

  1. corsair

    Thread Starter Member

    Mar 6, 2010
    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:
    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:

    Code ( (Unknown Language)):
    1. Main:
    2.      display  seg7,digit1
    3.      call      delay_1ms
    4.      display  seg3,digit2
    5.      call      delay_1ms
    6.      display  seg1,digit3
    7.      call      delay_1ms
    8.      display  seg2,digit4
    9.      call      delay_1ms
    10.      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:

    Code ( (Unknown Language)):
    1. main:
    2.         local   d1 = 0
    3.         local   d2 = 0
    4.         local   d3 = 0
    5.         local   d4 = 4
    7.         while d1 <= 9  
    8. d2 = 0
    9.             while d2 <= 9
    10. d3 = 0
    11.                 while d3 <= 9
    12. d4 = 0         
    13.                     while d4 <= 9
    14.                         display seg#v(d1),digit1
    15.                         call    delay_1ms
    16.                         display seg#v(d2),digit2
    17.                         call    delay_1ms
    18.                         display seg#v(d3),digit3
    19.                         call    delay_1ms
    20.                         display seg#v(d4),digit4
    21.                         call    delay_1ms
    22. d4 += 1
    23.                     endw
    24. d3 += 1
    25.                 endw
    26. d2 += 1
    27.             endw
    28. d1 += 1
    29.         endw
    31. 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?
  2. 139742

    New Member

    Apr 5, 2010

    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.
  3. 139742

    New Member

    Apr 5, 2010
    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.
  4. corsair

    Thread Starter Member

    Mar 6, 2010
    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!
  5. MMcLaren

    Well-Known Member

    Feb 14, 2010
    Do you have a schematic? I'd like to see what it is you're trying to describe.

    Thank you. Regards, Mike
  6. corsair

    Thread Starter Member

    Mar 6, 2010
    no, it doesn't seem that i have a pin diagram if you were asking me. but i did attach a couple of pictures.