user25136115
user25136115

Reputation: 1

Issue with the delay and the toggle on PIC16F84A micro

Task 1: Create a 1 Hz Square Waveform on PORT.A0

Write an assembly language program to create a 1 Hz square waveform on PORT A0. a) First write your code to toggle PORT A0 without any delay b) Then add a delay subroutine to produce the required delay. You are not allowed to use Timer Interrupt for the delay subroutine.

I keep getting an error about my delay but i tried may ways and still wrong

Task 2: Up/Down Counter on PORT A

The goal of this task is to write an assembly code which can count every 1 second from 0000 to 1111 or in reverse order from 1001 to 0000 based on the 2 inputs RA0 and RA1 shown in the Table 1.

When the counting has reaches maximum (1111 for count up) or minimum (0000 for count down), the counting will loop back to the other end (start from 0000 again for count up, or start from 1111 again for count down). The 4-bit output of the counting should be sent to outputs RB7:4, where RB7 as MSB and RB4 as LSB. See the requirement table below.

Table 1

for this one i cant count up or down , during pause it works

Code for task 1:

__CONFIG    _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _PWRTE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _DEBUG_OFF
__CONFIG    _CONFIG2, _CP_OFF


START:
    bcf     STATUS, RP0        ; Select Bank 0
    clrf    PORTB               ; Clear PORTB
    movlw   0x00                ; Initialize PORTB to 0
    movwf   PORTB
    movlw   b'00001111'        ; Set RB7:4 as outputs, RB3:0 as inputs
    movwf   TRISB
    movlw   b'11111100'        ; Set RA0 and RA1 as inputs
    movwf   TRISA

MainLoop:
    btfsc   PORTA, 1           ; Check if RA1 is low (counter disable)
    goto    MainLoop           ; If RA1 is low, do nothing

    btfsc   PORTA, 0           ; Check if RA0 is low (count down)
    goto    CountDown
    goto    CountUp

CountUp:
    call    Delay1Sec          ; Wait for 1 second
    incf    PORTB, F           ; Increment PORTB
    movf    PORTB, W
    andlw   b'11110000'        ; Mask the lower 4 bits
    xorlw   b'11110000'        ; Check if it is 1111
    btfss   STATUS, Z          ; If it is not 1111, skip the next line
    movlw   b'00000000'        ; Reset to 0000 if it was 1111
    movwf   PORTB
    goto    MainLoop

CountDown:
    call    Delay1Sec          ; Wait for 1 second
    decf    PORTB, F           ; Decrement PORTB
    movf    PORTB, W
    andlw   b'11110000'        ; Mask the lower 4 bits
    btfsc   STATUS, Z          ; If result is not 0000, skip the next line
    movlw   b'11110000'        ; Set to 1111 if it was 0000
    movwf   PORTB
    goto    MainLoop

Delay1Sec:
    ; Implement a delay here that approximates 1 second
    ; This delay loop is just a placeholder and should be calibrated
    movlw   D'255'
    movwf   count1
OuterDelayLoop:
    movlw   D'255'
    movwf   count2
InnerDelayLoop:
    decfsz  count2, f
    goto    InnerDelayLoop
    decfsz  count1, f
    goto    OuterDelayLoop
    return

    END

Code for task 2:

    ORG     0x00
    goto    START

    ORG     0x04                ; Interrupt vector

START:
    bcf     STATUS, RP0        ; Select Bank 0
    clrf    PORTB               ; Clear PORTB
    movlw   0x00                ; Initialize PORTB to 0
    movwf   PORTB
    movlw   b'00001111'        ; Set RB7:4 as outputs, RB3:0 as inputs
    movwf   TRISB
    movlw   b'11111100'        ; Set RA0 and RA1 as inputs
    movwf   TRISA

MainLoop:
    btfsc   PORTA, 1           ; Check if RA1 is low (counter disable)
    goto    MainLoop           ; If RA1 is low, do nothing

    btfsc   PORTA, 0           ; Check if RA0 is low (count down)
    goto    CountDown
    goto    CountUp

