a task with pic16f628 timer 0 . question

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
hi to every1 !!
i hav a task : make a program on assembler , simulating traffic lights in two directions , with two versions: 1) with software's control timer using TMR0 ; 2) with interrupt of TMR0 .
the first part of this task is totally completed ( except circuit of algorithm ) and no problem with this , so every switching of lights is controlled fully by timer 0 . okay . but now i am stuck by hours with second part . since it is a quite stupid idea to to force a chip to count digits with counters with BTFSS/BTFSC in macro ( due to power consumption 4 example ) , is there any way to use the first part of task to perform the second part of task ? maybe any other way ?
interrupt should be whatever me wish , 4 example "by appearing of 0 on PORTA,4 ( by switching ON SA4 ) , start interrupt and make yellow colour blinks for some time then go back to main loop "
i have tried and its ( maybe ) impossible cause tmr0 controls the changes of lights in the same time ! !
please , any opinions or ideas are welcomed !



Code:
    list p=16f628
    #include <p16f628.inc>
    __config _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
    cblock    0x22
counter_1
counter_2
    endc
;================== beginprogram ==================
    org 0x00
    clrf PORTB
    bcf STATUS,RP1
    bsf STATUS,RP0
    movlw b'11000000'
    movwf TRISB
    bcf STATUS,RP0
    banksel OPTION_REG
    movlw b'11010111'
    movwf OPTION_REG       ;prescaler — 1:256
    banksel TMR0
    movlw .0
    movwf TMR0             ;unset tmr

main_loop
    bsf PORTB,4
    bsf PORTB,1
    bcf PORTB,2
    bcf PORTB,3
    bcf PORTB,0
    movlw .92
    movwf counter_1
loop_1
    call delay
    decfsz counter_1,f
    goto loop_1
    movlw .4
    movwf counter_2
loop_2
    bcf PORTB,4
    movlw .8
    movwf counter_1
loop_3
    call delay
    decfsz counter_1,f
    goto loop_3
    bsf PORTB,4
    movlw .8
    movwf counter_1
loop_4
    call delay
    decfsz counter_1,f
    goto loop_4
    decfsz counter_2,f
    goto loop_2
    bsf PORTB,2
    bsf PORTB,3
    bcf PORTB,4
    movlw .31
    movwf counter_1
loop_5
    call delay
    decfsz counter_1,f
    goto loop_5
    bsf PORTB,0
    bsf PORTB,5
    bcf PORTB,2
    bcf PORTB,3
    bcf PORTB,1
    movlw .92
    movwf counter_1
loop_6
    call delay
    decfsz counter_1,f
    goto loop_6
    movlw .4
    movwf counter_2
loop_7
    bcf PORTB,5
    movlw .8
    movwf counter_1
loop_8
    call delay
    decfsz counter_1,f
    goto loop_8
    bsf PORTB,5
    movlw .8
    movwf counter_1
loop_9
    call delay
    decfsz counter_1,f
    goto loop_9
    decfsz counter_2,f
    goto loop_7
    bsf PORTB,2
    bsf PORTB,3
    bcf PORTB,5
    movlw .31
    movwf counter_1
loop_10
    call delay
    decfsz counter_1,f
    goto loop_10
    goto main_loop
;********* subroutine *********
delay
    btfss INTCON,T0IF
    goto delay
    bcf INTCON,T0IF
    banksel TMR0
    movlw .0
    movwf TMR0
    return
;********* subroutineend *********
    end
;================== end ==================
 

GopherT

Joined Nov 23, 2012
8,012
Start by adding a ; to the right of each instruction (or block of instructions) and place a comment - lots of comments, so we know what you intended to do.

also, if you read the datasheet - you will realize there are two more timers on that chip. An 8-bit and a 16 bit timer in addition to Timer0.
 

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
Start by adding a ; to the right of each instruction (or block of instructions) and place a comment - lots of comments, so we know what you intended to do.

also, if you read the datasheet - you will realize there are two more timers on that chip. An 8-bit and a 16 bit timer in addition to Timer0.
thx for fast answer ! yes i have seen but they need external oscillators afaik , and the task is about tmr0 only . the main circuit in first post doesnt has any external oscs

