Тест перевірки окремих вузлів або пристроїв

 

Програма за якою працює мікропроцесор мовою асемблера АТ89С4051 має наступний вигляд:

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

 

ORG 0

Goto               PROGRAM

 

sec                  equ H'11'              ; секунди

sec10              equ H'12'              ; Десятки секунд

min                 equ H'13'              ; минути

min10                       equ H'14'              ; Десятки минут

hour                equ H'15'              ; години

hour10                     equ H'16'              ; Десятки годин

Indicator         equ H'17'              ; 7-сегментний код для загрузки в регістр DD2

Bit_counter              equ H'18'              ; лічильник бітів, загруженних в регістр DD2

FLAGS           equ H'19'              ; різні прапорці

FLAGS_2       equ H'1F'

Fig_pointer     equ H'1B'             ; показник виведеної цифри

TEMP                      equ H'1C'             ; для тимчасового збереження вмісту порту A

Ind_start         equ H'1D'             ; адреса комірки, яка першою виводиться на індикатор

SB_delay        equ H'1E'             ; часова затримка

STATUS_copy equ H'21'              ; копії вмісту регістрів

W_copy          equ H'22'

FSR_copy      equ H'23'

min_al_1        equ H'24'              ; регістри першого будильника

min10_al_1              equ H'25'

hour_al_1       equ H'26'

hour10_al_1            equ H'27'

min_al_2        equ H'28'              ; регістри другого будильника

min10_al_2              equ H'29'

hour_al_2       equ H'2A'

hour10_al_2            equ H'2B'

EEP_Ind_4            equ H'2C'             ; регістри для індикації

EEP_Ind_3            equ H'2D'             ; режиму роботи з EEPROM

EEP_Ind_2            equ H'2E'

EEP_Ind_1            equ H'2F'

Alarm_count            equ H'30'              ; лічильник будильника

SB4_count             equ H'31'              ; лічильник часу натискання на кнопку SB2

IntCount_H             equ H'32'              ; лічильник переповнення таймеру номер 1

IntCount_L             equ H'33'              ; лічильник переповнення таймеру номер 2

MaxInt_H             equ H'34'              ; верхня границя лічильника переривань

MaxInt_L              equ H'35'              ; визначає секундну затримку

TIME_SET           equ H'36'              ; коефіцієнт корекції часу

 

; ------------- Підпрограма яка добавляє хвилини ---------------

 

INC_MIN macro Reg1_min,Reg2_min

 

movfw            Reg1_min     ; якщо кількість менут = 9 то

xorlw                       9                    ; обнуляємо менути і прибавляємо десятки менут

BZ               $+3           ; інакше прибавляємо менути та виходимо з підпрограми

incf                Reg1_min, f

goto Main_loop

 

clrf                 Reg1_min

movfw            Reg2_min

xorlw                       5                    ; якщо кількість десятків менут = 5,

BZ               $+3             ; обнуляємо менути та взагалі та виходимо з підпрограми

incf                Reg2_min, f  ; інакше прибавляємо десятки менут

goto               Main_loop

 

clrf                 Reg1_min

clrf                 Reg2_min

goto               Main_loop

 endm

 

 ; ------------- Підпрограма яка прибавляє години ---------------

 

INC_HOUR macro Reg1_hour,Reg2_hour

 

movfw            Reg1_hour     ; якщо кількість годин = 3, то перевіряємо чи

xorlw                       3                    ; число десятків годин = 2, якщо так то

btfss              STATUS, Z; обнуляємо години взагалі (перехід із 23 годин в 00)

goto                $+5

 

movfw            Reg2_hour

xorlw                       2

BZ               $+D'14'

 

movfw            Reg1_hour     ; якщо число годин = 10, прибавляєм

xorlw                       9                    ; десятки годин і скидаємо одениці

BZ               $+3           ; інакше прибавляєм одениці годин та виходимо із підпрограми

incf                Reg1_hour, f

goto               Main_loop

 

clrf                 Reg1_hour

movfw            Reg2_hour

xorlw                       2

BZ               $+3

incf                Reg2_hour, f

goto               Main_loop

 