CountUp:
    call    Delay1Sec          ; Wait for 1 second
    incf    PORTB, F           ; Increment PORTB
    movf    PORTB, W
    andlw   b'11110000'        ; Mask the lower 4 bits
    xorlw   b'11110000'        ; Check if it is 1111
    btfss   STATUS, Z          ; If it is not 1111, skip the next line
    movlw   b'00000000'        ; Reset to 0000 if it was 1111
    movwf   PORTB
    goto    MainLoop

CountDown:
    call    Delay1Sec          ; Wait for 1 second
    decf    PORTB, F           ; Decrement PORTB
    movf    PORTB, W
    andlw   b'11110000'        ; Mask the lower 4 bits
    btfsc   STATUS, Z          ; If result is not 0000, skip the next line
    movlw   b'11110000'        ; Set to 1111 if it was 0000
    movwf   PORTB
    goto    MainLoop

Delay1Sec:
    ; Implement a delay here that approximates 1 second
    ; This delay loop is just a placeholder and should be calibrated
    movlw   D'255'
    movwf   count1
OuterDelayLoop:
    movlw   D'255'
    movwf   count2
InnerDelayLoop:
    decfsz  count2, f
    goto    InnerDelayLoop
    decfsz  count1, f
    goto    OuterDelayLoop
    return

    END

Upvotes: 0

Views: 91

Answers (2)

Dan1138
Dan1138

Reputation: 1225

user25136115,

It seems that you may need someone to show actual working code for all three parts of your assignment.

Here is task 1a:

;
; File:     task1a.asm
; Target:   PIC16F84A
; Author:   dan1138
; Date:     2024-05-31
; Compiler: MPASM v5.22
;
; Description:
;
;   Homework example
;   See: https://stackoverflow.com/questions/78504317/issue-with-the-delay-and-the-toggle

;   Task 1: 
;       Create a 1 Hz Square Waveform on PORTA bit 0 
;       Write an assembly language program to create a 1 Hz square waveform on PORT A0. 
;           a) First write your code to toggle PORT A0 without any delay 
;           b) Then add a delay subroutine to produce the required delay. 
;       You are not allowed to use Timer Interrupt for the delay subroutine.
;
;                           PIC16F84A
;                   +----------:_:----------+
;             <>  1 : RA2               RA1 : 18 <> 
;             <>  2 : RA3               RA0 : 17 <> Output
;             <>  3 : RA4/T0CKI        OSC1 : 16 <- 4MHz crystal
;    ICSP_VPP ->  4 : MCLR             OSC2 : 15 -> 4MHz crystal
;         GND ->  5 : GND               VDD : 14 <- 5v0
;             <>  6 : RB0/INT       PGD/RB7 : 13 <> ICSP_PGD
;             <>  7 : RB1           PGC/RB6 : 12 <> ICSP_PGC
;             <>  8 : RB2               RB5 : 11 <> 
;             <>  9 : RB3               RB4 : 10 <> 
;                   +-----------------------:
;                            DIP-18

  include "p16f84a.inc"
  list   n=0,c=132,r=dec
  errorlevel -302
 
 __CONFIG   (_FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF)

    org     0
START:
    bsf     STATUS, RP0             ; Select Bank 1
    movlw   b'11111110'             ; Set RA0 as output
    movwf   TRISA

    bcf     STATUS, RP0             ; Select Bank 0
    movlw   b'00000001'
MainLoop:
    xorwf   PORTA,F
    goto    MainLoop

    END

Here is task 1b:

;
; File:     task1b.asm
; Target:   PIC16F84A
; Author:   dan1138
; Date:     2024-05-31
; Compiler: MPASM v5.22
;
; Description:
;
;   Homework example
;   See: https://stackoverflow.com/questions/78504317/issue-with-the-delay-and-the-toggle