Code:
list p=16f628          ;list of options
    #include <p16f628.inc> ; connect an additional output file
    __config _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
                           ; set configuration bits microcontroller
    cblock    0x22           ; determination unit constants
counter_1
counter_2
    endc
;================== begin of programm ==================
;********* needed settings *********
    org 0x00               ;make start address 0
    clrf PORTB             ;initialization of PORTB
    bcf STATUS,RP1
    bsf STATUS,RP0         ;choose bank 1
    movlw b'11000000'
    movwf TRISB            ;RB<5:0> now working as OUTPUT
    bcf STATUS,RP0         ;go back to bank 0
    banksel OPTION_REG     ;choose bank of register
    movlw b'11010111'
    movwf OPTION_REG       ;options for timer; prescaler — 1:256
    banksel TMR0           ;choose bank of register
    movlw .0
    movwf TMR0             ;unset timer
;********* needed setting completed *********
main_loop                  ;this is the main loop
    bsf PORTB,4 ;turn ON green led of one lighter
    bsf PORTB,1 ;also turn ON red led of another lighter
    bcf PORTB,2 ;turn OFF all yellow leds
    bcf PORTB,3
    bcf PORTB,0 ;and turn OFF red led of one lighter (watch the table)
    movlw .92 ;send digit 92 for counter1, to count 0,065ms*92=6 sec approximately
    movwf counter_1
loop_1
    call delay ; goto subroutine
    decfsz counter_1,f ;decrement counter1 (“skip if 0”)
    goto loop_1 ;if counter_1 >0 then go to loop 1
    movlw .4 ;if counter 1=0 then make 4 cycles, totally 8 yellow blinks, every for 8*0,065ms=0,5 sec approximately
    movwf counter_2
loop_2
...
...
...
...
etc
...
...
loop_10
    call delay ;call subroutine
    decfsz counter_1,f ;decrement counter_1 and skip next instruction if it 0
    goto loop_10
    goto main_loop         ;go to the begin of programm
;********* subroutine*********
delay
    btfss INTCON,T0IF ;check T0IF and skip next instruction if it 1
    goto delay ;t0if=0 - go here
    bcf INTCON,T0IF ;t0if=1 - go here
    banksel TMR0 ;choose bank of register
    movlw .0 ;send a constant (unset tmr)
    movwf TMR0
    return ;return back
;********* end of subroutine*********
    end
;================== end of programm ==================
i think the table of " switchings " could help to understand completed first part of the task . i have no problem with it , it compiles without any single error and were checked in real pic

below is the table of switching . programm starts with action 1, then goes to 2,3,4,5,6 etc till 20, then goes back to 1 to repeat the cycle . if table not helps to understand what is going on , i will create circuit of algorithm later



sorry for broken English
 

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
Why do you need 8 sequences of leds, just use the four sequence repeated.
no sir . i must have eight sequences because i have two traffic lights for two perpendicular roads :) it's all ok with my first type of programm