clrf                 Reg1_hour

clrf                 Reg2_hour

goto               Main_loop

 endm

 

; ------------- Підпрограма зменшення хвилин ---------------

 

DEC_MIN macro Reg1_min,Reg2_min

local DEC_min10,Clr

 

movfw            Reg1_min              ; зменшуєм хвилини

xorlw                       0

BZ               DEC_min10

decf                Reg1_min,f

goto               Main_loop

DEC_min10           movlw 9   ; установлюєм число хвилин = 9

movwf            Reg1_min              ; і зменшуєм десятки хвилин

movfw            Reg2_min

xorlw                       0

BZ               Clr

decf                Reg2_min, f

goto               Main_loop

movlw            5

movwf            Reg2_min

goto               Main_loop

 endm

 

 ; ------------- Підпрограма зменшення годин ---------------

 

DEC_HOUR macro Reg1_hour,Reg2_hour

local Set_hour,Clr,If_hour10_1,If_hour10_2,Dec_hour10

 

movfw            Reg1_hour            ; зменшуєм години

xorlw                       0

BZ               Set_hour

decf                Reg1_hour, f

goto               Main_loop

movfw            Reg2_hour            ; якщо десятки годин = 0,

xorlw                       0             ; установлюємо години рівні 3

btfss                STATUS, Z   

goto               If_hour10_1

movlw            3

movwf            Reg1_hour

goto               Dec_hour10

If_hour10_1             movfw Reg2_hour; якщо десятки годин = 1,

xorlw                       1             ; установлюєм число годин = 9

btfss                STATUS, Z

goto               If_hour10_2

movlw            9

movwf            Reg1_hour

goto               Dec_hour10

If_hour10_2             movlw   9 ; якщо десятки годин = 2,

movwf       Reg1_hour            ; установлюємо години рівні 9

Dec_hour10            movfw Reg2_hour; зменшуєм десятки годин

xorlw                       0

BZ               Clr

decf                Reg2_hour, f

goto               Main_loop

Clr                  movlw   2

movwf            Reg2_hour

goto               Main_loop

 endm

 

 ; ------------- Підпрограма запису в EEPROM ---------------

 

EE_write macro Adress,Data

 

movlw            Adress

movwf            EEADR

movfw            Data

movwf            EEDATA

call                 Write_to_EEPROM

 endm

 

 ; ------------- Підпрограма читання EEPROM ---------------

 

EE_read   macro Adress,Destination

 

movlw            Adress 

movwf            EEADR

call                 Read_from_EEPROM

movfw            EEDATA

movwf       Destination

 endm

 

 ; ------------------- ІНІЦІАЛІЗАЦІЯ ----------------------

PROGRAM

bsf                STATUS,RP0; банк 1

clrf                 TRISA               ; порт А на вихід

movlw            B'11110000'          ; RB7..RB4 - на вхід, RB3..RB0 - на вихід

movwf            TRISB

movlw            B'00001000'          ; відключений від таймеру

movwf            OPTION_REG

bcf                STATUS, RP0    ; банк 0

clrf                 TIME_SET

clrf                 FLAGS

clrf                 FLAGS_2

clrf                 sec

clrf                 sec10

clrf                 min

clrf                 min10

clrf                 hour

clrf                 hour10

clrf                 SB_delay

clrf                 Bit_counter

clrf                 Alarm_count

clrf                 PORTB

clrf                 SB4_count

clrf                 IntCount_H

clrf                 IntCount_L

 

movlw            B'00010001'

movwf            PORTA

movlw            H'16'         ; починаєм індикацію з десятків годин

movwf            Ind_start

movfw            Ind_start

movwf            Fig_pointer

bsf                FLAGS,PT          ; ввімкнення крапок на індикаторі

bsf                FLAGS_2, HL1

movlw          D'16'         ; запускаємо таймер номер 0

movwf          TMR0

EE_read          1, TIME_SET    ; читаємо значення коэфіціэнту

movwf          TIME_SET           ; корекції часу

EE_read          2, min_al_1; читаєм показпоказники обох

EE_read          3, min10_al_1   ; будильників з EEPROM