;   Task 1: 
;       Create a 1 Hz Square Waveform on PORTA bit 0 
;       Write an assembly language program to create a 1 Hz square waveform on PORT A0. 
;           a) First write your code to toggle PORT A0 without any delay 
;           b) Then add a delay subroutine to produce the required delay. 
;       You are not allowed to use Timer Interrupt for the delay subroutine.
;
;                           PIC16F84A
;                   +----------:_:----------+
;             <>  1 : RA2               RA1 : 18 <> 
;             <>  2 : RA3               RA0 : 17 <> One_Hz_Output
;             <>  3 : RA4/T0CKI        OSC1 : 16 <- 4MHz crystal
;    ICSP_VPP ->  4 : MCLR             OSC2 : 15 -> 4MHz crystal
;         GND ->  5 : GND               VDD : 14 <- 5v0
;             <>  6 : RB0/INT       PGD/RB7 : 13 <> ICSP_PGD
;             <>  7 : RB1           PGC/RB6 : 12 <> ICSP_PGC
;             <>  8 : RB2               RB5 : 11 <> 
;             <>  9 : RB3               RB4 : 10 <> 
;                   +-----------------------:
;                            DIP-18
 include "p16f84a.inc"
 list   n=0,c=132,r=dec
 errorlevel -302
 
 __CONFIG   (_FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF)
;
#define T0_COUNTS_PER_TICK 125
#define TICKS_PER_TENTH_SEC 25
;
; Allocate RAM
  cblock 0x10
    T0_Sample : 1
    TicksInTenthSecCount : 1
    TenthSecondCount : 1
  endc
;
    org     0
START:
    bsf     STATUS, RP0             ; Select Bank 1
    movlw   b'11111110'             ; Set RA0 as output
    movwf   TRISA
    movlw   0x84                    ; TMR0 clock source Fosc/4, TMR0 prescale 1:32
    movwf   OPTION_REG

    bcf     STATUS, RP0             ; Select Bank 0
    clrf    TMR0
    clrf    T0_Sample
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
    movlw   10
    movwf   TenthSecondCount

MainLoop:
    call    Wait4ms
    decfsz  TicksInTenthSecCount,F
    goto    MainLoop
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
;
; count tenths of seconds
    movf    TenthSecondCount,F
    skpz    
    decfsz  TenthSecondCount,F
    goto    MainLoop
    movlw   10
    movwf   TenthSecondCount
    
    movlw   b'00000001'
    xorwf   PORTA,F                 ; Toggle RA0
    goto    MainLoop
    
;
; Wait 4 milliseconds
Wait4ms:
    movf    T0_Sample,W
    subwf   TMR0,W
    sublw   T0_COUNTS_PER_TICK
    skpnc
    goto    Wait4ms
    movlw   T0_COUNTS_PER_TICK
    addwf   T0_Sample,F
    return

    END

Here is task 2:

;
; File:     task2.asm
; Target:   PIC16F84A
; Author:   dan1138
; Date:     2024-05-31
; Compiler: MPASM v5.22
;
; Description:
;
;   Homework example
;   See: https://stackoverflow.com/questions/78504317/issue-with-the-delay-and-the-toggle
;
;   Task 2: 
;       Up/Down Counter on PORT A 
;       The goal of this task is to write an assembly code which can count 
;       every 1 second from 0000 to 1111 or in reverse order from 1111 to 0000 
;       based on the 2 inputs RA0 and RA1 shown in the Table 1. 
;
;       When the counting has reaches maximum (1111 for count up) or 
;       minimum (0000 for count down), the counting will loop back to 
;       the other end (start from 0000 again for count up, 
;       or start from 1111 again for count down). 
;
;       The 4-bit output of the counting should be sent to outputs RB7:4, 
;       where RB7 as MSB and RB4 as LSB.
;
;   Table 1:
;           +-------+-------+-------------------------+
;           :    Input      :         output          :
;           +-------+-------+-------------------------+
;           :  RA0  :  RA1  :     Counting(RB7:4)     :
;           +-------+-------+-------------------------+
;           :   0   :   0   :         paused          :
;           +-------+-------+-------------------------+
;           :   0   :   1   :        Count up         :
;           +-------+-------+-------------------------+
;           :   1   :   0   :       Count down        :
;           +-------+-------+-------------------------+
;           :   1   :   1   : Reset to 0000 and pause :
;           +-------+-------+-------------------------+
;
;                           PIC16F84A
;                   +----------:_:----------+
;             <>  1 : RA2               RA1 : 18 <> Button_2
;             <>  2 : RA3               RA0 : 17 <> Button_1
;             <>  3 : RA4/T0CKI        OSC1 : 16 <- 4MHz crystal
;    ICSP_VPP ->  4 : MCLR             OSC2 : 15 -> 4MHz crystal
;         GND ->  5 : GND               VDD : 14 <- 5v0
;             <>  6 : RB0/INT       PGD/RB7 : 13 <> LED_3/ICSP_PGD
;             <>  7 : RB1           PGC/RB6 : 12 <> LED_2/ICSP_PGC
;             <>  8 : RB2               RB5 : 11 <> LED_1
;             <>  9 : RB3               RB4 : 10 <> LED_0
;                   +-----------------------:
;                            DIP-18
 include "p16f84a.inc"
 list   n=0,c=132,r=dec
 errorlevel -302
 
 __CONFIG   (_FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF)
;
#define T0_COUNTS_PER_TICK 125
#define TICKS_PER_TENTH_SEC 25
;
; Allocate RAM
  cblock 0x10
    T0_Sample : 1
    TicksInTenthSecCount : 1
    TenthSecondCount : 1
    OneSecondCount : 1
  endc
;
    org     0
START:
    bsf     STATUS, RP0             ; Select Bank 1
    movlw   b'11111111'             ; Set RA0:1 as input
    movwf   TRISA
    movlw   b'00001111'             ; Set RB7:4 as output
    movwf   TRISB
    movlw   0x84                    ; TMR0 clock source Fosc/4, TMR0 prescale 1:32
    movwf   OPTION_REG

    bcf     STATUS, RP0             ; Select Bank 0
    clrf    TMR0
    clrf    T0_Sample
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
    movlw   10
    movwf   TenthSecondCount
    clrf    OneSecondCount


MainLoop:
    call    Wait4ms
    decfsz  TicksInTenthSecCount,F  ; Count number of 4ms ticks in 100ms
    goto    MainLoop
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
;
; count tenths of seconds
    movf    TenthSecondCount,F      ; When tenths of second counter is zero
    skpz                            ; stop all counting.
    decfsz  TenthSecondCount,F      ; When tenths of second counter decrement 
    goto    MainLoop                ; from 1 to zero one second has elapsed.
    movlw   10
    movwf   TenthSecondCount        ; Restart tenths of second counter
;
; count seconds
    movf    PORTA,W
    andlw   b'00000011'             ; check for no button pressed
    skpnz
    goto    ShowCount               ; no button pressed so pause
    xorlw   b'00000011'             ; check for both buttons pressed
    skpz
    goto    CheckForWhichButton
    clrf    OneSecondCount          ; both buttons pressed so reset
    goto    ShowCount
CheckForWhichButton:
    xorlw   b'00000011' ^ b'0000001'; Check for RA0 pressed
    skpnz
    decf    OneSecondCount,F        ; RA0 pressed so count down
    xorlw   b'0000001' ^ b'0000010' ; Check for RA1 pressed
    skpnz
    incf    OneSecondCount,F        ; RA1 pressed so count up  
ShowCount:
    swapf   OneSecondCount,W        ; Put bit 3:0 in bits 7:4 of WREG
    xorwf   PORTB,W                 ; Make mask of what to change on PORTB
    andlw   b'11110000'             ; Change only RB7:4
    xorwf   PORTB,F                 ; Show current 4-bit count on PORTB
    goto    MainLoop
;
; Wait 4 milliseconds
Wait4ms:
    movf    T0_Sample,W
    subwf   TMR0,W
    sublw   T0_COUNTS_PER_TICK
    skpnc
    goto    Wait4ms
    movlw   T0_COUNTS_PER_TICK
    addwf   T0_Sample,F
    return

    END

My expectation is that you must submit the completed assignment in the next week or less.

So good luck.

Upvotes: 0

Dan1138
Dan1138

Reputation: 1225

First off be warned this answer is a lot more code than your homework assignment requires. Submit this and you will fail the assignment.

This code does conform to the "letter" of your tasks but it does them all in one application.

The stipulation to not use the timer interrupt is a bit of a problem but nowhere does it say you cannot use the timer to determine how much real time has elapsed.

I suspect that your instructor wants you doing a lot of tedious instruction cycle counting to create a callable delay function.

The code uses techniques your instructor may not have mentioned, so until you can explain how this code works to yourself don't let your instructor think you wrote it.

;
; File:     main.S
; Target:   PIC16F84A
; Author:   dan1138
; Date:     2024-05-30
; Compiler: pic-as v2.45
; IDE:      MPLABX v6.15
;
; Add this line in the project properties box, pic-as Global Options -> Additional options:
;   -Wa,-a -Wl,-pPor_Vec=0h,-pIsr_Vec=4h
;
; Description:
;
;   Homework example
;   See: https://stackoverflow.com/questions/78504317/issue-with-the-delay-and-the-toggle

;   Task 1: 
;       Create a 1 Hz Square Waveform on PORTA bit 0 
;       Write an assembly language program to create a 1 Hz square waveform on PORT A0. 
;           a) First write your code to toggle PORT A0 without any delay 
;           b) Then add a delay subroutine to produce the required delay. 
;       You are not allowed to use Timer Interrupt for the delay subroutine.
;
;   Task 2: 
;       Up/Down Counter on PORT A 
;       The goal of this task is to write an assembly code which can count 
;       every 1 second from 0000 to 1111 or in reverse order from 1001 to 0000 
;       based on the 2 inputs RA1 and RA2 shown in the Table 1. 
;
;       When the counting has reaches maximum (1111 for count up) or 
;       minimum (0000 for count down), the counting will loop back to 
;       the other end (start from 0000 again for count up, 
;       or start from 1111 again for count down). 
;
;       The 4-bit output of the counting should be sent to outputs RB7:4, 
;       where RB7 as MSB and RB4 as LSB.
;
;   Table 1:
;           +-------+-------+-------------------------+
;           :    Input      :         output          :
;           +-------+-------+-------------------------+
;           :  RA1  :  RA2  :     Counting(RB7:4)     :
;           +-------+-------+-------------------------+
;           :   0   :   0   :         paused          :
;           +-------+-------+-------------------------+
;           :   0   :   1   :        Count up         :
;           +-------+-------+-------------------------+
;           :   1   :   0   :       Count down        :
;           +-------+-------+-------------------------+
;           :   1   :   1   : Reset to 0000 and pause :
;           +-------+-------+-------------------------+
;
;                           PIC16F84A
;                   +----------:_:----------+
;    Button_2 <>  1 : RA2               RA1 : 18 <> Button_1
;             <>  2 : RA3               RA0 : 17 <> One_Hz_Output
;             <>  3 : RA4/T0CKI        OSC1 : 16 <- 4MHz crystal
;    ICSP_VPP ->  4 : MCLR             OSC2 : 15 -> 4MHz crystal
;         GND ->  5 : GND               VDD : 14 <- 5v0
;             <>  6 : RB0/INT       PGD/RB7 : 13 <> LED_3/ICSP_PGD
;             <>  7 : RB1           PGC/RB6 : 12 <> LED_2/ICSP_PGC
;             <>  8 : RB2               RB5 : 11 <> LED_1
;             <>  9 : RB3               RB4 : 10 <> LED_0
;                   +-----------------------:
;                            DIP-18

    PROCESSOR   16F84A
    PAGEWIDTH   132
    RADIX       DEC

#include <xc.inc>

; PIC16F84A Configuration Bit Settings
  CONFIG  FOSC = HS             ; Oscillator Selection bits (HS oscillator)
  CONFIG  WDTE = OFF            ; Watchdog Timer (WDT disabled)
  CONFIG  PWRTE = OFF           ; Power-up Timer Enable bit (Power-up Timer is disabled)
  CONFIG  CP = OFF              ; Code Protection bit (Code protection disabled)
;
; Skip macros
;
skpndc  MACRO
    btfsc   STATUS,STATUS_DC_POSITION
        ENDM

skpdc   MACRO
    btfss   STATUS,STATUS_DC_POSITION
        ENDM
skpnc  MACRO
    btfsc   STATUS,STATUS_C_POSITION
        ENDM

skpc   MACRO
    btfss   STATUS,STATUS_C_POSITION
        ENDM

skpnz  MACRO
    btfsc   STATUS,STATUS_Z_POSITION
        ENDM

skpz   MACRO
    btfss   STATUS,STATUS_Z_POSITION
        ENDM
;
; Power-On-Reset entry point
;
    PSECT   Por_Vec,global,class=CODE,delta=2
    global  resetVec
resetVec:
    goto    main
;
;   Data space use by interrupt handler to save context
    PSECT   Isr_Data,global,class=RAM,space=1,delta=1,noexec
;
    GLOBAL  WREG_save,STATUS_save,PCLATH_save
    GLOBAL  Segments
;
WREG_save:      ds      1
STATUS_save:    ds      1
PCLATH_save:    ds      1
Segments:       ds      2
;
;   Interrupt vector and handler
    PSECT   Isr_Vec,global,class=CODE,delta=2
    GLOBAL  IsrVec
;
IsrVec:
    movwf   WREG_save
    swapf   STATUS,W
    movwf   STATUS_save
    movf    PCLATH,W
    movwf   PCLATH_save
;
IsrHandler:

;
IsrExit:
    movf    PCLATH_save,W
    movwf   PCLATH
    swapf   STATUS_save,W
    movwf   STATUS
    swapf   WREG_save,F
    swapf   WREG_save,W
    retfie                      ; Return from interrupt
;
;objects in bank 0 memory, note PIC16F84 does not have banked memory
    PSECT   MainData,global,class=RAM,space=1,delta=1,noexec
    GLOBAL  T0_Sample,TicksInTenthSecCount,TenthSecondCount,OneSecondCount
    GLOBAL  SW_Flags
    GLOBAL  BTN_sample,BTN_stable,BTN_change,BTN_bounce

T0_Sample:      ds      1
#define T0_COUNTS_PER_TICK 125
#define TICKS_PER_TENTH_SEC 25
TicksInTenthSecCount: ds    1
TenthSecondCount:     ds    1
OneSecondCount:       ds    1
#define SW_1          SW_Flags,0
#define SW_1_MASK     0x01
#define SW_2          SW_Flags,1
#define SW_2_MASK     0x02
SW_Flags:       ds      1
#define DEBOUNCE_COUNT  2
#define BTN1_POSITION   1
#define BTN1_MASK       0x02
#define BTN2_POSITION   2
#define BTN2_MASK       0x04
BTN_sample:     ds      1
BTN_stable:     ds      1
BTN_change:     ds      1
BTN_bounce:     ds      1
;
; Applicaiton initialization
    PSECT   MainCode,global,class=CODE,delta=2
main:
    clrf    INTCON
    BANKSEL TRISB
    movlw   0x0F
    movwf   TRISB
    movlw   0xFE                ; RA0 output, RA1,RA2 inputs
    movwf   TRISA
    movlw   0x84                ; TMR0 clock source Fosc/4, TMR0 prescale 1:32
    movwf   OPTION_REG

    banksel TMR0
    clrf    TMR0
    clrf    T0_Sample
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
    movlw   10
    movwf   TenthSecondCount
    clrf    OneSecondCount

    clrf    BTN_sample
    clrf    BTN_stable
    clrf    BTN_change
    clrf    BTN_bounce
    clrf    SW_Flags
;
; Application process loop
AppLoop:
    call    Wait4ms
;
; debounce switches
    call    BTN_Poll
    iorlw   0
    skpnz               ; Skip if a button changed state
    goto    Count4msTicks
;
; Process button inputs
    movf    BTN_stable,W
    andwf   BTN_change,F
    btfsc   BTN_change,BTN2_POSITION
    bsf     SW_2        ; button 2 changed to pressed
    btfsc   BTN_change,BTN1_POSITION
    bsf     SW_1        ; button 1 changed to pressed
    clrf    BTN_change
;
; Process when button changed to pressed
    btfsc   SW_1
    call    SW_1_Process
    btfsc   SW_2
    call    SW_2_Process
;
; count 4ms ticks
Count4msTicks:
;
    decfsz  TicksInTenthSecCount,F
    goto    AppLoop
    movlw   TICKS_PER_TENTH_SEC
    movwf   TicksInTenthSecCount
;
; count tenths of seconds
    movf    TenthSecondCount,F
    skpz    
    decfsz  TenthSecondCount,F
    goto    AppLoop
    movlw   10
    movwf   TenthSecondCount
;
; do one Hz toggle on PORTA
    movlw   1
    xorwf   PORTA,F

    btfsc   BTN_stable,BTN1_POSITION
    goto    ButtonPressed
    btfsc   BTN_stable,BTN2_POSITION
    goto    ButtonPressed
;
; No buttons pressed,  state pause
    goto    ShowCount
ButtonPressed:
    btfss   BTN_stable,BTN1_POSITION
    goto    ButtonOneNotPressed
    btfss   BTN_stable,BTN2_POSITION
    goto    ButtonOneNotPressed
;
; Both buttons pressed, state Reset pause
    clrf    OneSecondCount
    goto    ShowCount
ButtonOneNotPressed:
    btfsc   BTN_stable,BTN2_POSITION
    incf    OneSecondCount,F
    btfsc   BTN_stable,BTN1_POSITION
    decf    OneSecondCount,F
ShowCount:
    swapf   OneSecondCount,W
    xorwf   PORTB,W
    andlw   0xF0
    xorwf   PORTB,F
    goto    AppLoop
;
; ============================================
; Button changed to pressed event processing
SW_1_Process:
    bcf     SW_1
    return
;
SW_2_Process:
    bcf     SW_2
    return
;
; ============================================
; Button polling
;
; poll buttons
; Returns: WREG = 0, no buttons changed
;          WREG = 1, buttons changed
BTN_Poll:
    clrw
    btfsc   PORTA,1
    iorlw   BTN1_MASK
    btfsc   PORTA,2
    iorlw   BTN2_MASK
    xorwf   BTN_sample,W
    skpnz
    goto    BTN_debounce
    xorwf   BTN_sample,F
    movlw   DEBOUNCE_COUNT
    movwf   BTN_bounce
    retlw   0
BTN_debounce:
    movf    BTN_bounce,F
    skpnz
    goto    BTN_debounce_done
    decfsz  BTN_bounce,F
    retlw   0
BTN_debounce_done:
    movf    BTN_sample,W
    xorwf   BTN_stable,W
    skpnz
    retlw   0
    iorwf   BTN_change,F
    xorwf   BTN_stable,F
    retlw   1
;
; Wait 4 milliseconds
Wait4ms:
    movf    T0_Sample,W
    subwf   TMR0,W
    sublw   T0_COUNTS_PER_TICK
    skpnc
    goto    Wait4ms
    movlw   T0_COUNTS_PER_TICK
    addwf   T0_Sample,F
    return

    END     resetVec

This does run in the MPLABX simulator but I don't use Proteus so that's on you.

Upvotes: 0

Related Questions