well . i had re-read datasheet again further and now i think the best idea is to use TMR1 with an internal clock signal ( since we can use (???) programm connection to internal oscillator too , not only external as i thought ) . o_O really there no any other way , to make everything with only one timer as i wished . o_O so , the only thing in my mind now is to put and additional "BTFSS/BTFSC" with "BCF TMRC1S,4" etc , in delay subroutine , which redirects chip for work with other timer :(
 

JohnInTX

Joined Jun 26, 2012
3,919
This is a classic example of a state-machine. Look at your table. Each entry is a self-contained condition, the state of the system. Each line is a different 'state' and the system can only be in one state at a time.
So.. a way to approach this is to first identify each state that the system can be in. According to your table, the system can be in 1 of 8 states. Code each state like it is a separate little program. Do this by coding 8 different functions (sub-routines), one for each state.

So now you have 8 different functions. If you called one, it would output the light pattern that you want for that particular state i.e. RED on Main Street, GREEN on the cross street. The next state might be RED on Main Street, YELLOW on the cross street. Then GREEN on Main Street, RED on the cross street.

That's 3 of the 8 states. The others are similar and describe unique conditions. When you are done, you have 8 subroutines/functions that, when called, set up the lights that define the system's current state.

Once you have all 8 states coded and working, its time to schedule them by calling them in sequence. Column 2 of your table tells you how to do that:
call function1;
delay (for the time in line1, column 2)
call function2;
delay(...);
call function3;
delay(...);
... etc...
when you get to the end, loop to the starting state.

To start, I would just use dumb delays. The scheduling will be just the code-flow. There are ways of implementing state machines that are better but I'd do a brute-force approach first. Later, you can add a better scheduler and if you write the light output routines as the self-contained sub-routines as I describe, a better scheduler can use them as is.

Have fun.
 

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
This is a classic example of a state-machine. Look at your table. Each entry is a self-contained condition, the state of the system. Each line is a different 'state' and the system can only be in one state at a time.
So.. a way to approach this is to first identify each state that the system can be in. According to your table, the system can be in 1 of 8 states. Code each state like it is a separate little program. Do this by coding 8 different functions (sub-routines), one for each state.

So now you have 8 different functions. If you called one, it would output the light pattern that you want for that particular state i.e. RED on Main Street, GREEN on the cross street. The next state might be RED on Main Street, YELLOW on the cross street. Then GREEN on Main Street, RED on the cross street.

That's 3 of the 8 states. The others are similar and describe unique conditions. When you are done, you have 8 subroutines/functions that, when called, set up the lights that define the system's current state.

Once you have all 8 states coded and working, its time to schedule them by calling them in sequence. Column 2 of your table tells you how to do that:
call function1;
delay (for the time in line1, column 2)
call function2;
delay(...);
call function3;
delay(...);
... etc...
when you get to the end, loop to the starting state.

To start, I would just use dumb delays. The scheduling will be just the code-flow. There are ways of implementing state machines that are better but I'd do a brute-force approach first. Later, you can add a better scheduler and if you write the light output routines as the self-contained sub-routines as I describe, a better scheduler can use them as is.

Have fun.
thank you , great idea . :) it just makes programm looks neat . i see no difference in functional aspect , but your idea of " how to make program " is a way better to understand if it is being demonstrating to audience :eek:

recently i have successfully received the highest mark for my homework ! thank to all for opinions and attention ! :) :) :)

finally , ive used both timer 0 and timer 1 . after simulation in mplab ive have used proteus simulation , and then checked everything in the real pic . below is my code ( maybe itll be useful for some1 ) . comments are deleted . and proteus file i cant attach in forum due to " The uploaded file does not have an allowed extension. "

Code:
    list p=16f628
    #include <p16f628.inc>
    __config _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
    cblock    0x22  
counter_1     
counter_2                
d1                         
d2                             
d3                             
    endc            
;================== begin of program ==================
    org 0x00                  
    goto start_loop            
    org 0x04                  
    goto interrupt             
start_loop                     
;********* list of macroses used *********
delay500us    macro            
    movlw D'5'                    
    movwf d3                    
    movlw D'5'                    
    movwf d2                    
    movlw D'5'                    
    movwf d1                    
    decfsz d1                    
    goto $-1                   
    decfsz d2                    
    goto $-5                    
    decfsz d3                    
    goto $-9                    
    endm                        
;********* end of list of macroses *********
;********* needed options *********
    banksel INTCON              
    clrf INTCON                  
    banksel PORTA              
    clrf PORTA              
    movlw 0x07                
    movwf CMCON               
    banksel TRISA             
    movlw b'00010000'          
    movwf TRISA                
    banksel PORTB             
    clrf PORTB                   
    banksel TRISB            
    movlw b'11000000'           
    movwf TRISB                 
    banksel OPTION_REG        
    movlw b'11010111'           
    movwf OPTION_REG         
    banksel TMR0            
    movlw .0                 
    movwf TMR0                  
;********* needed options are done *********
main_loop                   
    bsf PORTB,4                    
    bsf PORTB,1                    
    bcf PORTB,2                    
    bcf PORTB,3                    
    bcf PORTB,0                    
    movlw .92                    
    movwf counter_1                
loop_1                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_1                 
    movlw .4                
    movwf counter_2                
loop_2                            
    bcf PORTB,4                    
    movlw .8                    
    movwf counter_1                
loop_3                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_3                    
    bsf PORTB,4                    
    movlw .8                    
    movwf counter_1                
loop_4                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_4                    
    decfsz counter_2,f            
    goto loop_2                  
    bsf PORTB,2                    
    bsf PORTB,3                    
    bcf PORTB,4                    
    movlw .31                    
    movwf counter_1                
