Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
;-- Define the title, device and any files that need to be includedFor a start post your code, but for a clue you can use a data table to correct the pin connections for the seven segments.
;-----------------------------------------------------------------------------
;
; Segment patterns
;
;-----------------------------------------------------------------------------
; These values are for common anode displays
ORG 0x100 ;To avoid crossing a boundry in this table.
HEX2SEGMENTS
; Note enter this subroutine with the value to be converted to the segment bit pattern in the "W" register
;on exiting the subroutine "W" contains the bit pattern to be sent to the 7 segments.
CLRF PCLATH
INCF PCLATH, F ;Set PCLATH to 0x01 to point to this page
ANDLW b'00001111' ;Use only lower nibble
ADDWF PCL,F ;Add offset to current PC
; *** These bit patterns could be changed to assign segments to different I/O pins to make board layout easier ***
;These bit patterns are for the following segment to bit assignments
; A RB0
; B RB1
; C RB2
; D RB4
; E RB5
; F RB6
; G RB7
SEGMENTS
RETLW b'10000000' ;0 NOTE low to illuminate segment
RETLW b'11110001' ;1
RETLW b'01000100' ;2
RETLW b'01100000' ;3
RETLW b'00110001' ;4
RETLW b'00100010' ;5
RETLW b'00000010' ;6
RETLW b'11110000' ;7
RETLW b'00000000' ;8
RETLW b'00100000' ;9
RETLW b'00010000' ;A
RETLW b'00000011' ;B
RETLW b'10000110' ;C
RETLW b'01000001' ;D
RETLW b'00000110' ;E
RETLW b'00010110' ;F
; -----------------------------------
;
; 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