EE_read          4, hour_al_1

EE_read          5, hour10_al_1

EE_read          6, min_al_2

EE_read          7, min10_al_2

EE_read          8, hour_al_2

EE_read          9, hour10_al_2

movfw           min_al_1             ; якщо в регістрах будильника

xorlw                      H'11'         ; були числа 0х11, тоді,

btfss                        STATUS,Z          ; він був вімкнений при останньому

bsf               FLAGS, Al_on   ; записі в EEPROM

movfw           min_al_2

xorlw                      H'11'

btfss                        STATUS, Z

bsf               FLAGS_2, Al_on2

bsf               PORTB, 3; вмикаєм світлодіод

btfsc                        FLAGS, Al_on

bcf               PORTB, 3

btfsc                        FLAGS_2, Al_on2

bcf               PORTB, 3

bsf               INTCON, T0IE    ; дозволяєм переривання

bsf               INTCON, GIE

movlw           H'E'               ; ініціалізація регістрів для правельної індикації

movwf           EEP_Ind_1           ; режим роботи EEPROM

movlw           H'E'  

movwf           EEP_Ind_2   

movfw           TIME_SET; розбиваємо змінну TIME_SET

andlw                      B'00001111'          ; на 16-розрядні десятки та одениці

movwf           EEP_Ind_4          ; одениці

movfw           TIME_SET

movwf           EEP_Ind_3          ; десятки

swapf                      EEP_Ind_3,    f

movlw           B'00001111'

andwf       EEP_Ind_3,    f       

 

 

;******************************************************************

 ;  ГОЛОВНИЙ ЦИКЛ ПРОГРАМИ

******************************************************************

 

movlw H'21' ; задаємо верхню границю

movwf           MaxInt_L           ; лічби переривань = 3873

movlw           H'F'

movwf           MaxInt_H

movfw           TIME_SET; добавляєм TIME_SET до границі

bcf               STATUS, C; лічби переповнення таймера

addwf            MaxInt_L, f

btfsc                        STATUS, C

incf               MaxInt_H, f

movfw           IntCount_H          ; порівнюєм старший байт

xorwf                      MaxInt_H, w

btfss                        STATUS, Z

goto                        Main_loop

movfw           IntCount_L          ; порівнюєм молотший байт

xorwf                      MaxInt_L, w

btfss                        STATUS, Z

goto                        Main_loop

goto                        ADD1s          ; секунда пройшла

 

 ; ------- Процедура перекодування числа в семисегментний код --------

 

Table

   addwf PCL,f

   retlw B'00000010'; цифра 0

   retlw B'10011110'; цифра 1

   retlw B'00100100'; цифра 2

   retlw B'00001100'; цифра 3

   retlw B'10011000'; цифра 4

   retlw B'01001000'; цифра 5

   retlw B'01000000'; цифра 6

   retlw B'00011110'; цифра 7

   retlw B'00000000'; цифра 8

   retlw B'00001000'; цифра 9

    retlw B'11111110'; пусте місце (код 10h)

   retlw B'11111100'; тире (код 11h)

 

 ;********************* Режим індикації секунд ***********************

Show_seconds

 

clrf                SB4_count

btfsc                        FLAGS,Sec           ; якщо на індикаторі показані секунди

goto                        Show_hour           ; повертаємся до нормального вигляду

movlw           H'14'      

movwf           Ind_start  

bsf               FLAGS, Sec

movwf           SB_delay

goto                        Main_loop

Show_hour

 

movlw           H'16'

movwf           Ind_start

bcf               FLAGS,Sec

movwf           SB_delay

goto                        Main_loop

 

 ;***************** Добавляєм менути реального часу ******************

 

ADDmin_button

clrf               sec

clrf               sec10

INC_MIN min, min10

goto                       Main_loop

 

 ;******************Добавляєм години реального часу ******************

 

ADDh_button

clrf                       sec

clrf                       sec10

INC_HOUR             hour, hour10

goto            Main_loop

 

END                                           ; кінець програми


Рисунок 3.2.1 - Блок-схема роботи пристрою



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: