1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
| ;------------------------------------------------------------------------------------------------------------------------------
list p = 16f628a
__config 03F30h ; 11111100110001 - защиты памяти нет, низковольтное программирование запрещено, сброс по питанию запрещен,
; RA5/-MCLR работает как -MCLR, таймер вкл-я питания включен, сторожевой таймер - выключен, генератор - внутренний
;********* Переменные ************************************
CBLOCK 0x20 ;Начальный адрес блока констант
T_ext ;таймер внешнего цикла
T_int ;таймер внутреннего цикла
Strok ;байт строк, младшие 5 бит этого байта - состояния строк (1 - вкл, 0 - выкл)
Stolb ;байт столбцов, младшие 5 бит этого байта - состояния столбцов (1 - вкл, 0 - выкл)
ENDC ;
;******** Константы ***************************************
Cr1 equ .200 ;длительность 1-й задержки 200 мкс
Cr2 equ .150 ;длительность 2-й задержки 150х200 мкс
Status equ 03h ; Регистр выбора банка
TrisA equ 05h ; Регистр выбора направления работы выводов порта А
TrisB equ 06h ; Регистр выбора направления работы выводов порта В
PortA equ 05h ; Регистр управления защелками порта А
PortB equ 06h ; Регистр управления защелками порта В
Cmcon equ 1Fh ; вкл/выкл компараторов
F equ 1 ; Результат направить в регистр.
;********************************************************
; Пусть у нас RA1, RA2, RA3, RA6, RA7 - выходы строки
; RB3, RB4, RB5, RB6, RB7 - выходы столбцы
;********************************************************
;
org 0
;******** Установка направления работы порта A: RA7, RA6 - выходы, RA5, RA4, RA3 - входы, RA2, RA1, RA0 - выходы
;******** Установка направления работы порта B: RB7, RB6, RB5, RB4, RB3, RB2 - выходы, RB1, RB0 - входы ***
start movlw .7 ;
movwf Cmcon ; выключить компараторы и включить эти пины как цифровые входы/выходы
clrf PortA ; инициализация защелок порта А
movlw .248 ; 11111000
movwf PortB ; инициализация защелок порта В
bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status).
movlw .49 ; Записать конфигурацию порта A в аккумулятор (W). .49=00110001
movwf TrisA ; Скопировать конфигурацию порта А из W в регистр TrisA
movlw .7 ; Записать конфигурацию порта В в аккумулятор (W). .3=00000111
movwf TrisB ; Скопировать конфигурацию порта B из W в регистр TrisB.
bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит регистра Status)
;******** ЭФФЕКТ 1 ********************************************************************************
eff1 movlw b'00011111' ; включаем все строки
movwf Strok
movlw b'00000001' ; и первый столбец
movwf Stolb
;-------- Включаем светодиоды -----------------
cikl_stolb1 call in_ports
call pause
rlf Stolb,1 ; переходим на следующий столбец
btfss Stolb,5 ; если 5 бит stolb = 1, то следующая команда пропускается
goto cikl_stolb1
;----------------------------------------------
movlw b'00000001' ; включаем первую строку
movwf Strok
movlw b'00011111' ; и все столбцы
movwf Stolb
;-------- Включаем светодиоды -----------------
cikl_strok1 call in_ports
call pause
rlf Strok,1 ; переходим на следующую строку
btfss Strok,5 ; если 5 бит stolb = 1, то следующая команда пропускается
goto cikl_strok1
goto eff1
;******************************************************************************* ***********************
;******** Процедура включения строк и столбцов
in_ports btfsc Stolb,0 ; если 0-й бит stolb = 0, то следующая команда пропускается
bcf PortB,3 ; RB3=0 - вкл.1 столбец
btfss Stolb,0 ; если 0-й бит stolb =1, то следующая команда пропускается
bsf PortB,3 ; RB3=1 - выкл. 1 столбец
;--------------------------------------
btfsc Stolb,1 ; если 1-й бит stolb = 0, то следующая команда пропускается
bcf PortB,4 ; RB4=0 - вкл. 2 столбец
btfss Stolb,1 ; если 1-й бит stolb =1, то следующая команда пропускается
bsf PortB,4 ; RB4=1 - выкл. 2 столбец
;-------------------------------------
btfsc Stolb,2 ; если 2-й бит stolb = 0, то следующая команда пропускается
bcf PortB,5 ; RB5=0 - вкл. 3 столбец
btfss Stolb,2 ; если 2-й бит stolb =1, то следующая команда пропускается
bsf PortB,5 ; RB5=1 - выкл. 3 столбец
;--------------------------------------
btfsc Stolb,3 ; если 3-й бит stolb = 0, то следующая команда пропускается
bcf PortB,6 ; RB6=0 - вкл. 4 столбец
btfss Stolb,3 ; если 3-й бит stolb =1, то следующая команда пропускается
bsf PortB,6 ; RB6=1 - выкл. 4 столбец
;--------------------------------------
btfsc Stolb,4 ; если 4-й бит stolb = 0, то следующая команда пропускается
bcf PortB,7 ; RB7=0 - вкл. 5 столбец
btfss Stolb,4 ; если 4-й бит stolb =1, то следующая команда пропускается
bsf PortB,7 ; RB7=1 - выкл. 5 столбец
;-------- Строки -----------------------------------------------------------
btfsc Strok,0 ; если 0-й бит strok = 0, то следующая команда пропускается
bsf PortA,2 ; RA2=1 - вкл.1 строку
btfss Strok,0 ; если 0-й бит strok =1, то следующая команда пропускается
bcf PortA,2 ; RA2=0 - выкл.1 строку
;--------------------------------------
btfsc Strok,1 ; если 1-й бит strok = 0, то следующая команда пропускается
bsf PortA,3 ; RA3=1 - вкл.2 строку
btfss Strok,1 ; если 1-й бит strok =1, то следующая команда пропускается
bcf PortA,3 ; RA3=0 - выкл.2 строку
;--------------------------------------
btfsc Strok,2 ; если 2-й бит strok = 0, то следующая команда пропускается
bsf PortA,1 ; RA1=1 - вкл.3 строку
btfss Strok,2 ; если 2-й бит strok =1, то следующая команда пропускается
bcf PortA,1 ; RA1=0 - выкл.3 строку
;--------------------------------------
btfsc Strok,3 ; если 3-й бит strok = 0, то следующая команда пропускается
bsf PortA,7 ; RA7=1 - вкл.4 строку
btfss Strok,3 ; если 3-й бит strok =1, то следующая команда пропускается
bcf PortA,7 ; RA7=0 - выкл.4 столбец
;--------------------------------------
btfsc Strok,4 ; если 4-й бит strok = 0, то следующая команда пропускается
bsf PortA,6 ; RA6=1 - вкл.5 строку
btfss Strok,4 ; если 4-й бит strok =1, то следующая команда пропускается
bcf PortA,6 ; RA6=0 - выкл.5 строку
return
;******************************************************************************* *********************
;******** Процедура Паузы ****************************************************************************
pause movlw Cr2
movwf T_ext ; загрузить значение для внешнего цикла
cikl2 movlw Cr1
movwf T_int ; загрузить значение для внутреннего цикла
cikl3 decfsz T_int,1 ; если T_int = 0, следующая команда пропускается
goto cikl3 ; внутренний цикл
decfsz T_ext,1 ; если T_ext = 0, следующая команда пропускается
goto cikl2 ; внешний цикл
return
end
ПРИЛОЖЕНИЕ В
Программа для создания эффекта «Вращающийся крест»
;--------------------------------------------------------------------------------------------------------------------------
list p = 16f628a
__config 03F30h ; 11111100110001 - защиты памяти нет, низковольтное программирование запрещено,
; сброс по питанию запрещен, RA5/-MCLR работает как -MCLR, таймер вкл-я питания включен,
; сторожевой таймер - выключен, генератор - внутренний
;********* Переменные ************************************
CBLOCK 0x20 ; Начальный адрес блока
Temp ; обменник , 20h
Adr ; адрес фрейма в EEPROM или ОЗУ , 21h
T_int ; счетчик для паузы , 22h
Strok ; байт текущего состояния строк , 23h
Stolb ; байт текущего состояния столбцов , 24h
Fr_sch ; счетчик фреймов , 25h
Fr_cikl ; счетчик показов одного фрейма , 26h
Fr_kol ; количество фреймов , 27h
Fr_cikl_kol ; количество показов одного фрейма , 28h
;----- Свободная память ОЗУ в нулевом банке от 29h до 7Fh ---------------------------------
;----- Из этих 86 своб-х байт в первые 30 мы будем грузить наши фреймы ------------------
ENDC ;
;******** Константы ***************************************
Status equ 03h ; Регистр выбора банка
TrisA equ 05h ; Регистр выбора направления работы выводов порта А
TrisB equ 06h ; Регистр выбора направления работы выводов порта В
PortA equ 05h ; Регистр управления защелками порта А
PortB equ 06h ; Регистр управления защелками порта В
Cmcon equ 1Fh ; вкл/выкл компараторов
F equ 1 ; Результат направить в регистр.
FSR equ 04h ; регистр адреса при косвенной адресации
INDF equ 0h ; регистр косвенной адресации
Cr equ .50 ; значение счетчика для паузы
EEADR equ 1Bh ; адрес EEPROM
EECON1 equ 1Ch ; управляющий регистр для работы c EEPROM
EEDATA equ 1Ah ; регистр данных из/в EEPROM
;********************************************************
; Пусть у нас RA1, RA2, RA3, RA6, RA7 - выход строки
; RB3, RB4, RB5, RB6, RB7 - выходы столбцы
;********************************************************
org 0
;******** Установка направл-я работы порта A: RA7, RA6 - выходы, RA5, RA4, RA3 - входы, RA2, RA1, RA0 - выходы
;******** Установка направл-я работы порта B: RB7, RB6, RB5, RB4, RB3, RB2 - выходы, RB1, RB0 - входы *********
start movlw .7 ;
movwf Cmcon ; выключить компараторы и включить эти пины как цифровые входы/выходы
clrf PortA ; инициализация защелок порта А
movlw .248 ; 11111000
movwf PortB ; инициализация защелок порта В
bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит регистра Status).
movlw .49 ; Записать конфигурацию порта A в аккумулятор (W). .49=00110001
movwf TrisA ; Скопировать конфигурацию порта А из W в регистр TrisA
movlw .7 ; Записать конфигурацию порта В в аккумулятор (W). .3=00000111
movwf TrisB ; Скопировать конфигурацию порта B из W в регистр TrisB.
bcf Status,0 ; Сбросить флаг переноса (С) (после старта он может быть любым)
;******** Загрузка данных для фреймов из EEPROM в ОЗУ *******************************************************
;--------- Сначала прочитаем первый байт - узнаем, сколько фреймов надо считать ------------------
movlw .0 ; банк менять не надо, мы уже в первом банке
movwf EEADR ; установить адрес для чтения из EEPROM
bsf EECON1,0 ; чтение
movf EEDATA,0 ; запись прочитанного байта в аккумулятор
bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит регистра Status)
movwf Fr_kol ; сохранение прочитанного байта в Fr_kol
;-------- Fr_kol*5+1 - узнаем сколько байт надо считать --------------------------
rlf Fr_kol,0 ; умножаем на 2
movwf Temp
rlf Temp,0 ; еще на 2 (после этой команды в аккумуляторе Fr_kol*4)
addwf Fr_kol,0 ; после этого в аккумуляторе Fr_kol*5
movwf Temp ; сохраняем это значение в Temp
incf Temp,1 ; теперь Temp=Fr_kol*5+
;---------- Считываем Fr_kol*5+1 байт ----------------------------------------------
movlw 28h ; считанные данные сохраняем начиная с этого адреса (первый байт в Fr_cikl_kol и далее...)
movwf FSR ; адрес для косвенной адресации
movlw .1 ; начинаем читать EEPR
movwf Adr ; с адреса 1
zagruzka bsf Status,5 ; перейти в первый банк
movwf EEADR ; загружаем из аккумулятора адрес для чтения из EEPROM
bsf EECON1,0 ; чтение
movf EEDATA,0 ; запись прочитанного байта в аккумулятор
bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит регистра Status)
movwf INDF ; сохраняем считанный байт по адресу, записанному в FSR
incf FSR,1 ; увеличиваем адрес ОЗУ
incf Adr,1 ; увеличиваем адрес EEPROM
movf Adr,0 ; загружаем адрес EEPROM в аккумулятор
decfsz Temp,1 ; если считали все байты - следующая команда пропускается
goto zagruzka
;******************************************************************************* *******************
;******** Основная прога **************************************************************************
effect movlw 29h ; загружаем адрес начала первого фрейма в ОЗУ (2h) в переменную Adr
movwf Adr ;
movf Fr_kol,0 ; загружаем кол-во фреймов
movwf Fr_sch ; в счетчик фреймов
show movf Fr_cikl_kol,0 ; загружаем кол-во показов одного фрейма
movwf Fr_cikl ; в счетчик показов фрейма
povtor call show_frame ; показываем один фрейм Fr_cikl кол-во раз
decfsz Fr_cikl,1
goto povtor
movlw .5 ; переходим к следующему фрейму (сдвигаем Adr на 5)
addwf Adr,1
decfsz Fr_sch,1 ; уменьшаем счетчик фреймов для показа
goto show ; если не все наборы показаны, то переходим к следующему
goto effect ; если все, то начинаем сначала
;******************************************************************************* **************
;********* Процедура показа одного фрейма ****************************************************
show_frame movf Adr,0 ; загружаем в FSR адрес начала фрейма
movwf FSR
movlw b'00000001' ; начинаем с первой строки
movwf Strok
show_next movf INDF,0 ; загружаем набор столбцов для выбранной строки
movwf Stolb ; аккумулятор в stolb
call in_ports
call pause
call erase
incf FSR,1 ; следующий набор строк
rlf Strok,1 ; переходим на следующую строку
btfss Strok,5 ; если 5-й бит strok = 1, то следующая команда пропускается
goto show_next
return
;******** Процедура включения строк и столбцов в соответствии с байтами Strok и Stolb ************
in_ports btfsc Stolb,0 ; если 0-й бит stolb = 0, то следующая команда пропускается
bcf PortB,3 ; RB3=0 - вкл.1 столбец
btfss Stolb,0 ; если 0-й бит stolb =1, то следующая команда пропускается
bsf PortB,3 ; RB3=1 - выкл. 1 столбец
;--------------------------------------
btfsc Stolb,1 ; если 1-й бит stolb = 0, то следующая команда пропускается
bcf PortB,4 ; RB4=0 - вкл. 2 столбец
btfss Stolb,1 ; если 1-й бит stolb =1, то следующая команда пропускается
bsf PortB,4 ; RB4=1 - выкл. 2 столбе
;--------------------------------------
btfsc Stolb,2 ; если 2-й бит stolb = 0, то следующая команда пропускается
bcf PortB,5 ; RB5=0 - вкл. 3 столбец
btfss Stolb,2 ; если 2-й бит stolb =1, то следующая команда пропускается
bsf PortB,5 ; RB5=1 - выкл. 3 столбец
;--------------------------------------
btfsc Stolb,3 ; если 3-й бит stolb = 0, то следующая команда пропускается
bcf PortB,6 ; RB6=0 - вкл. 4 столбец
btfss Stolb,3 ; если 3-й бит stolb =1, то следующая команда пропускается
bsf PortB,6 ; RB6=1 - выкл. 4 столбец
;--------------------------------------
btfsc Stolb,4 ; если 4-й бит stolb = 0, то следующая команда пропускается
bcf PortB,7 ; RB7=0 - вкл. 5 столбец
btfss Stolb,4 ; если 4-й бит stolb =1, то следующая команда пропускается
bsf PortB,7 ; RB7=1 - выкл. 5 столбец
;-------- Строки -----------------------------------------------------------
btfsc Strok,0 ; если 0-й бит strok = 0, то следующая команда пропускается
bsf PortA,2 ; RA2=1 - вкл.1 строку
btfss Strok,0 ; если 0-й бит strok =1, то следующая команда пропускается
bcf PortA,2 ; RA2=0 - выкл.1 строку
;--------------------------------------
btfsc Strok,1 ; если 1-й бит strok = 0, то следующая команда пропускается
bsf PortA,3 ; RA3=1 - вкл.2 строку
btfss Strok,1 ; если 1-й бит strok =1, то следующая команда пропускается
bcf PortA,3 ; RA3=0 - выкл.2 строку
;--------------------------------------
btfsc Strok,2 ; если 2-й бит strok = 0, то следующая команда пропускается
bsf PortA,1 ; RA1=1 - вкл.3 строку
btfss Strok,2 ; если 2-й бит strok =1, то следующая команда пропускается
bcf PortA,1 ; RA1=0 - выкл.3 строку
;--------------------------------------
btfsc Strok,3 ; если 3-й бит strok = 0, то следующая команда пропускается
bsf PortA,7 ; RA7=1 - вкл.4 строку
btfss Strok,3 ; если 3-й бит strok =1, то следующая команда пропускается
bcf PortA,7 ; RA7=0 - выкл.4 столбец
;--------------------------------------
btfsc Strok,4 ; если 4-й бит strok = 0, то следующая команда пропускается
bsf PortA,6 ; RA6=1 - вкл.5 строку
btfss Strok,4 ; если 4-й бит strok =1, то следующая команда пропускается
bcf PortA,6 ; RA6=0 - выкл.5 строку
return
;****** Пауза ******************************************************
pause movlw Cr
movwf T_int ; загрузить кол-во циклов задержки
cikl3 decfsz T_int,1 ; если T_int = 0, следующая комада пропускается
goto cikl3 ; внутренний цикл
return
;****** Гашение всех светодиодов ***********************************
erase movf Strok,0
movwf Temp
movlw .0
movwf Stolb
movwf Strok
call in_ports
movf Temp,0
movwf Strok
return
;******************************************************************************* ************************
org 2100h ; EEPROM память
de .6, .40 ; кол-во фреймов и кол-во показов одного фрейма (скорость)
de b'00000100', b'00000100', b'00011111', b'00000100', b'00000100' ; первый фрейм
de b'00001000', b'00000101', b'00001110', b'00010100', b'00000010' ; второй фрейм
de b'00001000', b'00001011', b'00000100', b'00011010', b'00000010' ; третий фрейм
de b'00010001', b'00001010', b'00000100', b'00001010', b'00010001' ; четвертый фрейм
de b'00000010', b'00011010', b'00000100', b'00001011', b'00001000' ; пятый фрейм
de b'00000010', b'00010100', b'00001110', b'00000101', b'00001000' ; шестой фрейм
end
;-------------------------------------------------------------------------------------------------------------------------- |