loop_5                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_5                   
    bsf PORTB,0                    
    bsf PORTB,5                    
    bcf PORTB,2                    
    bcf PORTB,3                    
    bcf PORTB,1                    
    movlw .92                    
    movwf counter_1                
loop_6                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_6                  
    movlw .4               
    movwf counter_2                
loop_7                            
    bcf PORTB,5                    
    movlw .8                    
    movwf counter_1                
loop_8                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_8                   
    bsf PORTB,5                    
    movlw .8                    
    movwf counter_1                
loop_9                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_9                    
    decfsz counter_2,f            
    goto loop_7                   
    bsf PORTB,2                    
    bsf PORTB,3                    
    bcf PORTB,5                    
    movlw .31                    
    movwf counter_1                
loop_10                            
    call delay_1                
    decfsz counter_1,f            
    goto loop_10               
    goto main_loop             
;********* sub-routinnes *********
delay_1                           
    btfss PORTA,4             
    call timer_1             
    btfss INTCON,T0IF          
    goto delay_1               
    bcf INTCON,T0IF              
    banksel TMR0              
    movlw .0               
    movwf TMR0                  
    return                      
delay_2                          
    btfss INTCON,T0IF          
    goto delay_2             
    bcf INTCON,T0IF              
    banksel TMR0           
    movlw .0                   
    movwf TMR0                 
    return                        
timer_1                        
    banksel PORTA             
    bsf INTCON,GIE               
    bsf INTCON,PEIE           
    banksel PIE1             
    bsf PIE1,TMR1IE             
    banksel T1CON              
    bsf T1CON,0                 
    bcf T1CON,1                   
    movlw b'11111110'          
    movwf TMR1H                
    movwf TMR1L                  
    delay500us               
    nop                            
    goto main_loop              
;********* sub-routinne of interrupt *********
interrupt                        
    bcf INTCON,GIE          
    banksel T1CON              
    bcf T1CON,0                  
    bcf PIR1,TMR1IF       
    bcf PORTB,0                  
    bcf PORTB,1               
    bcf PORTB,4                   
    bcf PORTB,5                    
    movlw .8                   
    movwf counter_2                
loop_11                            
    bsf PORTB,2                    
    bsf PORTB,3                    
    movlw .8                    
    movwf counter_1                
loop_12                            
    call delay_2                
    decfsz counter_1,f            
    goto loop_12                
    bcf PORTB,2                    
    bcf PORTB,3                    
    movlw .8                    
    movwf counter_1                
loop_13                            
    call delay_2                
    decfsz counter_1,f            
    goto loop_13                
    decfsz counter_2,f            
    goto loop_11              
    retfie                   
;********* end of sub-routinne of interrupt *********
;********* end of sub-routinnes *********
    end                            ;
;================== end of programm ==================
/solved o_O
 

JohnInTX

Joined Jun 26, 2012
3,919
recently i have successfully received the highest mark for my homework ! thank to all for opinions and attention ! :) :) :)
Nothing succeeds like success. Well done and congratulations on your high marks!

If you would like to take the next step and explore ways to make it even better, let us know.
 

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
If you would like to take the next step and explore ways to make it even better, let us know.
yes , sure ! i am interested in this ! ! please tell me :)

as i suppose now , we can succesfully complete the task with traffic light by 2 ways: 1) linear algorythm ( like i have done it before , see top picture in pdf-file ) - simple way ; 2) parallel algorythm with modification of " status word " , which choosing which way (route ) the programm will go next time ( see bottom picture in pdf-file ). this way was recommended by my lecturer as alternative , but i have rejected this idea it cause we really havent examined how to do it properly .

if its possible , then how to improve algorythm further ?

Mod note: Reduced file size
 

Attachments

Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
3,919
I like what your lecturer has provided in the second page, it is the basis of a finite state machine. The 'status word' is the state indicator. I use them all the time for things like this and PICs are particularly good at them. So... where to start?

First, a little clean up:
Instead of explicitly calling out IO in the code flow, do it in subroutines with useful names. Your lights can only have one meaning at a time so have one subroutine per meaning i.e. MainStreetGREEN_CrossStreetRED. The same with any inputs. Rather than asking is PORTA,2 low, ask has the button been pressed? The general rule is to keep your main code as minimal as possible. The code snippet below shows how I would collect the IO initialization and unique light patterns into their own routines. Personally, I put all IO into its own file and INCLUDE "IO.inc". If you look at the resulting code, its easier to read and see what's going on. This idea of separating the program's logic flow from the peripheral actions is important when you get into more complex things, have to relocate pins or - as we shall see - find out that the IO doesn't always behave like it should.

Code:
; Breaking out the IO. First, collect all IO - including the initialization - into
; one place (I would recommend a second file called IO.inc)
;************** INIT IO  ********************
; Set up all IO for the system
initIO:
    banksel PORTA            
    clrf PORTA            
    movlw 0x07              
    movwf CMCON            
    banksel TRISA          
    movlw b'00010000'        
    movwf TRISA              
    banksel PORTB          
    clrf PORTB                
    banksel TRISB          
    movlw b'11000000'        
    movwf TRISB
    return

; Each light pattern gets its own subroutine
;*******************************
MainStreetGREEN_CrossStreetRED:
    bsf PORTB,0                  
    bsf PORTB,5                  
    bcf PORTB,2                  
    bcf PORTB,3                  
    bcf PORTB,1
    return


;-------------------------
; Now in main, THIS:
;***********************************

    banksel PORTA            
    clrf PORTA            
    movlw 0x07              
    movwf CMCON            
    banksel TRISA          
    movlw b'00010000'        
    movwf TRISA              
    banksel PORTB          
    clrf PORTB                
    banksel TRISB          
    movlw b'11000000'        
    movwf TRISB

    banksel OPTION_REG      
    movlw b'11010111'        
    movwf OPTION_REG      
    banksel TMR0          
    movlw .0              
    movwf TMR0


;becomes THIS:
    call initIO        ; init system IO

    banksel OPTION_REG      
    movlw b'11010111'        
    movwf OPTION_REG      
    banksel TMR0          
    movlw .0              
    movwf TMR0


; and THIS:
;**********************************
loop_5                          
    call delay_1              
    decfsz counter_1,f          
    goto loop_5                
    bsf PORTB,0                  
    bsf PORTB,5                  
    bcf PORTB,2                  
    bcf PORTB,3                  
    bcf PORTB,1

; becomes THIS
loop_5:
    call delay_1              
    decfsz counter_1,f          
    goto loop_5

    call MainStreetGREEN_CrossStreetRED
  ...
Things like timer inits should be broken out as well - we'll get to that directly.

Once we can easily deal with the IO, its time to think about delays. You are using dumb delays that eat up all of the system's resources. Before getting into the state machine, let's fix that.
We'll use TMR2 to generate periodic interrupts at 10ms intervals. I'll let you give that a try yourself. Select values for the prescaler, PR2 and postscaler to generate interrupts at 10msec intervals. For now, just clear TMR2IF when its interrupted and return to the code. See the datasheet for the 628A to see how to write a basic interrupt code. If you have a scope, pulse a spare output line to confirm you have 10msec. We then will have a system tick that we can use to create other timers. As in the IO, I would put the timer init code in its own routine (initSYSTIK). This code should do everything BUT enabling GIE. Enable GIE as the last thing after ALL inits (IO, Timers and whatever).

When done with these two things, we will have the tools to move on to a state-driven real time system, one that is applicable to many other tasks.
Baby steps for now.

Have fun.

BTW: Since this is a school project you might not be up for a lot of changes at this time. If that's the case, you don't have to do any of the actual coding, just keep it in mind for the next one :)
 
Last edited:

Thread Starter

Cyrenaica —

Joined Jun 7, 2015
17
hi guys
more than year passed
i should notify that my previous code was wrong
here is the right one
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Автор:[DELETED]                                                                                ;
; Дата: 04.12.2015                                                                                    ;
; Версія: 1.2                                                                                        ;
; Назва: Світлофор автоматичний модифікований                                                        ;
; Опис: Програма являється імітатором світлофора для сімейства мікроконтроллерів PIC16F62X, викона- ;
; ним на світлодіодах. Робота регулюється вбудованими таймерами. Світлофор має автоматичне переми-    ;
; кання, однак вбудована функція ввімкнення жовтих блимань при натисканні на кнопку SA4. Автоматич- ;
; но повертається до звичайного режиму роботи.                                                        ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    list p=16f628                ;список параметрів
    #include <p16f628.inc>        ;підключення вихідного додаткового файлу
    __config _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
                                ;встановлення бітів рекомендованої конфігурації мікроконтролера
    cblock    0x22                ;визначення блоку констант
counter_1                        ;
counter_2                        ;
d1                                ;
d2                                ;
d3                                ;
    endc                        ;блок констант визначений
;================== початок програми ==================
    org 0x00                    ;встановлення адреси програми
    goto start_loop                ;відсилання до початкового контуру
    org 0x04                    ;встановлення адреси програми
    goto interrupt                ;відсилання до контуру переривання
start_loop                        ;визначення початкового контуру
;********* список використовуваних макросів *********
delay500us    macro                 ;макрос затримки часу на 500 мкс
    movlw D'5'                    ;
    movwf d3                    ;
    movlw D'5'                    ;
    movwf d2                    ;
    movlw D'5'                    ;
    movwf d1                    ;
    decfsz d1                    ;
    goto $-1                    ;
    decfsz d2                    ;
    goto $-5                    ;
    decfsz d3                    ;
    goto $-9                    ;
    endm                        ;
;********* кінець списку використовуваних макросів *********
;********* проведення необхідних налаштувань *********
    banksel INTCON                ;обрано банк регістра
    clrf INTCON                    ;регістр очищено
    banksel PORTA                ;обрано банк регістра
    clrf PORTA                    ;регістр очищено, клямки ініціалізовані
    movlw 0x07                    ;0x07 ---> WREG
    movwf CMCON                    ;WREG ---> CMCON — компаратор вимкнено; порти A є цифровими входами
    banksel TRISA                ;обрано банк регістра
    movlw b'00010000'            ;00010000 ---> WREG
    movwf TRISA                    ;WREG ---> TRISA — четвертий контакт порту A працює на вхід
    banksel PORTB                ;обрано банк регістра
    clrf PORTB                    ;регістр очищено, клямки ініціалізовані
    banksel TRISB                ;обрано банк регістра
    movlw b'11000000'            ;11000000 ---> WREG
    movwf TRISB                    ;WREG ---> TRISB — контакти 0-5 порту B працюють на вихід
    banksel OPTION_REG            ;обрано банк регістра
    movlw b'11010111'            ;11010111 ---> WREG
    movwf OPTION_REG            ;WREG ---> OPTION_REG — переддільник для таймера 0 — 1:256
    banksel TMR0                ;обрано банк регістра
    movlw .0                    ;0 ---> WREG
    movwf TMR0                    ;WREG ---> TMR0 — відлік від 0 до 255 (65536 к. ц.)
;********* необхідні налаштування закінчені *********
main_loop                        ;визначення головного контуру
    bsf PORTB,4                    ;
    bsf PORTB,1                    ;
    bcf PORTB,2                    ;
    bcf PORTB,3                    ;
    bcf PORTB,0                    ;
    movlw .92                    ;
    movwf counter_1                ;
loop_1                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_1                    ;до цього моменту реалізовувалася подія 1 (дивись таблицю 1)
    movlw .4                    ;кількість циклів ввімкнення/вимкнення зелених світлодіодів: 4
    movwf counter_2                ;
loop_2                            ;
    bcf PORTB,4                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_3                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_3                    ;
    bsf PORTB,4                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_4                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_4                    ;
    decfsz counter_2,f            ;
    goto loop_2                    ;до цього моменту реалізовувалися події 2-9
    bsf PORTB,2                    ;
    bsf PORTB,3                    ;
    bcf PORTB,4                    ;
    movlw .31                    ;
    movwf counter_1                ;
loop_5                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_5                    ;до цього моменту реалізовувалася подія 10
    bsf PORTB,0                    ;
    bsf PORTB,5                    ;
    bcf PORTB,2                    ;
    bcf PORTB,3                    ;
    bcf PORTB,1                    ;
    movlw .92                    ;
    movwf counter_1                ;
loop_6                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_6                    ;до цього моменту реалізовувалася подія 11
    movlw .4                    ;кількість циклів ввімкнення/вимкнення зелених світлодіодів: 4
    movwf counter_2                ;
