;
; File: main.S
; Target: PIC16F627A
; Author: dan1138
; Date: 2024-05-14
; Compiler: pic-as(v2.40)
; IDE: MPLABX v6.00
;
; Description:
;
; Answer for homework see: https://www.electro-tech-online.com/threads/pic16f627a-project.166131/
;
; PIC16F627A
; +----------:_:----------+
; <> 1 : RA2 RA1 : 18 <> SW2
; <> 2 : RA3 RA0 : 17 <> SW1
; <> 3 : RA4(*) OSC1/RA7 : 16 <>
; VPP -> 4 : RA5/MCLRn OSC2/RA6 : 15 <>
; GND -> 5 : VSS VDD : 14 <- 5v0
; LED_a <> 6 : RB0 PGD/RB7 : 13 <> /PGD
; LED_b <> 7 : RB1/RX/DT PGC/RB6 : 12 <> LED_g /PGC
; LED_c <> 8 : RB2/RX/CK RB5 : 11 <> LED_f
; LED_d <- 9 : RB3/CCP1 PGM/RB4 : 10 <> LED_e
; +-----------------------:
; DIP-18
; Notes:
; (*) RA4 is an open drain output. Requires an external pull-up for output.
;
;
; Add this line in the project properties box, pic-as Global Options -> Additional options:
; -Wa,-a -Wl,-pPor_Vec=0h,-pIsr_Vec=4h
;
PROCESSOR 16F627A
PAGEWIDTH 132
RADIX DEC
;
; Define the system oscillator frequency this code will setup
;
#define _XTAL_FREQ 4000000
;
; PIC16F627A Configuration Bit Settings
;
CONFIG FOSC = INTOSCIO ; Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
CONFIG WDTE = OFF ; Watchdog Timer Enable bit (WDT disabled)
CONFIG PWRTE = OFF ; Power-up Timer Enable bit (PWRT disabled)
CONFIG MCLRE = ON ; RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
CONFIG BOREN = OFF ; Brown-out Detect Enable bit (BOD disabled)
CONFIG LVP = OFF ; Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
CONFIG CPD = OFF ; Data EE Memory Code Protection bit (Data memory code protection off)
CONFIG CP = OFF ; Flash Program Memory Code Protection bit (Code protection off)
#include <xc.inc>
;
; Power-On-Reset entry point
;
PSECT Por_Vec,global,class=CODE,delta=2
global resetVec
resetVec:
goto main
;
; Interrupt vector and handler
PSECT Isr_Vec,global,class=CODE,delta=2
retfie ; Return from interrupt
;
; Application
;
psect MainData,global,class=RAM,space=1,delta=1,noexec
global SW_Sample,SW_Stable,SW_Change,SW_Bounce
global DigitCount
#define SW_BOUNCE_TIME 5
SW_Sample: ds 1
SW_Stable: ds 1
SW_Change: ds 1
SW_Bounce: ds 1
#define MAX_DIGIT_COUNT 9
#define MIN_DIGIT_COUNT 0
DigitCount: ds 1
;
; Data common to all banks
psect TMR0data,global,class=COMMON,space=1,delta=1,noexec
global T0_Tick,delay_1s_count
; Define how many TIMER0 counts in one 250Hz period
; (Forc/4/TMR0_prescale/250Hz)
#define T0_250HZ (_XTAL_FREQ/4/32/250)
T0_Tick: ds 1
delay_1s_count: ds 1
PSECT MainCode,global,class=CODE,delta=2
main:
clrf INTCON
movlw 0x07
movwf CMCON
banksel SW_Sample
clrf SW_Sample
clrf SW_Stable
movlw SW_BOUNCE_TIME
movwf SW_Bounce
clrf DigitCount
banksel OPTION_REG
movlw 0xD4 ; TIMER0 clock source is Fosc/4, prescale 1:32
movwf OPTION_REG
bsf TRISA,TRISA_TRISA0_POSITION
bsf TRISA,TRISA_TRISA1_POSITION
clrf TRISB
banksel PORTB
clrf PORTB
clrf T0_Tick
;
; Process loop
;
AppLoop:
call SW_Poll
iorlw 0
btfsc STATUS,STATUS_Z_POSITION
goto AppLoop
;
; Decide what to do when switches change state
movf SW_Stable,W
andlw 0x03
btfsc STATUS,STATUS_Z_POSITION
goto AppLoop ; Both switches open
xorlw 0x03
btfsc STATUS,STATUS_Z_POSITION
goto AppLoop ; Both switches closed
clrw ;
SW_check_SW1:
btfss SW_Change,0
goto SW1_no_change
bcf SW_Change,0
btfsc SW_Stable,0
call SW1_Action ; SW1 closed
SW1_no_change:
btfss SW_Change,1
goto SW2_no_change
bcf SW_Change,1
btfsc SW_Stable,1
call SW2_Action ; SW2 closed
SW2_no_change:
;
; WREG is zero when not button action occurs
SW_ActionRepeat:
iorlw 0
btfsc STATUS,STATUS_Z_POSITION ; Skip if burron action occurred
goto AppLoop
;
; Display count
call LookUpSegments
banksel PORTB
movwf PORTB
call delay_1s
;
; Check if a button changed during wait
banksel SW_Change
movf SW_Change,W
btfss STATUS,STATUS_Z_POSITION
goto AppLoop ; button changed stop action
;
; Repeate action if button pressed
clrw ;
btfsc SW_Stable,0
call SW1_Action
btfsc SW_Stable,1
call SW2_Action
goto SW_ActionRepeat
;
SW1_Action:
movf DigitCount,W
xorlw MAX_DIGIT_COUNT
movlw MIN_DIGIT_COUNT
btfss STATUS,STATUS_Z_POSITION
incf DigitCount,W
movwf DigitCount
retlw 1
;
SW2_Action:
movf DigitCount,W
xorlw MIN_DIGIT_COUNT
movlw MAX_DIGIT_COUNT
btfss STATUS,STATUS_Z_POSITION
decf DigitCount,W
movwf DigitCount
retlw 1
;
; Poll buttons
; Returns: WREG = 0, no change
; WREG = 1, button changed
SW_Poll:
banksel TMR0 ; Poll TIMER0 to wait for 4 milliseconds to elapse
movf T0_Tick,W
subwf TMR0,W
addlw -T0_250HZ
btfss STATUS,STATUS_C_POSITION
goto SW_Poll
movlw T0_250HZ
addwf T0_Tick,F
;
; Sample switch inputs
banksel PORTA
clrw
btfsc PORTA,0 ; skip if SW1 open
iorlw 0b00000001 ; Show SW1 pressed
btfsc PORTA,1 ; skip if SW2 open
iorlw 0b00000010 ; Show SW2 pressed
banksel SW_Sample
xorwf SW_Sample,W
andlw 0x03
btfss STATUS,STATUS_Z_POSITION
goto SW_Bouncing
decfsz SW_Bounce,F
goto SW_Bounce_Done
SW_Bouncing:
xorwf SW_Sample,F
movlw SW_BOUNCE_TIME
movwf SW_Bounce
retlw 0
SW_Bounce_Done:
movf SW_Sample,W
xorwf SW_Stable,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0
iorwf SW_Change,F
xorwf SW_Stable,F
retlw 1
;
;
delay_1s:
movlw 250 ; number of 250Hz cycles in one second
movwf delay_1s_count
delay_1s_Loop:
call SW_Poll
decfsz delay_1s_count,F
goto delay_1s_Loop
return
;
; The student must fix this function
; to return the correct bits to light
; the 7-segment display correctly
;
LookUpSegments:
banksel DigitCount
movlw 0
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00000001 ; seven-segments for 0
movlw 1
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00000010 ; seven-segments for 1
movlw 2
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00000010 ; seven-segments for 2
movlw 3
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00000100 ; seven-segments for 3
movlw 4
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00001000 ; seven-segments for 4
movlw 5
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b00100000 ; seven-segments for 5
movlw 6
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b01000000 ; seven-segments for 6
movlw 7
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b10000000 ; seven-segments for 7
movlw 8
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b10000001 ; seven-segments for 8
movlw 9
xorwf DigitCount,W
btfsc STATUS,STATUS_Z_POSITION
retlw 0b10000010 ; seven-segments for 9
retlw 0
;
END resetVec