My countdown timer starts with 30 minutes (3 for the tens place of minute, and 0 for the units place of minute, and the tens and units place of seconds). I followed this youtube video https://www.youtube.com/watch?v=mIG8N5sbXUY&t=1782s but instead of incrementing the seconds, I decrement. I'm quite new to PIC assembly so I do not know why this does not work while the code in the video does. Below is my code
LIST P=16F84A, F=INHX8M
INCLUDE<P16F84A.INC>
__CONFIG _CP_OFF & _WDT_ON & _XT_OSC
MINUTE_TENS EQU 0x20
MINUTE_UNITS EQU 0x21
SECOND_TENS EQU 0x22
SECOND_UNITS EQU 0x23
COUNT EQU 0x24
ORG 0X00
GOTO START
ORG 0X04
GOTO ISR
LOOKUP ADDWF PCL,F
RETLW 0X00
RETLW 0X01
RETLW 0X02
RETLW 0X03
RETLW 0X04
RETLW 0X05
RETLW 0X06
RETLW 0X07
RETLW 0X08
RETLW 0X09
ISR MOVLW 0x0C
MOVWF TMR0
BCF INTCON,TMR0IF
DECFSZ COUNT,F
RETFIE
MOVLW .122
MOVWF COUNT
DECF SECOND_UNITS,F
MOVF SECOND_UNITS,W
SUBLW 0x00
BTFSS STATUS,C
RETFIE
CLRF SECOND_UNITS
DECF SECOND_TENS,F
MOVF SECOND_TENS,W
SUBLW 0x00
BTFSS STATUS,C
RETFIE
CLRF SECOND_TENS
DECF MINUTE_UNITS,F
MOVF MINUTE_UNITS,W
SUBLW 0x00
BTFSS STATUS,C
RETFIE
CLRF MINUTE_UNITS
DECF MINUTE_TENS,F
MOVF MINUTE_TENS,W
SUBLW 0x00
BTFSS STATUS,C
RETFIE
CLRF MINUTE_TENS
RETFIE
DELAY NOP
RETURN
START BSF STATUS, RP0
CLRF TRISA
MOVLW 0x70
MOVWF TRISB
MOVLW 0x44
MOVWF OPTION_REG
BCF STATUS, RP0
MOVLW 0x0C
MOVWF TMR0
MOVLW .122
MOVWF COUNT
MOVLW 0xA0
MOVWF INTCON ;enable tmr0 interrupt
MOVLW 3 ;start at 30:00
MOVWF MINUTE_TENS
CLRF MINUTE_UNITS
CLRF SECOND_TENS
CLRF SECOND_UNITS
CLRF PORTA
MAIN MOVF MINUTE_TENS,W
CALL LOOKUP
MOVWF PORTB
BSF PORTA,RA0
CALL DELAY ;1 ms
BCF PORTA,RA0
MOVF MINUTE_UNITS,W
CALL LOOKUP
MOVWF PORTB
BSF PORTA,RA1
CALL DELAY ;1 ms
BCF PORTA,RA1
MOVF SECOND_TENS,W
CALL LOOKUP
MOVWF PORTB
BSF PORTA,RA2
CALL DELAY ;1 ms
BCF PORTA,RA2
MOVF SECOND_UNITS,W
CALL LOOKUP
MOVWF PORTB
BSF PORTA,RA3
CALL DELAY ;1 ms
BCF PORTA,RA3
GOTO MAIN
END
The multiplexing of the LEDs work but it does not countdown. How can I make this countdown every second? It seems like my tmr0 isn't working.
CodePudding user response:
The code you posted does not work as you have claimed.
This code does seem to simulate correctly:
MPASM 5.22 MAIN.ASM 3-3-2022 0:58:20 PAGE 1
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
00001 list c=132,n=0 ; Make .LST look nice
00002 list p=16F84A ; Tell assembler the controller we are using
00003 list r=dec ; Use desciaml as default radix for expressions
00004 errorlevel -224 ; Suppress Use of this instruction is not recommended warning
00005 ;
00006 ; File: main.asm
00007 ; Target: PIC16F84A
00008 ; Author: dan1138
00009 ; Date: 2022-MAR-02
00010 ; Compiler: MPASMWIN(v5.22) absolute mode
00011 ; IDE: none
00012 ;
00013 ; Description:
00014 ;
00015 ; Example project for the PIC16F84 controller using the MPASMWIN(v5.22) from the command line.
00016 ;
00017 ;
00018 ; PIC16F84A
00019 ; ----------:_:----------
00020 ; DIGIT_3 <> 1 : RA2 RA1 : 18 <> DIGIT_2
00021 ; DIGIT_4 <> 2 : RA3 RA0 : 17 <> DIGIT_1
00022 ; <> 3 : RA4/T0CKI OSC1 : 16 <- 4MHz crystal
00023 ; ICSP_VPP -> 4 : MCLR OSC2 : 15 -> 4MHz crystal
00024 ; GND -> 5 : GND VDD : 14 <- 5v0
00025 ; LED_SEG_g <> 6 : RB0/INT PGD/RB7 : 13 <> LED_SEG_dp/ICSP_PGD
00026 ; LED_SEG_f <> 7 : RB1 PGC/RB6 : 12 <> LED_SEG_a /ICSP_PGC
00027 ; LED_SEG_e <> 8 : RB2 RB5 : 11 <> LED_SEG_b
00028 ; LED_SEG_d <> 9 : RB3 RB4 : 10 <> LED_SEG_c
00029 ; -----------------------:
00030 ; DIP-18
00031 ;
00032 ;
00033 ; Include target specific definitions for special function registers
00034 ;
00035 #include "p16f84A.inc"
00001 LIST
00002
00003 ;==========================================================================
00004 ; MPASM PIC16F84A processor include
00005 ;
00006 ; (c) Copyright 1999-2013 Microchip Technology, All rights reserved
00007 ;==========================================================================
00008
00208 LIST
00036 ;
00037 ; Set the configuration word
00038 ;
2007 3FF1 00039 __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
00040 ;
00041 ;
00042 ;
00043 ;
00044 ; Declare RAM for application
00045 ;
00046 CBLOCK 0x0C
0000000C 00047 TMR0_Sample :1 ; Sample of TIMER0 use for system tick
0000000D 00048 TicksInOneSec :1 ; Count Ticks in one second
0000000E 00049 Seconds :2 ; Seconds: units, tens
00000010 00050 Minutes :2 ; Minutes: units, tens
00000012 00051 LED_Segments :4 ; Segment refresh buffer
00000016 00052 LED_DigitOn :1 ; Mask of which one digit is on
00053 ENDC
00054
00055
00056 ;
00057 ; Define how much real time is in a system tick.
00058 ; This application uses a system tick of 4 milliseconds.
00059 ;
00060 ; This is:
00061 ; FOSC / 4 / TMR0_prescale = (TIMER0 clock frequency)
00062 ; 4000000/4/32 = 31250 Hz
00063 ;
00064 ; (TIMER0 clock frequency) / TMR0_8_MS = System tick frequency
00065 ; 31250/125 = 250 Hz
00066 ;
00067 ; 250 Hz has a period of 0.004 seconds.
00068 ;
00069 #define TMR0_4_MS d'125' ; TIMER0 counts in 4 milliseconds
00070 #define TICKS_PER_SECOND d'250' ; System ticks in one second
00071 ;
00072 ; ==============================================================
00073 ; Power on reset
00074 ;
0000 00075 org 0x0000
0000 00076 Start:
0000 2854 00077 goto main
0001 00078 LookupSegments:
0001 018A 00079 clrf PCLATH
0002 390F 00080 andlw h'0F'
0003 0782 00081 addwf PCL,F
00082 ; abcdefg _
0004 347E 00083 dt b'01111110' ; | |
00084 ; |_|
00085 ;
0005 3430 00086 dt b'00110000' ; |
00087 ; |
00088 ; _
0006 346D 00089 dt b'01101101' ; _|
00090 ; |_
00091 ; _
0007 3479 00092 dt b'01111001' ; _|
00093 ; _|
00094 ;
0008 3433 00095 dt b'00110011' ; |_|
00096 ; |
00097 ; _
0009 345B 00098 dt b'01011011' ; |_
00099 ; _|
00100 ; _
000A 345F 00101 dt b'01011111' ; |_
00102 ; |_|
00103 ; _
000B 3470 00104 dt b'01110000' ; |
00105 ; |
00106 ; _
000C 347F 00107 dt b'01111111' ; |_|
00108 ; |_|
00109 ; _
000D 3473 00110 dt b'01110011' ; |_|
00111 ; |
00112 ; _
000E 3477 00113 dt b'01110111' ; |_|
00114 ; | |
00115 ;
000F 341F 00116 dt b'00011111' ; |_
00117 ; |_|
00118 ; _
0010 344E 00119 dt b'01001110' ; |
00120 ; |_
00121 ;
0011 343D 00122 dt b'00111101' ; _|
00123 ; |_|
00124 ; _
0012 344F 00125 dt b'01001111' ; |_
00126 ; |_
00127 ; _
0013 3447 00128 dt b'01000111' ; |_
00129 ; |
00130 ;
00131 ; ==============================================================
00132 ; The LED task is called every system tick (4 milliseconds)
00133 ;
00134 ; It refreshes one of the four LED digits from the segment buffer.
00135 ;
0014 00136 LED_Task:
0014 0816 00137 movf LED_DigitOn,W
0015 0716 00138 addwf LED_DigitOn,W
0016 390F 00139 andlw h'0F'
0017 1903 00140 skpnz
0018 3801 00141 iorlw 1
0019 0096 00142 movwf LED_DigitOn
001A 1816 00143 btfsc LED_DigitOn,0
001B 0812 00144 movf LED_Segments 0,W
001C 1896 00145 btfsc LED_DigitOn,1
001D 0813 00146 movf LED_Segments 1,W
001E 1996 00147 btfsc LED_DigitOn,3
001F 0814 00148 movf LED_Segments 2,W
0020 1996 00149 btfsc LED_DigitOn,3
0021 0815 00150 movf LED_Segments 3,W
0022 0185 00151 clrf PORTA
0023 0086 00152 movwf PORTB
0024 0816 00153 movf LED_DigitOn,W
0025 0085 00154 movwf PORTA
0026 0008 00155 return
00156 ;
00157 ; ==============================================================
00158 ; The Count Down task is called every system tick (4 milliseconds)
00159 ;
00160 ; This task count system ticks until one second has elapsed (250 counts)
00161 ; Decrements the 30 minute time to zero
00162 ; Converts the minutes and seconds to segments
00163 ; Updates the segment buffer
00164 ;
0027 00165 CountDown_Task:
0027 0B8D 00166 decfsz TicksInOneSec,F
0028 0008 00167 return
0029 30FA 00168 movlw TICKS_PER_SECOND
002A 008D 00169 movwf TicksInOneSec
00170
002B 038E 00171 decf Seconds,F
002C 1E0E 00172 btfss Seconds,4
002D 283F 00173 goto UpdateSegments
002E 3009 00174 movlw d'9'
002F 008E 00175 movwf Seconds
00176
0030 038F 00177 decf Seconds 1,F
0031 1E0F 00178 btfss Seconds 1,4
0032 283F 00179 goto UpdateSegments
0033 3005 00180 movlw d'5'
0034 008F 00181 movwf Seconds 1
00182
0035 0390 00183 decf Minutes,F
0036 1E10 00184 btfss Minutes,4
0037 283F 00185 goto UpdateSegments
0038 3009 00186 movlw d'9'
0039 0090 00187 movwf Minutes
00188
003A 0391 00189 decf Minutes 1,F
003B 1E11 00190 btfss Minutes 1,4
003C 283F 00191 goto UpdateSegments
003D 3003 00192 movlw d'3'
003E 0091 00193 movwf Minutes 1
00194
003F 00195 UpdateSegments:
003F 0811 00196 movf Minutes 1,W
0040 2001 00197 call LookupSegments
0041 0612 00198 xorwf LED_Segments 0,W
0042 397F 00199 andlw h'7F'
0043 0692 00200 xorwf LED_Segments 0,F
0044 0810 00201 movf Minutes 0,W
0045 2001 00202 call LookupSegments
0046 0613 00203 xorwf LED_Segments 1,W
0047 397F 00204 andlw h'7F'
0048 0693 00205 xorwf LED_Segments 1,F
0049 080F 00206 movf Seconds 1,W
004A 2001 00207 call LookupSegments
004B 0614 00208 xorwf LED_Segments 2,W
004C 397F 00209 andlw h'7F'
004D 0694 00210 xorwf LED_Segments 2,F
004E 080E 00211 movf Seconds 0,W
004F 2001 00212 call LookupSegments
0050 0615 00213 xorwf LED_Segments 3,W
0051 397F 00214 andlw h'7F'
0052 0695 00215 xorwf LED_Segments 3,F
0053 0008 00216 return
00217 ;
00218 ; ==============================================================
00219 ; Main application starts here
00220 ;
0054 00221 main:
0054 30D5 00222 movlw b'11010101' ; Select TIMER0 clock source as FOSC/4, prescale TMR0 a 1:64
0055 0062 00223 option
00224 ;
00225 ; Wait for about 800 milliseconds before making PGC/PGD outputs.
00226 ;
00227 ; This will give the In-Circuit-Serial-Programmer a chance
00228 ; to connect to the PIC16F84A
00229 ;
0056 3032 00230 movlw d'50'
0057 008C 00231 movwf TMR0_Sample
0058 0181 00232 clrf TMR0
0059 018B 00233 clrf INTCON
005A 00234 POR_Wait:
005A 1D0B 00235 btfss INTCON,TMR0IF
005B 285A 00236 goto POR_Wait
005C 110B 00237 bcf INTCON,TMR0IF
005D 0B8C 00238 decfsz TMR0_Sample,F
005E 285A 00239 goto POR_Wait
00240
005F 30D4 00241 movlw b'11010100' ; Select TIMER0 clock source as FOSC/4, prescale TMR0 at 1:32
0060 0062 00242 option
0061 30F0 00243 movlw b'11110000' ; RA3,RA2,RA1,RA0 as outputs
0062 0065 00244 tris PORTA
0063 3000 00245 movlw b'00000000' ; All PORTB as outputs
0064 0066 00246 tris PORTB
00247 ;
00248 ; Initialize application states
00249 ;
0065 0181 00250 clrf TMR0
0066 018C 00251 clrf TMR0_Sample
0067 30FA 00252 movlw TICKS_PER_SECOND
0068 008D 00253 movwf TicksInOneSec
0069 0196 00254 clrf LED_DigitOn
006A 0192 00255 clrf LED_Segments 0
006B 0193 00256 clrf LED_Segments 1
006C 0194 00257 clrf LED_Segments 2
006D 0195 00258 clrf LED_Segments 3
006E 018E 00259 clrf Seconds 0 ; Seconds units
006F 018F 00260 clrf Seconds 1 ; Seconds tens
0070 0190 00261 clrf Minutes 0 ; Minutes units
0071 3003 00262 movlw d'3'
0072 0091 00263 movwf Minutes 1 ; Minutes tens
0073 203F 00264 call UpdateSegments
00265 ;
00266 ; ==============================================================
00267 ; Application loop
00268 ;
00269 ; The application does this:
00270 ; Creates the system tick
00271 ; Counts timer down from 30 minutes
00272 ; Updates the LED digits
00273 ;
0074 00274 AppLoop:
00275 ;
00276 ; Loop to wait for system tick
0074 00277 WaitForSystemTick:
0074 080C 00278 movf TMR0_Sample,W ; Get previous TIMER0 count state
0075 0201 00279 subwf TMR0,W ; Difference of current minus previous sample
0076 3C7D 00280 sublw TMR0_4_MS
0077 1C03 00281 btfss STATUS,C ; Skip if period longer than 0.8 milliseconds
0078 2874 00282 goto WaitForSystemTick
0079 307D 00283 movlw TMR0_4_MS
007A 078C 00284 addwf TMR0_Sample,F ; Update tick period count
007B 00285 SystemTickTime:
00286 ;
00287 ; Do LED task
007B 2014 00288 call LED_Task
00289 ;
00290 ; Do Count down task
007C 2027 00291 call CountDown_Task
007D 2874 00292 goto AppLoop
00293
00294 end