loop_7                            ;
    bcf PORTB,5                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_8                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_8                    ;
    bsf PORTB,5                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_9                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_9                    ;
    decfsz counter_2,f            ;
    goto loop_7                    ;до цього моменту реалізовувалися події 12-19
    bsf PORTB,2                    ;
    bsf PORTB,3                    ;
    bcf PORTB,5                    ;
    movlw .31                    ;
    movwf counter_1                ;
loop_10                            ;
    call delay_1                ;
    decfsz counter_1,f            ;
    goto loop_10                ;до цього моменту реалізовувалася подія 20
    goto main_loop                ;відсилання до головного контуру
;********* підпрограми *********
delay_1                            ;визначення першого контуру затримки
    btfss PORTA,4                ;сигнал на четвертому контакті порту A має високий рівень?
    call timer_1                ;ні — відсилання до контуру таймера 1
    btfss INTCON,T0IF            ;так — перевірка таймера 0 на переповнення. Біт T0IF встановлений?
    goto delay_1                ;ні — відсилання до першого контуру затримки
    bcf INTCON,T0IF                ;так — скидання біту T0IF
    banksel TMR0                ;обрано банк регістра
    movlw .0                    ;0 ---> WREG
    movwf TMR0                    ;WREG ---> TMR0 — таймер 0 обнулено
    return                        ;повернення із підпрограми
delay_2                            ;визначення другого контуру затримки
    btfss INTCON,T0IF            ;біт T0IF встановлений?
    goto delay_2                ;ні — відсилання до другого контуру затримки
    bcf INTCON,T0IF                ;так — скидання біту T0IF
    banksel TMR0                ;обрано банк регістра
    movlw .0                    ;0 ---> WREG
    movwf TMR0                    ;WREG ---> TMR0 — таймер 0 обнулено
    return                        ;повернення із підпрограми
timer_1                            ;визначення контуру таймера 1
    banksel PORTA                ;обрано банк регістра
    bsf INTCON,GIE                ;глобальний дозвіл переривань
    bsf INTCON,PEIE                ;дозвіл переривань від периферійних модулів
    banksel PIE1                ;обрано банк регістра
    bsf PIE1,TMR1IE                ;переривання таймера 1 дозволене
    banksel T1CON                ;обрано банк регістра
    bsf T1CON,0                    ;ввімкнення модуля таймера 1
    bcf T1CON,1                    ;вибір внутрішнього джерела в якості джерела тактового сигналу
    movlw b'11111110'            ;11111110 ---> WREG
    movwf TMR1H                    ;WREG ---> TMR1H
    movwf TMR1L                    ;WREG ---> TMR1L
    delay500us                    ;затримка на 500 мкс
    nop                            ;порожній цикл (для контролю)
    goto main_loop                ;відсилання до головного контуру
;********* підпрограма обробки перериваннь *********
interrupt                        ;визначення контуру переривання
    bcf INTCON,GIE                ;глобальна заборона переривань
    banksel T1CON                ;обрано банк регістра
    bcf T1CON,0                    ;таймер 1 вимкнений
    bcf PIR1,TMR1IF                ;скидання прапора переривання таймера 1
    bcf PORTB,0                    ;
    bcf PORTB,1                    ;
    bcf PORTB,4                    ;
    bcf PORTB,5                    ;
    movlw .8                    ;кількість циклів ввімкнення/вимкнення жовтих світлодіодів: 8
    movwf counter_2                ;
loop_11                            ;
    bsf PORTB,2                    ;
    bsf PORTB,3                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_12                            ;
    call delay_2                ;
    decfsz counter_1,f            ;
    goto loop_12                ;
    bcf PORTB,2                    ;
    bcf PORTB,3                    ;
    movlw .8                    ;
    movwf counter_1                ;
loop_13                            ;
    call delay_2                ;
    decfsz counter_1,f            ;
    goto loop_13                ;
    decfsz counter_2,f            ;
    goto loop_11                ;блимання жовтими світлодіодами реалізоване
    retfie                        ;повернення із підпрограми із дозволом переривань
;********* кінець підпрограми обробки перериваннь *********
;********* кінець підпрограм *********
    end                            ;
;================== кінець програми ==================
there should have been " goto " instead of " return " in some place , i dont remember where
excuses for late posting
happy new year everyone
 
Last edited:
Top