Building a 2-person "quiz reaction timer" with a microcontroller

Thread Starter

farscape

Joined May 16, 2010
26
Hi,

I'm taking an intro to digital electronics class and we have a final project where we need to build a 2 person "game show" quiz reaction timer. I feel like I'm in way over my head at this point and I would appreciate any and all help to get me started with the basic setup.

Here are the basic instructions:

The game has 2 players, each with a a button connected to an LED

A reset button is pushed and there is a 9-second countdown on a 7-segment LED display. After the last count, there is a final 1 second delay, after which the first player to hit his/her button has their LED light up while the second player's LED is locked out

If somebody "jumps the gun" and hits their button before the time has run out then the other player's LED is lit and the round is over.

Were required to use PIC microcontroller, so I have to figure out how the circuit should be set up as well as the code for the process I described.

We've had a little practice with basic programming (decrement commands, etc.) but I'm at a loss as to how to program the PIC to carry out all these requirements. If this doesn't make sense, let me know, and I'll try to clarify.

Thanks
 

Markd77

Joined Sep 7, 2009
2,806
Which PIC will you be using? As long as you have at least 12 IO ports the circuit should be simple.
Will you be using assembler or C? And if C which make?
You should draw up a schematic and post it here for someone to check. Hardware first, then software.
You could consider using an interrupt to check if the buttons have been pressed.
You could use the MCLR pin for the reset button or just a normal IO pin.
 

Thread Starter

farscape

Joined May 16, 2010
26
Hi, thanks for the response.

-We've been using the PIC16F84A which has 13 I/O ports so I'm guessing from what you said that will be adequate. We're not required to use a specific one.
-We are using assembly language

Ive drawn up and attached a basic hardware schematic, but any corrections will be much appreciated.
-I'm confused about the function/purpose of the crystal oscillator and how it interacts with the OSC1 and OSC2 pins of the chip. Is it necessary? (We used this in an earlier lab this semester with the same connections).
-Are my resistor values in the right ballpark?
-Can the RB0/INT pin be used to block signals from the slower players input? I cant quite figure out how this comes into play.

The programming is whats really scaring me, but Ill start on that and see what I can come up with. Any tips on how to get started?

Thanks for the help
 

Markd77

Joined Sep 7, 2009
2,806
Not far off. The MCLR switch and resistor should be swapped because reset is low voltage.
If your crystal is a 2 pin device you need a couple of capacitors to ground. If it is a 3 pin resonator then your circuit is fine.
The LEDs are drawn the wrong way round, but you would probably spot that quickly enough.
VSS and VDD are the wrong way round too.
Assuming you have a common cathode 7 segment, that is fine.

I'd be tempted to use RA0-Ra3 and RB0-RB2 for the 7 segment and then you can use the interrupt on change feature of RB4 and RB5 for the user buttons.

The crystal is necessary with this PIC but if you used the 16F628 instead you could use the internal oscillator.

Resistor values are fine.

Using the code template from the Microchip site makes things easier. You will have to change the CONFIG statement for your requirements.
Rich (BB code):
;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F84A. This file contains the basic code               *
;   building blocks to build upon.                                    *  
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:        xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F84A.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


    list      p=16F84A            ; list directive to define processor
    #include <p16F84A.inc>        ; processor specific variable definitions

    __CONFIG   _CP_OFF & _WDT_ON & _PWRTE_ON & _RC_OSC

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.




;***** VARIABLE DEFINITIONS
w_temp        EQU     0x0C        ; variable used for context saving 
status_temp   EQU     0x0D        ; variable used for context saving








;**********************************************************************
        ORG     0x000             ; processor reset vector
          goto    main              ; go to beginning of program


        ORG     0x004             ; interrupt vector location
        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


; isr code can go here or be located as a call subroutine elsewhere


        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



main

; remaining code goes here










        END                     ; directive 'end of program'
 
Last edited:

Markd77

Joined Sep 7, 2009
2,806
As far as programming goes, the counting and 7 segment goes on in the main loop and as soon as any button is pressed you have a winner and it is game over, so really there are only 2 states. If you have the user buttons on interrupt on change pins it becomes fairly simple.
 

BMorse

Joined Sep 26, 2009
2,675
I would have gone with the pic16f628a (as MarkD pointed out) instead of the F84, since it is newer, cheaper, and has more built in features, such as an internal 4mhz oscillator, you could have just used this to minimize board components....

also, I would connect the LED's the other way around,



Better to sink than source current from the pic pin.



B. Morse
 

Thread Starter

farscape

Joined May 16, 2010
26
Thank you both very much for the tips.

Ive updated the schematic and hopefully fixed most of my errors.
-I dont recall seeing the pic16f828a in our lab so I think Ill stick with the 84a just to be safe.
-If I switch the LED's around so that they are powered from VCC then with my vague understanding, it seems like both LED's will always be lit... Or will the pins be floating so that there is no current?

About the interrupt pins (RB4, RB5)
-Ive been reading about the interrupt function, but I'm not quite sure if I'm understanding... So when there is a change of state in one of the player inputs (RB4 or RB5) the program enters a subroutine and I can specify that the unchanged input is cut off in this case? Or does this have something to do with a player incorrectly powering his/her input before the counting sequence has finished? Can you dumb this down for me a bit?

As far as the programming goes, I'll start to stumble through it and get something posted later today. But in general this is how I will try to organize things. I hope I'm not too far off...
-Once reset is asserted, CLKOUT goes high and powers the crystal oscillator which drives CLKIN at 4Mhz.
-I want six out of seven of the output bits to start high to show a "9" on the display, after 1 second all 7 outputs high to show a "8" and continue this until I get to 0 at 9 seconds.
-Is this sort of a trial and error process where I need to keep adding counting sequences until I come up with approximately 1 second in terms of oscillations of CLKIN or is there a less clumsy way to go about this?
-After 9 seconds, the display shows "0" for 1 second and then the inputs are enabled and the first player's input to go high is sent to the output and the LED is lit, disabling the second player's input.
-I'm at a loss as to how I'm going to program the event where a player asserts his input before the counting sequence is complete. I forgot to mention this but the player who "jumps the gun" is supposed to have his LED flash for a moment and then the other player has his LED turn on and remain lit until the reset in pushed.

Anyways, Ill see what I can come up with this afternoon. Thanks a lot
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
With the alternate LED wiring (delete the ground symbols - I'm not sure what they are doing there) If you output a 1 they will be off, a 0 they will be on. If both ends of the LED are at 5V no current can flow.

If you set the interrupt to trigger on pin change the program executes the main timing and 7 segment update loop until one of the buttons is pressed then enters the interrupt. At this point the game is over, you just need to use a bit of logic to decide who has won and then display the result. Counting doesen't need to carry on at this point.
It doesn't matter at which point a player presses a button - as soon as they press they have either won or lost depending on the count timer.

You can use this to get your 1 second delay:
http://www.piclist.com/tecHREF/piclist/codegen/delay.htm
 

Thread Starter

farscape

Joined May 16, 2010
26
Sorry for the delay, this is turning out to be more difficult for me then I had imagined. I think I may be going about this programming the most primitive way possible but here it goes... (My code is attached on the next page)

In an earlier lab we set up a pic16f84a to blink an LED once a second so I'm hoping I can use that code to break things down into 1 second segments and then after each 1 second segment I can change the state of the outputs to reflect the countdown sequence on the LED display.

I hope this isn't completely wrong, but I'm hoping in my initialization, that I can assign different output states
(pin values) that correspond to the value of the count.
-So, initially, when the count is at 10 the output pins to the display show a "9"
-and then after 1 second, count=9 and this corresponds to a different state I specified in initialization
where the output displays an "8" and so on

If by some miracle, this is one way to go about this, do you know how I could set these initial values for my display?

Thanks for your patience
 
Last edited:

Markd77

Joined Sep 7, 2009
2,806
Try this. I put a table in which obviously you will have to alter according to how your 7seg is wired.

I also put the donothing loop which stops it from rolling through and restarting.

I presume you have set the CONFIG elsewhere but you might want to post that to check.

You can insert code by going advanced, highlighting the code and clicking the
button.

Still more work to do but it's a good start.

If you want to know more about tables read AN556 on the microchip site. You probably only need to look at the most simple method as your program will probably not be very long.

Rich (BB code):
;----------------------------------------------------------------------
;    cpu equates (memory map)
portB    equ    0x06        ; (p. 10 defines port address)
count    equ    0x0c
nCount    equ    0x0d
mCount    equ    0x0e
;----------------------------------------------------------------------

    org    0x000

start    movlw    0x00        ; load W with 0x00 make port B output (p. 45)
    tris    portB        ; copy W tristate, port B outputs (p. 58)
    clrf    portB        ; clear all lines low



get_cnt    movf    count, w    ; move count to W
    ;movlw   0x0A                ; set w=10 decimal
    
    call table
            movwf    portB        ; move W to port B
    call    pause        ; delay by subroutine
    call    pause        
    call    pause
    call    pause
    call    pause        ; five pause executions equals ~ 1 second
    decfsz    count, f                ; decrement counter, skip if=0
    goto    get_cnt        ; repeat forever

doNothing
    goto doNothing


table    addwf PCL
    retlw b'00000001'
    retlw b'00000010'
    retlw b'00000100'
    retlw b'00001000'
    retlw b'00010000'
    retlw b'00100000'
    retlw b'01000000'
    retlw b'10000000'
    retlw b'11111111'
    retlw b'10101010'
    retlw b'01010101'


pause    movlw    0xff        ; set w = 255 decimal
    movwf    mCount        ; mCount = w
loadN    movlw    0xff        ; set w = 255 decimal
    movwf    nCount        ; nCount = w
decN    decfsz    nCount, f    ; nCount--
    goto    decN        ; if nCount != 0 then repeat nCount--
    decfsz    mCount, f    ; else decrement Count
    goto    loadN        ; if mCount != 0 then 
                ;   reload nCount to 255 and decrement
    return            ; else exit subroutine

    end
---------------------------------------------------------------------------------------
 
Last edited:

Thread Starter

farscape

Joined May 16, 2010
26
Sorry to be such a nuisance, but I read the an556 and I'm not quite sure exactly what the table does.

Does each line of the table correspond to one of my outputs to the 7 segment? And so does that mean I'll have to make 9 seperate tables for each number I want displayed?

Thanks
 

Markd77

Joined Sep 7, 2009
2,806
Actually I just spotted a mistake I made which could be confusing you; this bit:

Rich (BB code):
get_cnt    movf    count, w    ; move count to W
         ;movlw   0x0A                ; set w=10 decimal
should change to:

Rich (BB code):
     movlw   0x0A                ; set w=10 decimal
     movf count, F
get_cnt    movf    count, w    ; move count to W
Each line is for 1 second and displays a digit.

When you call table the addwf PCL makes it jump forward to one of the retlw instructions.
If W is 0 it goes to the line immediately after the addwf line.
If W is 10 it goes to the last one (the 11th retlw)
Whatever value is in the retlw instruction is now in W and it returns to the instruction after "call table" which puts W onto port B.
The b'11111111' just means binary and is the equivalent of FF hex or 255 decimal. It would light up all the segments which would display an "8" on the 7 seg. The left 1 equates to PORTB7 and the right 1 is B0 (which you aren't using so doesen't matter.
I hope I've explained this clearly, but if not, ask away.
 

Thread Starter

farscape

Joined May 16, 2010
26
Yes, I think I understand now. Thank you so much.

I've written into the table, the values for my 7 segment corresponding to the pins on my PIC. I'm assuming that I should be using RB1-RB7 for this, so I altered the wiring for the rest of the PIC to allow this. Hopefully that's correct.

Ive attached my updated schematic and code if you don't mind taking a look.
-I added the CONFIG I came up with, but I'm a little uncertain how much information I need to include in this...

Rich (BB code):
;----------------------------------------------------------------------
;    cpu equates (memory map)
portB    equ    0x06        ; (p. 10 defines port address)
count    equ    0x0c
nCount    equ    0x0d
mCount    equ    0x0e
;----------------------------------------------------------------------

    
processor 16F84A
INCLUDE "p16f84A.inc"
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
org H’00’


start    movlw    0x00        ; load W with 0x00 make port B output (p. 45)
         tris    portB        ; copy W tristate, port B outputs (p. 58)
         clrf    portB        ; clear all lines low

         movlw   0x0A         ; set w=10 decimal
         movf    count, F
get_cnt  movf    count, w     ; move count to W

    
         call    table
         movwf   portB        ; move W to port B
         call    pause        ; delay by subroutine
         call    pause        
         call    pause
         call    pause
         call    pause        ; five pause executions equals ~ 1 second
         decfsz  count, f     ; decrement counter, skip if=0
         goto    get_cnt      ; repeat forever

doNothing
         goto doNothing


table    addwf PCL
         retlw b'00000000'
         retlw b'01111110'
         retlw b'00000100'
         retlw b'10110110'
         retlw b'10011110'
         retlw b'11001100'
         retlw b'11011010'
         retlw b'11111010'
         retlw b'00001110'
         retlw b'11111110'
         retlw b'11011110'


pause    movlw    0xff        ; set w = 255 decimal
         movwf    mCount      ; mCount = w
loadN    movlw    0xff        ; set w = 255 decimal
         movwf    nCount      ; nCount = w
decN     decfsz   nCount, f   ; nCount--
         goto     decN        ; if nCount != 0 then repeat nCount--
         decfsz   mCount, f   ; else decrement Count
         goto     loadN       ; if mCount != 0 then 
                              ;   reload nCount to 255 and decrement
         return               ; else exit subroutine

    end
---------------------------------------------------------------------------------------
Thanks
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
Looks ok, I hadn't noticed the revised drawing with the alternate 7seg pins.
I think it is probably just as easy to check the user inputs in the decN loop of the pause subroutine. Saves setting up the interrupt, messing around with 2 ports for the 7 seg, and will just require a bit of tweaking to get the pause back to 1/5 second.
If you put a pause in the doNothing loop it will then carry on checking.

It's worth checking if you need the capacitors from the crystal to ground.
It's probably a good idea to put a 10nF capacitor between Vdd and Vss for stability.
 
Last edited:

MMcLaren

Joined Feb 14, 2010
861
Hi farscape (and gang),

If you were to connect RB0..RB6 to segments A..G then you could use a segment data table that looks something like this;
Rich (BB code):
;
;  segment data table (caveat, non-boundary tolerant)
;
segtbl
        addwf   PCL,F           ;                                 |B0
        dt      b'00111111'     ; "0"   -|-|F|E|D|C|B|A           |B0
        dt      b'00000110'     ; "1"   -|-|-|-|-|C|B|-           |B0
        dt      b'01011011'     ; "2"   -|G|-|E|D|-|B|A           |B0
        dt      b'01001111'     ; "3"   -|G|-|-|D|C|B|A           |B0
        dt      b'01100110'     ; "4"   -|G|F|-|-|C|B|-           |B0
        dt      b'01101101'     ; "5"   -|G|F|-|D|C|-|A           |B0
        dt      b'01111101'     ; "6"   -|G|F|E|D|C|-|A           |B0
        dt      b'00000111'     ; "7"   -|-|-|-|-|C|B|A           |B0
        dt      b'01111111'     ; "8"   -|G|F|E|D|C|B|A           |B0
        dt      b'01101111'     ; "9"   -|G|F|-|D|C|B|A           |B0
I wrote a sample program for your application yesterday which I can post when I get home tonight, if you're interested.

Regards, Mike
 
Last edited:

Thread Starter

farscape

Joined May 16, 2010
26
Okay, assuming the pinouts I have specified are good to go, I think I may have figured out how to program the check into the pause routine... Am I on the right track with this?

I also initialized the portA pins as well

Rich (BB code):
;----------------------------------------------------------------------
;    cpu equates (memory map)
portB    equ    0x06        ; (p. 10 defines port address)
count    equ    0x0c
nCount   equ    0x0d
mCount   equ    0x0e
portA    equ    0x05 
;----------------------------------------------------------------------

    
processor 16F84A
INCLUDE "p16f84A.inc"
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
org H’00’


start    movlw    0x00        ; load W with 0x00 make port B output (p. 45)
         tris    portB        ; copy W tristate, port B outputs (p. 58)
         clrf    portB        ; clear all lines low
         movlw    0x0C        ; load w with 0x0C make RA0,RA1 output and RA2,RA3 input
         tris    portA        ; copy W tristate
      
         movlw   0x0A         ; set w=10 decimal
         movf    count, F
get_cnt  movf    count, w     ; move count to W

    
         call    table
         movwf   portB        ; move W to port B
         call    pause        ; delay by subroutine
         call    pause        
         call    pause
         call    pause
         call    pause        ; five pause executions equals ~ 1 second
         decfsz  count, f     ; decrement counter, skip if=0
         goto    get_cnt      ; repeat forever

doNothing
         goto doNothing


table    addwf PCL
         retlw b'00000000'
         retlw b'01111110'
         retlw b'00000100'
         retlw b'10110110'
         retlw b'10011110'
         retlw b'11001100'
         retlw b'11011010'
         retlw b'11111010'
         retlw b'00001110'
         retlw b'11111110'
         retlw b'11011110'


pause    movlw    0xff        ; set w = 255 decimal
         movwf    mCount      ; mCount = w
loadN    movlw    0xff        ; set w = 255 decimal
         movwf    nCount      ; nCount = w
decN     decfsz   nCount, f   ; nCount--
         goto     decN        ; if nCount != 0 then repeat nCount--   
         decfsz   mCount, f   ; else decrement Count
         BTFSS    portA, b'10'
         goto     loadN       ; if mCount != 0 then 
         call     flash1                     
         return               ; else exit subroutine

flash1   bsf      portA, b'10'
         movlw    0xff        ; set w = 255 decimal
         movwf    mCount      ; mCount = w
loadN1   movlw    0xff        ; set w = 255 decimal
         movwf    nCount      ; nCount = w
decN1    decfsz   nCount, f   ; nCount--
         goto     decN1        ; if nCount != 0 then repeat nCount--   
         decfsz   mCount, f   ; else decrement Count
         goto     loadN1
         bcf      portA, b'10'
         bsf      portA, b'01'
         goto     doNothing
end
---------------------------------------------------------------------------------------
Thanks
 

Attachments

Thread Starter

farscape

Joined May 16, 2010
26
Hi Mike,

Thanks for the tip. I'm very new at this so I'm unfamiliar with a segment data table. What is the "dt" command?

And I would love to see what you came up with for a program if you get a chance to post it.

Thanks
 

MMcLaren

Joined Feb 14, 2010
861
farscape,

I think you're on the right track but there are a couple things that don't look right.

The 'dt' assembler directive creates 'retlw' instructions.

If it will help, here's the example program I came up with yesterday. Each 1-second interval is made up of 200 5-msec intervals where we sample the switches on RA0 and RA1. The display is updated at the end of each 1 second interval. A switch press takes you out of the 1-second loop. Then you determine which switch was pressed and if it was pressed early (early == time > 0).

Regards, Mike

Rich (BB code):
;       #include <P16F84A.INC>
        radix dec

time    equ     0x0C            ; time, 0..9 seconds
sectmr  equ     0x0D            ; 1-second timer
DelayHi equ     0x0E            ; DelayCy() subsystem variable

;******************************************************************
;  K8LH DelayCy() subsystem macro generates four instructions
;
        radix   dec
clock   equ     4               ; clock frequency in Megahertz
usecs   equ     clock/4         ; cycles/microsecond multiplier
msecs   equ     clock/4*1000    ; cycles/millisecond multiplier

DelayCy macro   delay           ; 11..327690 cycle range
        movlw   high((delay-11)/5)+1
        movwf   DelayHi
        movlw   low ((delay-11)/5)
        call    uDelay-((delay-11)%5)
        endm

;******************************************************************
;  Reset Vector                                                   *
;******************************************************************
        org     0x0000
v_reset
        clrf    STATUS          ; bank 0                          |B0
        clrf    PORTA           ;                                 |B0
        clrf    PORTB           ;                                 |B0
        banksel TRISA           ; bank 1                          |B1
        movlw   3               ;                                 |B1
        movwf   TRISA           ; RA1:RA0 inputs                  |B1
        clrf    TRISB           ; portb all outputs               |B1
        banksel PORTA           ; bank 0                          |B0
;
;  initialize program variables
;
        movlw   9               ;                                 |B0
        movwf   time            ; time = 9                        |B0
        call    segtbl          ; get segment data pattern        |B0
        movwf   PORTB           ; display "9"                     |B0
;
;  main.loop
;
newsec
        movlw   1000/5          ; 1000-msecs/5-msecs              |B0
        movwf   sectmr          ; turn on 1-second timer          |B0
sample
        DelayCy(5*msecs-7)      ; delay 5-msecs minus 7 cycles    |B0
        comf    PORTA,F         ; sample active lo switches       |B0
        andlw   3               ; on RA1:RA0 pins                 |B0
        skpz                    ; new press? no, skip, else       |B0
        goto    testsw          ; branch and test                 |B0
        decfsz  sectmr,F        ; 1-sec timeout? yes, skip,else   |B0
        goto    sample          ;                                 |B0
        movf    time,W          ; 9 second time out?              |B0
        skpnz                   ; no, skip, else                  |B0
        goto    newsec          ; just waiting for a press now    |B0
        decf    time,F          ; decrement time                  |B0
        movf    time,W          ; W = time, 0..8                  |B0
        call    segtbl          ; get segment data                |B0
        movwf   PORTB           ; display new time                |B0
        goto    newsec          ;                                 |B0
testsw
        movf    time,F          ; timer timed out (0)?            |B0
        skpz                    ; yes, skip, else                 |B0
        goto    early           ; branch (pressed too early)      |B0
        andlw   1               ; switch 1 press?                 |B0
        skpnz                   ; yes, skip, else                 |B0
        goto    light2          ; light LED 2                     |B0
        goto    light1          ; light LED 1                     |B0
early
        andlw   1               ; switch 1 pressed early?         |B0
        skpnz                   ; yes, skip, else                 |B0
        goto    light1          ; light LED 1                     |B0
        goto    light2          ; light LED 2                     |B0
light1
        bsf     PORTA,2         ; light LED 1 on RA2              |B0
        goto    $               ; loop forever (wait for reset)   |B0
light2
        bsf     PORTA,3         ; light LED 2 on RA3              |B0
        goto    $               ; loop forever (wait for reset)   |B0
;******************************************************************
;  segment data lookup table (caveat, non-boundary tolerant)
;
segtbl
        addwf   PCL,F           ;                                 |B0
        retlw   b'00111111'     ; "0"   -|-|F|E|D|C|B|A           |B0
        retlw   b'00000110'     ; "1"   -|-|-|-|-|C|B|-           |B0
        retlw   b'01011011'     ; "2"   -|G|-|E|D|-|B|A           |B0
        retlw   b'01001111'     ; "3"   -|G|-|-|D|C|B|A           |B0
        retlw   b'01100110'     ; "4"   -|G|F|-|-|C|B|-           |B0
        retlw   b'01101101'     ; "5"   -|G|F|-|D|C|-|A           |B0
        retlw   b'01111101'     ; "6"   -|G|F|E|D|C|-|A           |B0
        retlw   b'00000111'     ; "7"   -|-|-|-|-|C|B|A           |B0
        retlw   b'01111111'     ; "8"   -|G|F|E|D|C|B|A           |B0
        retlw   b'01101111'     ; "9"   -|G|F|-|D|C|B|A           |B0
;******************************************************************
;  DelayCy() subsystem uDelay subroutine
;
        nop                     ; entry for (delay-11)%5 == 4     |B0
        nop                     ; entry for (delay-11)%5 == 3     |B0
        nop                     ; entry for (delay-11)%5 == 2     |B0
        nop                     ; entry for (delay-11)%5 == 1     |B0
uDelay  addlw   -1              ; subtract "loop" cycle time      |B0
        skpc                    ; borrow? no, skip, else          |B0
        decfsz  DelayHi,F       ; done?  yes, skip, else          |B0
        goto    uDelay          ; do another loop                 |B0
        return                  ;                                 |B0
;******************************************************************
        end
 

Attachments

Last edited:
Top