Материал из EPIRB Wiki
RA1AMO (обсуждение | вклад) (Новая страница: «<pre> ; время работы 3 часа ; 11-06-05 ; после прошествия 5 минут с момента начала отсчета задержк…») |
RA1AMO (обсуждение | вклад) (→Версия прошивки 3.1, циклы 30с/120с; 60с/60с; 1м/4м) |
||
| (не показано 14 промежуточных версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
| + | ==Контроллер маяка на PIC16F630== | ||
| + | |||
| + | [[File:Pic_beacon.jpg|300px|thumb|none|Контроллер маяка на PIC16F630]] | ||
| + | |||
| + | [[File:Key3_amo.gif|299px|thumb|none|Переключатель для управления маяком]] | ||
| + | |||
| + | [[File:Mf3_amo.gif|432px|thumb|none|Схема контроллера]] | ||
| + | |||
| + | ===Версия прошивки 3.0, циклы 30с/30с; 60с/60с; 1м/4м=== | ||
| + | |||
| + | [[file:Mf3.HEX.zip]] | ||
| + | |||
<pre> | <pre> | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | ; | + | ;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, MOT, T). Вариант кода задается переключателем. |
| − | + | ;-Может работать непрерывно или циклом: 30с/30с; 60с/60с; 1м/4м. | |
| − | ; | + | ;-Есть выход 1000 Гц для модуляции маяка на 144 МГц. |
| − | ; | + | ;-Автоотключение через 8 часов. |
| − | ; | + | ;-Потребление в выключенном состоянии 0.08 ма, во время работы, при передаче позывного, 0.5 ма. |
| − | ; | + | ;-Уход часов определяется кварцем. |
| − | + | ;-Код с переключателя считывается один раз после сброса. | |
| − | + | ;-Режим отложенного старта (ОС), задержка 120 минут | |
| − | + | ;-Ускорение передачи позывного за 10 сек до конца цикла (только для 5 мин цикла) | |
| − | ; | + | ;-Питание от 3 до 5 вольт |
| − | + | ||
| − | + | ||
| − | ; | + | |
| − | ; | + | |
| − | + | ||
| − | ; | + | |
| − | ; | + | |
; | ; | ||
; PIC16F630 | ; PIC16F630 | ||
| Строка 53: | Строка 43: | ||
; FLAG,3 флаг взводится через 5 мин после начала работы | ; FLAG,3 флаг взводится через 5 мин после начала работы | ||
; и отменяет задержку включения при сбросе | ; и отменяет задержку включения при сбросе | ||
| + | ; FLAG,4 флаг устанавливается за 10 сек до конца цикла | ||
| + | |||
DELAY ; счетчик пятиминуток, задержка включения | DELAY ; счетчик пятиминуток, задержка включения | ||
| Строка 99: | Строка 91: | ||
EEDAT EQU 0X9A ; прочитанные из EEPROM данные | EEDAT EQU 0X9A ; прочитанные из EEPROM данные | ||
PCON EQU 0X8E ; регистр power control | PCON EQU 0X8E ; регистр power control | ||
| − | PIE1 EQU 0X8C ; регистр контроля | + | PIE1 EQU 0X8C ; регистр контроля периферийных прерываний |
PIR1 EQU 0X0C ; регистр флагов прерываний от | PIR1 EQU 0X0C ; регистр флагов прерываний от | ||
| − | ; | + | ; периферийных модулей |
; | ; | ||
| Строка 147: | Строка 139: | ||
SKPC ; пропустить, если результат >=0 | SKPC ; пропустить, если результат >=0 | ||
BSF FLAG,0 ; | BSF FLAG,0 ; | ||
| + | |||
| + | |||
| + | MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла | ||
| + | SUBLW D'125' ; ставим флаг, по которому во время передачи | ||
| + | SKPNZ ; меняем скорость | ||
| + | BSF FLAG,4 ; только при 5 мин цикле | ||
| + | |||
| + | ; использовать либо верхнее, либо нижнее | ||
| + | |||
| + | ;SUBLW D'250' ; а это костыль для ускорения за 10 сек | ||
| + | ;SKPNZ ; до конца любого цикла, даже если | ||
| + | ;BSF FLAG,4 ; работаем непрерывно | ||
DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0 | DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0 | ||
GOTO POP_TX | GOTO POP_TX | ||
MOVF TX_ALL,W ; восстанавливаем | MOVF TX_ALL,W ; восстанавливаем | ||
| − | MOVWF TX_ALL_CNT ; | + | MOVWF TX_ALL_CNT ; |
| + | |||
| + | BCF FLAG,4 ; в конце цикла сбросить флаг ускорения | ||
POP_TX | POP_TX | ||
| Строка 159: | Строка 165: | ||
MOVWF SEC_CNT | MOVWF SEC_CNT | ||
| + | BTFSS FLAG,2 ; если задержка активирована, то | ||
BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг | BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг | ||
; отмены задержки включения | ; отмены задержки включения | ||
| Строка 206: | Строка 213: | ||
; после считывания напряжение с переключателя | ; после считывания напряжение с переключателя | ||
; снимается для экономии энергии | ; снимается для экономии энергии | ||
| + | |||
| + | ;================================================================== | ||
| + | ; инициализация TMR1 | ||
| + | ; | ||
| + | CLRF T1CON ; очистить TIMER1 control register | ||
| + | CLRF TMR1H ; очистить верхний байт TMR1 | ||
| + | CLRF TMR1L ; очистить нижний байт TMR1 | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | CLRF PIE1 ; очистить рег контроля периферийных прерываний | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | CLRF PIR1 ; очистить рег флагов периферийных прерываний | ||
| + | MOVLW B'00001110' ; инициализация TIMER1 control register | ||
| + | MOVWF T1CON ; с этого момента генератор 32.768 включен | ||
| + | |||
;================================================================== | ;================================================================== | ||
| Строка 212: | Строка 234: | ||
MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин | MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин | ||
DECF SEC_CNT,F ; имитируем прерывание | DECF SEC_CNT,F ; имитируем прерывание | ||
| − | + | ||
| − | MOVLW D' | + | ;MOVLW D'2' ; сколько пятиминуток будем работать |
| − | MOVWF MIN_CNT ; | + | MOVLW D'96' ; сколько пятиминуток будем работать |
| + | MOVWF MIN_CNT ; 96х5=8 час | ||
; MOVLW D'2' ; сколько пятиминуток задержка включения | ; MOVLW D'2' ; сколько пятиминуток задержка включения | ||
MOVLW D'24' ; сколько пятиминуток задержка включения | MOVLW D'24' ; сколько пятиминуток задержка включения | ||
MOVWF DELAY ; 24х5=120 мин | MOVWF DELAY ; 24х5=120 мин | ||
| − | + | ||
MOVLW D'178' ; тон звука, 178 ~ 1000 Гц | MOVLW D'178' ; тон звука, 178 ~ 1000 Гц | ||
MOVWF SET_TONE ; чем больше, тем ниже частота | MOVWF SET_TONE ; чем больше, тем ниже частота | ||
BSF FLAG,0 ; поднимаем флаг | BSF FLAG,0 ; поднимаем флаг | ||
| + | |||
| + | BCF FLAG,4 | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; если это включение питания, то выполняется задержка для | ||
| + | ; гарантированного запуска генератора 32768 и его инициализация | ||
| + | ; если другой сброс, то инициализация и задержка пропускаются | ||
| + | ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVF PCON,W ; PCON -> W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | MOVWF TMPW ; W -> TMPW | ||
| + | BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс | ||
| + | GOTO DELAY_START ; по включению - задержка однозначно нужна | ||
| + | BTFSC TMPW,BOR ; а это был сброс по снижению напр питания | ||
| + | GOTO SKIP_DELAY ; или не был... | ||
| + | |||
| + | DELAY_START | ||
| + | |||
| + | BCF FLAG,3 ; при первом включении очистить FLAG,3 | ||
| + | |||
| + | ; задержка | ||
| + | MOVLW D'255' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | MOVLW 0X80 | ||
| + | MOVWF CW_CHAR ; | ||
| + | CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BSF PCON,POR ; устанавливаем POR=1 | ||
| + | BSF PCON,BOR ; устанавливаем BOR=1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | SLEEP ; ожидаем запуск | ||
| + | |||
| + | SKIP_DELAY | ||
| Строка 262: | Строка 324: | ||
MOVLW D'60' ; цикл 120 сек | MOVLW D'60' ; цикл 120 сек | ||
GOTO END_SW | GOTO END_SW | ||
| − | |||
SW11 ; цикл 1 мин/4 мин | SW11 ; цикл 1 мин/4 мин | ||
MOVLW D'120' ; молчим последние 4 m | MOVLW D'120' ; молчим последние 4 m | ||
MOVWF TX_OFF ; | MOVWF TX_OFF ; | ||
MOVLW D'150' ; цикл 5 m | MOVLW D'150' ; цикл 5 m | ||
| − | |||
END_SW | END_SW | ||
| Строка 273: | Строка 333: | ||
MOVWF TX_ALL_CNT ; инициализация | MOVWF TX_ALL_CNT ; инициализация | ||
DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось | DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Окончание инициализации TIMER1 | ||
| + | ; | ||
| + | |||
| + | MOVLW B'11000000' ; разрешить прерывания от периферийных модулей | ||
| + | MOVWF INTCON | ||
| + | |||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | BSF PIE1,TMR1IE ; разрешить прерывания от TMR1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF T1CON,TMR1ON ; TMR1 ON | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; Если с момента запуска прошло 5 мин, то при сбросе задержку | ||
| + | ; включения игнорируем | ||
| + | |||
| + | BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала | ||
| + | ; работы | ||
| + | BSF FLAG,2 ; задержка включения не нужна | ||
| + | |||
| + | ;================================================================== | ||
| + | ; MAIN | ||
| + | ; передача последовательности символов | ||
| + | ; можно предавать любое количество, 0XFF означает конец последовательности, | ||
| + | ; после чего формируется пауза и передача циклически повторяется | ||
| + | ; | ||
| + | SEND_MSG | ||
| + | ; если автоотключение не нужно, то три | ||
| + | ; нижеследующих строчки надо закомментировать | ||
| + | MOVF MIN_CNT,F ; проверяем, не обнулился ли | ||
| + | SKPNZ ; счетчик пятиминуток | ||
| + | GOTO POWER_OFF ; если да, то выключаемся | ||
| + | |||
| + | BTFSS FLAG,2 ; пропустить след, если задержка включения | ||
| + | ; кончилась (1-разрешение работы) | ||
| + | GOTO FLASH ; мигнуть и sleep | ||
| + | |||
| + | BTFSS FLAG,0 ; если флаг сброшен, то идем спать | ||
| + | GOTO TO_SLEEP | ||
| + | |||
| + | MOVF SWITCH,W | ||
| + | MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX | ||
| + | |||
| + | GET_MSG | ||
| + | MOVF CHAR_INDEX,W | ||
| + | BCF INTCON,GIE ; запрещаем прерывания | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM | ||
| + | BSF EECON1,RD ; разрешаем чтение EEPROM | ||
| + | MOVF EEDAT,W ; значение ячейки -> регистр W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF INTCON,GIE ; разрешаем прерывания | ||
| + | ;MOVLW 0x06 | ||
| + | MOVWF CW_CHAR ; W -> CW_CHAR | ||
| + | |||
| + | MOVLW 0XFF ; конец сообщения? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ | ||
| + | GOTO END_MSG ; да, перейти к END_MSG | ||
| + | |||
| + | MOVLW D'60' ; скорость передачи быстро | ||
| + | BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла | ||
| + | MOVLW D'160' ; скорость передачи медленно | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | CALL SEND_CHAR ; передаем букву и паузу в 3 точки | ||
| + | ; или паузу 6 точек, если SPACE | ||
| + | INCF CHAR_INDEX ; CHAR_INDEX+1 | ||
| + | GOTO GET_MSG | ||
| + | |||
| + | END_MSG | ||
| + | CALL WORD_SPACE ; пауза 6 точек | ||
| + | GOTO SEND_MSG ; | ||
| + | |||
| + | ; время работы закончилось | ||
| + | POWER_OFF ; отсюда выход только через RESET | ||
| + | CLRF T1CON ; очистить TIMER1 control register, выключаем | ||
| + | ; генератор 32768 | ||
| + | ;BCF T1CON,TMR1ON ; TMR1 OFF | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | |||
| + | ; после сброса считаем, что это сброс по питанию | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BCF PCON,POR ; устанавливаем POR=0 | ||
| + | BCF PCON,BOR ; устанавливаем BOR=0 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | TO_SLEEP ; | ||
| + | CLRF PORTA | ||
| + | SLEEP | ||
| + | NOP | ||
| + | GOTO SEND_MSG | ||
| + | ;======================================================================== | ||
| + | ; индикатор включенной задержки | ||
| + | ; мигаем порт A.1 | ||
| + | FLASH | ||
| + | MOVLW D'60' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | BSF PORTA,1 | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; пауза в 1 точку | ||
| + | CALL SEND_SPACE ; | ||
| + | BCF PORTA,1 | ||
| + | GOTO TO_SLEEP | ||
| + | ;======================================================================== | ||
| + | ; SEND_CHAR | ||
| + | ; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает | ||
| + | ; его, и, в зависимости от состояния бита, передает: тире, если бит = 1; | ||
| + | ; точку, если бит = 0. | ||
| + | ; Знак передается, пока в слове есть хоть одна единица. Последняя единица | ||
| + | ; "съедается", она означает конец слова. | ||
| + | ; | ||
| + | SEND_CHAR | ||
| + | MOVLW 0X00 ; пауза? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ ; | ||
| + | GOTO WORD_SPACE | ||
| + | |||
| + | SEND_ONE_CHAR | ||
| + | BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен | ||
| + | RETURN | ||
| + | |||
| + | CLRC ; очистить бит переноса | ||
| + | RRF CW_CHAR, F ; сдвиг вправо через перенос | ||
| + | ; | ||
| + | MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0" | ||
| + | SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем | ||
| + | GOTO PAUSE2 ; конец буквы | ||
| + | SKPC ; проверить бит переноса, пропустить, если=1 | ||
| + | GOTO SEND_A_DIT ; перейти к SEND_A_DIT | ||
| + | |||
| + | SEND_A_DAH ; передаем тире | ||
| + | MOVLW 0X03 ; 1 тире = 3 точки | ||
| + | MOVWF NBR_DIT | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; после тире - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генериуем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | SEND_A_DIT | ||
| + | MOVLW 0X01 ; передаем точку | ||
| + | MOVWF NBR_DIT | ||
| + | MOVWF NBR_SPACE ; после точки - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генерируем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | PAUSE2 | ||
| + | MOVLW D'2' ; пауза в 2 точки после буквы | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | WORD_SPACE | ||
| + | MOVLW D'6' ; пауза в 6 точек между словами | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | ;================================================================== | ||
| + | ; SEND_TONE | ||
| + | ; Подпрограмма осуществляет задержку и одновременно формирует сигнал | ||
| + | ; звуковой частоты (порт A.1) | ||
| + | ; | ||
| + | |||
| + | SEND_TONE | ||
| + | |||
| + | MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек | ||
| + | MOVWF CTR_NBR ; | ||
| + | |||
| + | DIT_LENGTH | ||
| + | MOVF CW_SPEED, W ; CW_SPEED скорость передачи | ||
| + | MOVWF CTR_DIT ; | ||
| + | |||
| + | START_CYCLE | ||
| + | BSF PORTA,1 ; A.1=1 в начале цикла | ||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE ; заносим значение в счетчик цикла задержки | ||
| + | |||
| + | HIGH_HALF | ||
| + | DECFSZ TONE, F ; считаем до нуля | ||
| + | GOTO HIGH_HALF | ||
| + | BCF PORTA,1 ; A.1=0 в конце цикла | ||
| + | |||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================ | ||
| + | ; SEND_SPACE | ||
| + | ; Делает тоже самое, что и SEND_TONE, только вместо команд управления | ||
| + | ; портами стоит команда NOP | ||
| + | ; | ||
| + | |||
| + | SEND_SPACE | ||
| + | |||
| + | MOVF NBR_SPACE, W ; | ||
| + | MOVWF CTR_NBR | ||
| + | |||
| + | DIT_LENGTH_SP | ||
| + | MOVF CW_SPEED, W ; | ||
| + | MOVWF CTR_DIT | ||
| + | |||
| + | START_CYCLE_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE ; | ||
| + | |||
| + | HIGH_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO HIGH_HALF_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF_SP | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE_SP | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH_SP ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ;================================================================== | ||
| + | ; Идентификатор | ||
| + | ORG 0x2000 ; стартовый адрес | ||
| + | |||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Слово конфигурации | ||
| + | ORG 0x2007 ; стартовый адрес | ||
| + | |||
| + | DATA 0x31E4 | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Запись в EEPROM при программировании | ||
| + | ; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк | ||
| + | ; может передавать последовательно три символа Морзе, четвертым обязательно | ||
| + | ; должен быть EOM | ||
| + | ; В последнюю адресуемую ячейку можно записать большее количество символов | ||
| + | |||
| + | ORG 0X2100 ; стартовый адрес | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x02 ; E . 00000010 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x04 ; I .. 00000100 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x08 ; S ... 00001000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x10 ; H .... 00010000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x20 ; 5 ..... 00100000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | END | ||
| + | </pre> | ||
| + | |||
| + | ===Версия прошивки 3.1, циклы 30с/120с; 60с/60с; 1м/4м=== | ||
| + | |||
| + | [[file:Mf31.HEX.zip]] | ||
| + | |||
| + | <pre> | ||
| + | ;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, MOT, T). Вариант кода задается переключателем. | ||
| + | ;-Может работать непрерывно или циклом: 30с/120с; 60с/60с; 1м/4м. | ||
| + | ;-Есть выход 1000 Гц для модуляции маяка на 144 МГц. | ||
| + | ;-Автоотключение через 8 часов. | ||
| + | ;-Потребление в выключенном состоянии 0.08 ма, во время работы, при передаче позывного, 0.5 ма. | ||
| + | ;-Уход часов определяется кварцем. | ||
| + | ;-Код с переключателя считывается один раз после сброса. | ||
| + | ;-Режим отложенного старта (ОС), задержка 60 минут | ||
| + | ;-Ускорение передачи позывного за 10 сек до конца цикла (только для 5 мин цикла) | ||
| + | ;-Питание от 3 до 5 вольт | ||
| + | ; | ||
| + | ; PIC16F630 | ||
| + | ; WDT off, intLC, MCLR on, BOR on, PWRTE on | ||
| + | ; | ||
| + | list P=16F630 | ||
| + | radix HEX | ||
| + | |||
| + | ;==================================================================== | ||
| + | ; именование пользовательских регистров | ||
| + | ; | ||
| + | CBLOCK 0X20 ; начальный адрес пользовательских регистров | ||
| + | TMPW ; временный регистр для хранения W во время прерывания | ||
| + | TMPS ; временный регистр для хранения STATUS | ||
| + | SEC_CNT ; счетчик пар секунд | ||
| + | MIN_CNT ; счетчик минут (пятиминуток, автовыключение) | ||
| + | FLAG ; регистр флагов: | ||
| + | ; FLAG,0 разрешает передачу позывного в свое время | ||
| + | ; FLAG,2 флаг задержки включения (1-можно работать) | ||
| + | ; FLAG,3 флаг взводится через 5 мин после начала работы | ||
| + | ; и отменяет задержку включения при сбросе | ||
| + | ; FLAG,4 флаг устанавливается за 10 сек до конца цикла | ||
| + | |||
| + | |||
| + | DELAY ; счетчик пятиминуток, задержка включения | ||
| + | TX_ALL_CNT ; счетчик пар секунд в цикле | ||
| + | TX_OFF ; с какой секунды пауза | ||
| + | TX_ALL ; сколько пар секунд в цикле | ||
| + | |||
| + | SWITCH ; состояние переключателя | ||
| + | CHAR_INDEX ; номер передаваемого символа | ||
| + | |||
| + | CW_SPEED ; скорость передачи | ||
| + | |||
| + | ; процедура SEND_TONE | ||
| + | NBR_DIT ; NBR_DIT кол-во пропускаемых точек | ||
| + | CTR_NBR ; счетчик пропускаемых точек | ||
| + | TONE ; счетчик частоты | ||
| + | SET_TONE ; установка тона передаваемого сигнала | ||
| + | ; процедура SEND_SPACE | ||
| + | NBR_SPACE ; колво пропускаемых точек | ||
| + | CTR_DIT ; счетчик пропускаемых точек | ||
| + | ; процедура SEND_ONE_CHAR | ||
| + | CW_CHAR ; передаваемый символ | ||
| + | ENDC | ||
| + | |||
| + | |||
| + | ; | ||
| + | ; Именование регистров микроконтроллера | ||
| + | ; | ||
| + | CMCON EQU 0X19 ; регистр контроля компаратора | ||
| + | TMR0 EQU 0X01 ; timer0 | ||
| + | TMR1L EQU 0X0E ; timer1 младший байт | ||
| + | TMR1H EQU 0X0F ; timer1 старший байт | ||
| + | T1CON EQU 0X10 ; timer1 control register | ||
| + | PCL EQU 0X02 ; программный счетчик | ||
| + | STATUS EQU 0X03 ; регистр status | ||
| + | FSR EQU 0X04 ; указатель адреса в памяти данных | ||
| + | PORTA EQU 0X05 ; порт A | ||
| + | PORTC EQU 0X07 ; порт C | ||
| + | PCLATH EQU 0X0A ; верхние 5 бит программного счетчика | ||
| + | INTCON EQU 0X0B ; регистр контроля прерываний | ||
| + | TRISA EQU 0X85 ; управляющий регистр порта A | ||
| + | TRISC EQU 0X87 ; управляющий регистр порта C | ||
| + | OPTION_REG EQU 0X81 ; регистр option | ||
| + | EEADR EQU 0X9B ; адресный регистр EEPROM | ||
| + | EECON1 EQU 0X9C ; содержит бит RD | ||
| + | EEDAT EQU 0X9A ; прочитанные из EEPROM данные | ||
| + | PCON EQU 0X8E ; регистр power control | ||
| + | PIE1 EQU 0X8C ; регистр контроля периферийных прерываний | ||
| + | PIR1 EQU 0X0C ; регистр флагов прерываний от | ||
| + | ; периферийных модулей | ||
| + | |||
| + | ; | ||
| + | ; присвоение значений символьным константам | ||
| + | ; | ||
| + | RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS | ||
| + | W EQU 0X00 ; file register designator = W | ||
| + | F EQU 0X01 ; file register designator = F | ||
| + | Z EQU 0X02 ; бит нуля в STATUS | ||
| + | C EQU 0X00 ; бит преноса в STATUS | ||
| + | RD EQU 0X00 ; инициализация чтения EEPROM | ||
| + | POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был | ||
| + | ; сброс по включению питания | ||
| + | BOR EQU 0X00 ; сброс по снижению питания | ||
| + | TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1 | ||
| + | TMR1ON EQU 0X00 ; | ||
| + | GIE EQU 0X07 ; | ||
| + | TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1 | ||
| + | PON EQU 0X00 ; POWER ON IN FLAG | ||
| + | ; | ||
| + | ;================================================================= | ||
| + | ; vector table | ||
| + | ; | ||
| + | ORG 0X000 ; стартовый адрес | ||
| + | GOTO START ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ; TIMER1 INTERRUPT | ||
| + | ; | ||
| + | ORG 0X004 ; адрес прерывания | ||
| + | MOVWF TMPW ; сохраняем W | ||
| + | SWAPF STATUS,W | ||
| + | MOVWF TMPS ; сохраняем STATUS | ||
| + | |||
| + | BTFSC PIR1,0 ; прерывание от TMR1? | ||
| + | GOTO T1_INT ; да | ||
| + | NOP ; обработчик левого прерывания | ||
| + | GOTO END_ISR ; | ||
| + | |||
| + | T1_INT | ||
| + | MOVF TX_ALL_CNT,W ; вычитание | ||
| + | SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT | ||
| + | |||
| + | BCF FLAG,0 ; | ||
| + | SKPC ; пропустить, если результат >=0 | ||
| + | BSF FLAG,0 ; | ||
| + | |||
| + | |||
| + | MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла | ||
| + | SUBLW D'125' ; ставим флаг, по которому во время передачи | ||
| + | SKPNZ ; меняем скорость | ||
| + | BSF FLAG,4 ; только при 5 мин цикле | ||
| + | |||
| + | ; использовать либо верхнее, либо нижнее | ||
| + | |||
| + | ;SUBLW D'250' ; а это костыль для ускорения за 10 сек | ||
| + | ;SKPNZ ; до конца любого цикла, даже если | ||
| + | ;BSF FLAG,4 ; работаем непрерывно | ||
| + | |||
| + | DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0 | ||
| + | GOTO POP_TX | ||
| + | MOVF TX_ALL,W ; восстанавливаем | ||
| + | MOVWF TX_ALL_CNT ; | ||
| + | |||
| + | BCF FLAG,4 ; в конце цикла сбросить флаг ускорения | ||
| + | POP_TX | ||
| + | |||
| + | DECFSZ SEC_CNT, F ; SEC_CNT-1 | ||
| + | GOTO POP ; | ||
| + | MOVLW D'150' ; 300 секунд = 5 мин | ||
| + | MOVWF SEC_CNT | ||
| + | |||
| + | BTFSS FLAG,2 ; если задержка активирована, то | ||
| + | BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг | ||
| + | ; отмены задержки включения | ||
| + | |||
| + | DECF MIN_CNT,F ; MIN_CNT-1 | ||
| + | DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0 | ||
| + | GOTO POP | ||
| + | BSF FLAG,2 ; устанавливаем флаг разрешения работы | ||
| + | |||
| + | POP | ||
| + | BCF PIR1,0 ; сброс флага переполнения | ||
| + | |||
| + | END_ISR | ||
| + | SWAPF TMPS,W ; восстанавливаем регистры W and SATUS | ||
| + | MOVWF STATUS ; | ||
| + | SWAPF TMPW,F ; | ||
| + | SWAPF TMPW,W ; | ||
| + | RETFIE ; возврат из прерывания | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Начало основной программы | ||
| + | ;================================================================== | ||
| + | START | ||
| + | MOVLW B'10001110' ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF OPTION_REG ; инициализация регистра option | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF PORTA ; очистка порта A | ||
| + | CLRF PORTC ; очистка порта C | ||
| + | |||
| + | MOVLW B'00000111' ; | ||
| + | MOVWF CMCON ; запрещаем работу компаратора | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVLW B'00000000' ; | ||
| + | MOVWF TRISA ; порт A - все выходы | ||
| + | MOVLW B'11111111' ; | ||
| + | MOVWF TRISC ; порт C - все входы | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF TMR0 ; на всякий случай. Говорят, надо... | ||
| + | CLRWDT ; сбрасываем WDT | ||
| + | |||
| + | BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы, | ||
| + | ; подключенные к переключателю | ||
| + | ; после считывания напряжение с переключателя | ||
| + | ; снимается для экономии энергии | ||
| + | |||
| + | ;================================================================== | ||
| + | ; инициализация TMR1 | ||
| + | ; | ||
| + | CLRF T1CON ; очистить TIMER1 control register | ||
| + | CLRF TMR1H ; очистить верхний байт TMR1 | ||
| + | CLRF TMR1L ; очистить нижний байт TMR1 | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | CLRF PIE1 ; очистить рег контроля периферийных прерываний | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | CLRF PIR1 ; очистить рег флагов периферийных прерываний | ||
| + | MOVLW B'00001110' ; инициализация TIMER1 control register | ||
| + | MOVWF T1CON ; с этого момента генератор 32.768 включен | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | |||
| + | MOVLW D'150' ; инициализация счетчика пар секунд | ||
| + | MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин | ||
| + | DECF SEC_CNT,F ; имитируем прерывание | ||
| + | |||
| + | ;MOVLW D'2' ; сколько пятиминуток будем работать | ||
| + | MOVLW D'96' ; сколько пятиминуток будем работать | ||
| + | MOVWF MIN_CNT ; 96х5=8 час | ||
| + | |||
| + | ; MOVLW D'2' ; сколько пятиминуток задержка включения | ||
| + | MOVLW D'12' ; сколько пятиминуток задержка включения | ||
| + | MOVWF DELAY ; 12х5=60 мин | ||
| + | |||
| + | MOVLW D'178' ; тон звука, 178 ~ 1000 Гц | ||
| + | MOVWF SET_TONE ; чем больше, тем ниже частота | ||
| + | |||
| + | BSF FLAG,0 ; поднимаем флаг | ||
| + | |||
| + | BCF FLAG,4 | ||
| + | |||
;================================================================== | ;================================================================== | ||
| Строка 293: | Строка 902: | ||
BCF FLAG,3 ; при первом включении очистить FLAG,3 | BCF FLAG,3 ; при первом включении очистить FLAG,3 | ||
| − | ; инициализация TMR1 | + | ; задержка |
| + | MOVLW D'255' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | MOVLW 0X80 | ||
| + | MOVWF CW_CHAR ; | ||
| + | CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BSF PCON,POR ; устанавливаем POR=1 | ||
| + | BSF PCON,BOR ; устанавливаем BOR=1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | SLEEP ; ожидаем запуск | ||
| + | |||
| + | SKIP_DELAY | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; читаем переключатель | ||
| + | ; | ||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00011100' ; маска | ||
| + | MOVWF SWITCH ; сохраняем состояние переключателя | ||
| + | |||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00000011' ; маска двух младших бит | ||
| + | |||
| + | BCF FLAG,2 ; обнуляем флаг задержки | ||
| + | BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след. | ||
| + | BSF FLAG,2 ; устанавливаем флаг, можно работать | ||
| + | |||
| + | BCF PORTA,2 ; отключаем подтягивающие резисторы | ||
| + | |||
| + | ADDWF PCL,F ; таблица | ||
| + | GOTO SW00 | ||
| + | GOTO SW01 | ||
| + | GOTO SW10 | ||
| + | GOTO SW11 | ||
| + | SW00 ; непрерывно | ||
| + | MOVLW D'0' ; молчим последние 0 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'30' ; цикл 60 сек | ||
| + | GOTO END_SW | ||
| + | SW01 ; цикл 30сек/120сек | ||
| + | MOVLW D'60' ; молчим последние 120 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'75' ; цикл 150 сек | ||
| + | GOTO END_SW | ||
| + | SW10 ; цикл 1 мин/1 мин | ||
| + | MOVLW D'30' ; молчим последние 60 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'60' ; цикл 120 сек | ||
| + | GOTO END_SW | ||
| + | SW11 ; цикл 1 мин/4 мин | ||
| + | MOVLW D'120' ; молчим последние 4 m | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'150' ; цикл 5 m | ||
| + | |||
| + | END_SW | ||
| + | MOVWF TX_ALL ; | ||
| + | MOVWF TX_ALL_CNT ; инициализация | ||
| + | DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Окончание инициализации TIMER1 | ||
| + | ; | ||
| + | |||
| + | MOVLW B'11000000' ; разрешить прерывания от периферийных модулей | ||
| + | MOVWF INTCON | ||
| + | |||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | BSF PIE1,TMR1IE ; разрешить прерывания от TMR1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF T1CON,TMR1ON ; TMR1 ON | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; Если с момента запуска прошло 5 мин, то при сбросе задержку | ||
| + | ; включения игнорируем | ||
| + | |||
| + | BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала | ||
| + | ; работы | ||
| + | BSF FLAG,2 ; задержка включения не нужна | ||
| + | |||
| + | ;================================================================== | ||
| + | ; MAIN | ||
| + | ; передача последовательности символов | ||
| + | ; можно предавать любое количество, 0XFF означает конец последовательности, | ||
| + | ; после чего формируется пауза и передача циклически повторяется | ||
| + | ; | ||
| + | SEND_MSG | ||
| + | ; если автоотключение не нужно, то три | ||
| + | ; нижеследующих строчки надо закомментировать | ||
| + | MOVF MIN_CNT,F ; проверяем, не обнулился ли | ||
| + | SKPNZ ; счетчик пятиминуток | ||
| + | GOTO POWER_OFF ; если да, то выключаемся | ||
| + | |||
| + | BTFSS FLAG,2 ; пропустить след, если задержка включения | ||
| + | ; кончилась (1-разрешение работы) | ||
| + | GOTO FLASH ; мигнуть и sleep | ||
| + | |||
| + | BTFSS FLAG,0 ; если флаг сброшен, то идем спать | ||
| + | GOTO TO_SLEEP | ||
| + | |||
| + | MOVF SWITCH,W | ||
| + | MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX | ||
| + | |||
| + | GET_MSG | ||
| + | MOVF CHAR_INDEX,W | ||
| + | BCF INTCON,GIE ; запрещаем прерывания | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM | ||
| + | BSF EECON1,RD ; разрешаем чтение EEPROM | ||
| + | MOVF EEDAT,W ; значение ячейки -> регистр W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF INTCON,GIE ; разрешаем прерывания | ||
| + | ;MOVLW 0x06 | ||
| + | MOVWF CW_CHAR ; W -> CW_CHAR | ||
| + | |||
| + | MOVLW 0XFF ; конец сообщения? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ | ||
| + | GOTO END_MSG ; да, перейти к END_MSG | ||
| + | |||
| + | MOVLW D'60' ; скорость передачи быстро | ||
| + | BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла | ||
| + | MOVLW D'160' ; скорость передачи медленно | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | CALL SEND_CHAR ; передаем букву и паузу в 3 точки | ||
| + | ; или паузу 6 точек, если SPACE | ||
| + | INCF CHAR_INDEX ; CHAR_INDEX+1 | ||
| + | GOTO GET_MSG | ||
| + | |||
| + | END_MSG | ||
| + | CALL WORD_SPACE ; пауза 6 точек | ||
| + | GOTO SEND_MSG ; | ||
| + | |||
| + | ; время работы закончилось | ||
| + | POWER_OFF ; отсюда выход только через RESET | ||
| + | CLRF T1CON ; очистить TIMER1 control register, выключаем | ||
| + | ; генератор 32768 | ||
| + | ;BCF T1CON,TMR1ON ; TMR1 OFF | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | |||
| + | ; после сброса считаем, что это сброс по питанию | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BCF PCON,POR ; устанавливаем POR=0 | ||
| + | BCF PCON,BOR ; устанавливаем BOR=0 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | TO_SLEEP ; | ||
| + | CLRF PORTA | ||
| + | SLEEP | ||
| + | NOP | ||
| + | GOTO SEND_MSG | ||
| + | ;======================================================================== | ||
| + | ; индикатор включенной задержки | ||
| + | ; мигаем порт A.1 | ||
| + | FLASH | ||
| + | MOVLW D'60' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | BSF PORTA,1 | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; пауза в 1 точку | ||
| + | CALL SEND_SPACE ; | ||
| + | BCF PORTA,1 | ||
| + | GOTO TO_SLEEP | ||
| + | ;======================================================================== | ||
| + | ; SEND_CHAR | ||
| + | ; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает | ||
| + | ; его, и, в зависимости от состояния бита, передает: тире, если бит = 1; | ||
| + | ; точку, если бит = 0. | ||
| + | ; Знак передается, пока в слове есть хоть одна единица. Последняя единица | ||
| + | ; "съедается", она означает конец слова. | ||
| + | ; | ||
| + | SEND_CHAR | ||
| + | MOVLW 0X00 ; пауза? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ ; | ||
| + | GOTO WORD_SPACE | ||
| + | |||
| + | SEND_ONE_CHAR | ||
| + | BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен | ||
| + | RETURN | ||
| + | |||
| + | CLRC ; очистить бит переноса | ||
| + | RRF CW_CHAR, F ; сдвиг вправо через перенос | ||
| + | ; | ||
| + | MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0" | ||
| + | SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем | ||
| + | GOTO PAUSE2 ; конец буквы | ||
| + | SKPC ; проверить бит переноса, пропустить, если=1 | ||
| + | GOTO SEND_A_DIT ; перейти к SEND_A_DIT | ||
| + | |||
| + | SEND_A_DAH ; передаем тире | ||
| + | MOVLW 0X03 ; 1 тире = 3 точки | ||
| + | MOVWF NBR_DIT | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; после тире - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генериуем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | SEND_A_DIT | ||
| + | MOVLW 0X01 ; передаем точку | ||
| + | MOVWF NBR_DIT | ||
| + | MOVWF NBR_SPACE ; после точки - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генерируем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | PAUSE2 | ||
| + | MOVLW D'2' ; пауза в 2 точки после буквы | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | WORD_SPACE | ||
| + | MOVLW D'6' ; пауза в 6 точек между словами | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | ;================================================================== | ||
| + | ; SEND_TONE | ||
| + | ; Подпрограмма осуществляет задержку и одновременно формирует сигнал | ||
| + | ; звуковой частоты (порт A.1) | ||
| + | ; | ||
| + | |||
| + | SEND_TONE | ||
| + | |||
| + | MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек | ||
| + | MOVWF CTR_NBR ; | ||
| + | |||
| + | DIT_LENGTH | ||
| + | MOVF CW_SPEED, W ; CW_SPEED скорость передачи | ||
| + | MOVWF CTR_DIT ; | ||
| + | |||
| + | START_CYCLE | ||
| + | BSF PORTA,1 ; A.1=1 в начале цикла | ||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE ; заносим значение в счетчик цикла задержки | ||
| + | |||
| + | HIGH_HALF | ||
| + | DECFSZ TONE, F ; считаем до нуля | ||
| + | GOTO HIGH_HALF | ||
| + | BCF PORTA,1 ; A.1=0 в конце цикла | ||
| + | |||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================ | ||
| + | ; SEND_SPACE | ||
| + | ; Делает тоже самое, что и SEND_TONE, только вместо команд управления | ||
| + | ; портами стоит команда NOP | ||
| + | ; | ||
| + | |||
| + | SEND_SPACE | ||
| + | |||
| + | MOVF NBR_SPACE, W ; | ||
| + | MOVWF CTR_NBR | ||
| + | |||
| + | DIT_LENGTH_SP | ||
| + | MOVF CW_SPEED, W ; | ||
| + | MOVWF CTR_DIT | ||
| + | |||
| + | START_CYCLE_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE ; | ||
| + | |||
| + | HIGH_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO HIGH_HALF_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF_SP | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE_SP | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH_SP ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ;================================================================== | ||
| + | ; Идентификатор | ||
| + | ORG 0x2000 ; стартовый адрес | ||
| + | |||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Слово конфигурации | ||
| + | ORG 0x2007 ; стартовый адрес | ||
| + | |||
| + | DATA 0x31E4 | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Запись в EEPROM при программировании | ||
| + | ; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк | ||
| + | ; может передавать последовательно три символа Морзе, четвертым обязательно | ||
| + | ; должен быть EOM | ||
| + | ; В последнюю адресуемую ячейку можно записать большее количество символов | ||
| + | |||
| + | ORG 0X2100 ; стартовый адрес | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x02 ; E . 00000010 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x04 ; I .. 00000100 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x08 ; S ... 00001000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x10 ; H .... 00010000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x20 ; 5 ..... 00100000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | END | ||
| + | </pre> | ||
| + | |||
| + | ===Версия прошивки 3.2, циклы 30с/120с; 60с/60с; 1м/4м=== | ||
| + | <pre> | ||
| + | |||
| + | ;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, RA1AMO). Вариант кода задается переключателем. | ||
| + | ;-Может работать непрерывно или циклом: 30с/120с; 60с/60с; 1м/4м. | ||
| + | ;-Есть выход 1000 Гц для модуляции маяка на 144 МГц. | ||
| + | ;-Автоотключение через 8 часов, без учета ОС. | ||
| + | ;-Потребление в выключенном состоянии менее 0.08 ма, во время работы, при передаче позывного, 0.5 ма. | ||
| + | ;-Уход часов определяется кварцем. | ||
| + | ;-Код с переключателя считывается один раз после сброса. | ||
| + | ;-Режим отложенного старта (ОС), задержка 120 минут | ||
| + | ;-Питание от 3 до 5 вольт | ||
| + | ; | ||
| + | ; PIC16F630 | ||
| + | ; WDT off, intLC, MCLR on, BOR on, PWRTE on | ||
| + | ; | ||
| + | list P=16F630 | ||
| + | radix HEX | ||
| + | |||
| + | ;==================================================================== | ||
| + | ; именование пользовательских регистров | ||
| + | ; | ||
| + | CBLOCK 0X20 ; начальный адрес пользовательских регистров | ||
| + | TMPW ; временный регистр для хранения W во время прерывания | ||
| + | TMPS ; временный регистр для хранения STATUS | ||
| + | SEC_CNT ; счетчик пар секунд | ||
| + | MIN_CNT ; счетчик минут (пятиминуток, автовыключение) | ||
| + | FLAG ; регистр флагов: | ||
| + | ; FLAG,0 разрешает передачу позывного в свое время | ||
| + | ; FLAG,2 флаг задержки включения (1-можно работать) | ||
| + | ; FLAG,3 флаг взводится через 5 мин после начала работы | ||
| + | ; и отменяет задержку включения при сбросе | ||
| + | ; FLAG,4 флаг устанавливается за 10 сек до конца цикла | ||
| + | |||
| + | |||
| + | DELAY ; счетчик пятиминуток, задержка включения | ||
| + | TX_ALL_CNT ; счетчик пар секунд в цикле | ||
| + | TX_OFF ; с какой секунды пауза | ||
| + | TX_ALL ; сколько пар секунд в цикле | ||
| + | |||
| + | SWITCH ; состояние переключателя | ||
| + | CHAR_INDEX ; номер передаваемого символа | ||
| + | |||
| + | CW_SPEED ; скорость передачи | ||
| + | |||
| + | ; процедура SEND_TONE | ||
| + | NBR_DIT ; NBR_DIT кол-во пропускаемых точек | ||
| + | CTR_NBR ; счетчик пропускаемых точек | ||
| + | TONE ; счетчик частоты | ||
| + | SET_TONE ; установка тона передаваемого сигнала | ||
| + | ; процедура SEND_SPACE | ||
| + | NBR_SPACE ; колво пропускаемых точек | ||
| + | CTR_DIT ; счетчик пропускаемых точек | ||
| + | ; процедура SEND_ONE_CHAR | ||
| + | CW_CHAR ; передаваемый символ | ||
| + | ENDC | ||
| + | |||
| + | |||
| + | ; | ||
| + | ; Именование регистров микроконтроллера | ||
| + | ; | ||
| + | CMCON EQU 0X19 ; регистр контроля компаратора | ||
| + | TMR0 EQU 0X01 ; timer0 | ||
| + | TMR1L EQU 0X0E ; timer1 младший байт | ||
| + | TMR1H EQU 0X0F ; timer1 старший байт | ||
| + | T1CON EQU 0X10 ; timer1 control register | ||
| + | PCL EQU 0X02 ; программный счетчик | ||
| + | STATUS EQU 0X03 ; регистр status | ||
| + | FSR EQU 0X04 ; указатель адреса в памяти данных | ||
| + | PORTA EQU 0X05 ; порт A | ||
| + | PORTC EQU 0X07 ; порт C | ||
| + | PCLATH EQU 0X0A ; верхние 5 бит программного счетчика | ||
| + | INTCON EQU 0X0B ; регистр контроля прерываний | ||
| + | TRISA EQU 0X85 ; управляющий регистр порта A | ||
| + | TRISC EQU 0X87 ; управляющий регистр порта C | ||
| + | OPTION_REG EQU 0X81 ; регистр option | ||
| + | EEADR EQU 0X9B ; адресный регистр EEPROM | ||
| + | EECON1 EQU 0X9C ; содержит бит RD | ||
| + | EEDAT EQU 0X9A ; прочитанные из EEPROM данные | ||
| + | PCON EQU 0X8E ; регистр power control | ||
| + | PIE1 EQU 0X8C ; регистр контроля периферийных прерываний | ||
| + | PIR1 EQU 0X0C ; регистр флагов прерываний от | ||
| + | ; периферийных модулей | ||
| + | |||
| + | ; | ||
| + | ; присвоение значений символьным константам | ||
| + | ; | ||
| + | RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS | ||
| + | W EQU 0X00 ; file register designator = W | ||
| + | F EQU 0X01 ; file register designator = F | ||
| + | Z EQU 0X02 ; бит нуля в STATUS | ||
| + | C EQU 0X00 ; бит преноса в STATUS | ||
| + | RD EQU 0X00 ; инициализация чтения EEPROM | ||
| + | POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был | ||
| + | ; сброс по включению питания | ||
| + | BOR EQU 0X00 ; сброс по снижению питания | ||
| + | TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1 | ||
| + | TMR1ON EQU 0X00 ; | ||
| + | GIE EQU 0X07 ; | ||
| + | TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1 | ||
| + | PON EQU 0X00 ; POWER ON IN FLAG | ||
| + | ; | ||
| + | ;================================================================= | ||
| + | ; vector table | ||
| + | ; | ||
| + | ORG 0X000 ; стартовый адрес | ||
| + | GOTO START ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ; TIMER1 INTERRUPT | ||
| + | ; | ||
| + | ORG 0X004 ; адрес прерывания | ||
| + | MOVWF TMPW ; сохраняем W | ||
| + | SWAPF STATUS,W | ||
| + | MOVWF TMPS ; сохраняем STATUS | ||
| + | |||
| + | BTFSC PIR1,0 ; прерывание от TMR1? | ||
| + | GOTO T1_INT ; да | ||
| + | NOP ; обработчик левого прерывания | ||
| + | GOTO END_ISR ; | ||
| + | |||
| + | T1_INT | ||
| + | MOVF TX_ALL_CNT,W ; вычитание | ||
| + | SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT | ||
| + | |||
| + | BCF FLAG,0 ; | ||
| + | SKPC ; пропустить, если результат >=0 | ||
| + | BSF FLAG,0 ; | ||
| + | |||
| + | |||
| + | ; MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла | ||
| + | ; SUBLW D'125' ; ставим флаг, по которому во время передачи | ||
| + | ; SKPNZ ; меняем скорость | ||
| + | ; BSF FLAG,4 ; только при 5 мин цикле | ||
| + | |||
| + | ; использовать либо верхнее, либо нижнее | ||
| + | |||
| + | ;SUBLW D'250' ; а это костыль для ускорения за 10 сек | ||
| + | ;SKPNZ ; до конца любого цикла, даже если | ||
| + | ;BSF FLAG,4 ; работаем непрерывно | ||
| + | |||
| + | DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0 | ||
| + | GOTO POP_TX | ||
| + | MOVF TX_ALL,W ; восстанавливаем | ||
| + | MOVWF TX_ALL_CNT ; | ||
| + | |||
| + | ; BCF FLAG,4 ; в конце цикла сбросить флаг ускорения | ||
| + | POP_TX | ||
| + | |||
| + | DECFSZ SEC_CNT, F ; SEC_CNT-1 | ||
| + | GOTO POP ; | ||
| + | MOVLW D'150' ; 300 секунд = 5 мин | ||
| + | MOVWF SEC_CNT | ||
| + | |||
| + | BTFSS FLAG,2 ; если задержка активирована, то | ||
| + | BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг | ||
| + | ; отмены задержки включения | ||
| + | |||
| + | BTFSC FLAG,2 ; если флаг разрешения работы установлен, начинаем отсчет | ||
| + | ; задержки отключения | ||
| + | DECF MIN_CNT,F ; MIN_CNT-1 минуты работы считаем после | ||
| + | ; окончании задержки включения | ||
| + | |||
| + | |||
| + | DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0 | ||
| + | GOTO POP ; задержка окончилась | ||
| + | BSF FLAG,2 ; устанавливаем флаг разрешения работы | ||
| + | |||
| + | |||
| + | POP | ||
| + | BCF PIR1,0 ; сброс флага переполнения | ||
| + | |||
| + | END_ISR | ||
| + | SWAPF TMPS,W ; восстанавливаем регистры W and SATUS | ||
| + | MOVWF STATUS ; | ||
| + | SWAPF TMPW,F ; | ||
| + | SWAPF TMPW,W ; | ||
| + | RETFIE ; возврат из прерывания | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Начало основной программы | ||
| + | ;================================================================== | ||
| + | START | ||
| + | MOVLW B'10001110' ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF OPTION_REG ; инициализация регистра option | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF PORTA ; очистка порта A | ||
| + | CLRF PORTC ; очистка порта C | ||
| + | |||
| + | MOVLW B'00000111' ; | ||
| + | MOVWF CMCON ; запрещаем работу компаратора | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVLW B'00000000' ; | ||
| + | MOVWF TRISA ; порт A - все выходы | ||
| + | MOVLW B'11111111' ; | ||
| + | MOVWF TRISC ; порт C - все входы | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF TMR0 ; на всякий случай. Говорят, надо... | ||
| + | CLRWDT ; сбрасываем WDT | ||
| + | |||
| + | BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы, | ||
| + | ; подключенные к переключателю | ||
| + | ; после считывания напряжение с переключателя | ||
| + | ; снимается для экономии энергии | ||
| + | |||
| + | ;================================================================== | ||
| + | ; инициализация TMR1 | ||
| + | ; | ||
CLRF T1CON ; очистить TIMER1 control register | CLRF T1CON ; очистить TIMER1 control register | ||
CLRF TMR1H ; очистить верхний байт TMR1 | CLRF TMR1H ; очистить верхний байт TMR1 | ||
| Строка 304: | Строка 1494: | ||
MOVLW B'00001110' ; инициализация TIMER1 control register | MOVLW B'00001110' ; инициализация TIMER1 control register | ||
MOVWF T1CON ; с этого момента генератор 32.768 включен | MOVWF T1CON ; с этого момента генератор 32.768 включен | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | |||
| + | MOVLW D'150' ; инициализация счетчика пар секунд | ||
| + | MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин | ||
| + | DECF SEC_CNT,F ; имитируем прерывание | ||
| + | |||
| + | ;MOVLW D'2' ; сколько пятиминуток будем работать | ||
| + | MOVLW D'96' ; сколько пятиминуток будем работать | ||
| + | MOVWF MIN_CNT ; 96х5=8 час | ||
| + | |||
| + | ; MOVLW D'2' ; сколько пятиминуток задержка включения | ||
| + | MOVLW D'24' ; сколько пятиминуток задержка включения | ||
| + | MOVWF DELAY ; 24х5=120 мин | ||
| + | |||
| + | MOVLW D'178' ; тон звука, 178 ~ 1000 Гц | ||
| + | MOVWF SET_TONE ; чем больше, тем ниже частота | ||
| + | |||
| + | BSF FLAG,0 ; поднимаем флаг | ||
| + | |||
| + | ; BCF FLAG,4 | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; если это включение питания, то выполняется задержка для | ||
| + | ; гарантированного запуска генератора 32768 и его инициализация | ||
| + | ; если другой сброс, то инициализация и задержка пропускаются | ||
| + | ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVF PCON,W ; PCON -> W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | MOVWF TMPW ; W -> TMPW | ||
| + | BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс | ||
| + | GOTO DELAY_START ; по включению - задержка однозначно нужна | ||
| + | BTFSC TMPW,BOR ; а это был сброс по снижению напр питания | ||
| + | GOTO SKIP_DELAY ; или не был... | ||
| + | |||
| + | DELAY_START | ||
| + | |||
| + | BCF FLAG,3 ; при первом включении очистить FLAG,3 | ||
; задержка | ; задержка | ||
| Строка 321: | Строка 1553: | ||
SKIP_DELAY | SKIP_DELAY | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; читаем переключатель | ||
| + | ; | ||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00011100' ; маска | ||
| + | MOVWF SWITCH ; сохраняем состояние переключателя | ||
| + | |||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00000011' ; маска двух младших бит | ||
| + | |||
| + | BCF FLAG,2 ; обнуляем флаг задержки | ||
| + | BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след. | ||
| + | BSF FLAG,2 ; устанавливаем флаг, можно работать | ||
| + | |||
| + | BCF PORTA,2 ; отключаем подтягивающие резисторы | ||
| + | |||
| + | ADDWF PCL,F ; таблица | ||
| + | GOTO SW00 | ||
| + | GOTO SW01 | ||
| + | GOTO SW10 | ||
| + | GOTO SW11 | ||
| + | SW00 ; непрерывно | ||
| + | MOVLW D'0' ; молчим последние 0 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'30' ; цикл 60 сек | ||
| + | GOTO END_SW | ||
| + | SW01 ; цикл 30сек/120сек | ||
| + | MOVLW D'60' ; молчим последние 120 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'75' ; цикл 150 сек | ||
| + | GOTO END_SW | ||
| + | SW10 ; цикл 1 мин/1 мин | ||
| + | MOVLW D'30' ; молчим последние 60 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'60' ; цикл 120 сек | ||
| + | GOTO END_SW | ||
| + | SW11 ; цикл 1 мин/4 мин | ||
| + | MOVLW D'120' ; молчим последние 4 m | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'150' ; цикл 5 m | ||
| + | |||
| + | END_SW | ||
| + | MOVWF TX_ALL ; | ||
| + | MOVWF TX_ALL_CNT ; инициализация | ||
| + | DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось | ||
;================================================================== | ;================================================================== | ||
; Окончание инициализации TIMER1 | ; Окончание инициализации TIMER1 | ||
; | ; | ||
| − | |||
| − | |||
MOVLW B'11000000' ; разрешить прерывания от периферийных модулей | MOVLW B'11000000' ; разрешить прерывания от периферийных модулей | ||
| Строка 335: | Строка 1612: | ||
BCF STATUS, RP0 ; bank 0 | BCF STATUS, RP0 ; bank 0 | ||
BSF T1CON,TMR1ON ; TMR1 ON | BSF T1CON,TMR1ON ; TMR1 ON | ||
| + | |||
;================================================================== | ;================================================================== | ||
| Строка 343: | Строка 1621: | ||
; работы | ; работы | ||
BSF FLAG,2 ; задержка включения не нужна | BSF FLAG,2 ; задержка включения не нужна | ||
| − | |||
;================================================================== | ;================================================================== | ||
| Строка 385: | Строка 1662: | ||
GOTO END_MSG ; да, перейти к END_MSG | GOTO END_MSG ; да, перейти к END_MSG | ||
| − | MOVLW D'160' ; скорость передачи | + | ; MOVLW D'60' ; скорость передачи быстро |
| + | ; BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла | ||
| + | MOVLW D'160' ; скорость передачи медленно | ||
MOVWF CW_SPEED ; чем больше, тем медленней | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| Строка 397: | Строка 1676: | ||
GOTO SEND_MSG ; | GOTO SEND_MSG ; | ||
| + | ; время работы закончилось | ||
POWER_OFF ; отсюда выход только через RESET | POWER_OFF ; отсюда выход только через RESET | ||
| − | BCF T1CON,TMR1ON | + | |
| + | CLRF FLAG ; очистка регистра флагов | ||
| + | CLRF T1CON ; очистить TIMER1 control register, выключаем | ||
| + | ; генератор 32768 | ||
| + | ;BCF T1CON,TMR1ON ; TMR1 OFF | ||
CLRF INTCON ; запретить прерывания | CLRF INTCON ; запретить прерывания | ||
| + | |||
| + | ; после сброса считаем, что это сброс по питанию | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BCF PCON,POR ; устанавливаем POR=0 | ||
| + | BCF PCON,BOR ; устанавливаем BOR=0 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
TO_SLEEP ; | TO_SLEEP ; | ||
| Строка 556: | Строка 1846: | ||
ORG 0x2000 ; стартовый адрес | ORG 0x2000 ; стартовый адрес | ||
| − | DATA | + | DATA 0x0132 |
| − | DATA | + | DATA 0xF321 |
DATA 0x0000 | DATA 0x0000 | ||
DATA 0x0000 | DATA 0x0000 | ||
| Строка 565: | Строка 1855: | ||
ORG 0x2007 ; стартовый адрес | ORG 0x2007 ; стартовый адрес | ||
| − | + | ; DATA 0x31E4 | |
| − | + | DATA 0x1024 ; вкл защиту данных | |
| + | ; DATA 0x11A4 | ||
;================================================================== | ;================================================================== | ||
; Запись в EEPROM при программировании | ; Запись в EEPROM при программировании | ||
| Строка 611: | Строка 1902: | ||
DATA 0xFF ; EOM 11111111 | DATA 0xFF ; EOM 11111111 | ||
| − | DATA | + | DATA 0x0A ; R .-. |
| + | DATA 0x06 ; A .- | ||
| + | DATA 0x3E ; 1 .---- | ||
| + | DATA 0x06 ; A .- | ||
| + | DATA 0x07 ; M -- | ||
| + | DATA 0x0F ; O --- | ||
DATA 0xFF ; EOM 11111111 | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | END | ||
| + | </pre> | ||
| + | |||
| + | ===Вариант для управления радиостанцией, 30с/120с; 60с/60с; 1м/4м, передача позывного=== | ||
| + | |||
| + | [[File:Pic_beacon_1.jpg|300px|thumb|none|Контроллер маяка на PIC16F630 в корпусе]] | ||
| + | |||
| + | [[File:Cntrl_spb_amw.gif|697px|thumb|none|Схема для управления маяком для городской охоты, возможно подключение обычной радиостанции]] | ||
| + | |||
| + | <pre> | ||
| + | ; на 11 ногу можно повесить управление TX (высокий уровень при передаче) | ||
| + | |||
| + | ; PIC16F630 | ||
| + | ; WDT off, intLC, MCLR on, BOR on, PWRTE on | ||
| + | ; | ||
| + | list P=16F630 | ||
| + | radix HEX | ||
| + | |||
| + | ;==================================================================== | ||
| + | ; именование пользовательских регистров | ||
| + | ; | ||
| + | CBLOCK 0X20 ; начальный адрес пользовательских регистров | ||
| + | TMPW ; временный регистр для хранения W во время прерывания | ||
| + | TMPS ; временный регистр для хранения STATUS | ||
| + | SEC_CNT ; счетчик пар секунд | ||
| + | MIN_CNT ; счетчик минут (пятиминуток, автовыключение) | ||
| + | FLAG ; регистр флагов: | ||
| + | ; FLAG,0 разрешает передачу позывного в свое время | ||
| + | ; FLAG,2 флаг задержки включения (1-можно работать) | ||
| + | ; FLAG,3 флаг взводится через 5 мин после начала работы | ||
| + | ; и отменяет задержку включения при сбросе | ||
| + | ; FLAG,4 флаг устанавливается за 10 сек до конца цикла | ||
| + | |||
| + | |||
| + | DELAY ; счетчик пятиминуток, задержка включения | ||
| + | TX_ALL_CNT ; счетчик пар секунд в цикле | ||
| + | TX_OFF ; с какой секунды пауза | ||
| + | TX_ALL ; сколько пар секунд в цикле | ||
| + | |||
| + | SWITCH ; состояние переключателя | ||
| + | CHAR_INDEX ; номер передаваемого символа | ||
| + | |||
| + | CW_SPEED ; скорость передачи | ||
| + | |||
| + | ; процедура SEND_TONE | ||
| + | NBR_DIT ; NBR_DIT кол-во пропускаемых точек | ||
| + | CTR_NBR ; счетчик пропускаемых точек | ||
| + | TONE ; счетчик частоты | ||
| + | SET_TONE ; установка тона передаваемого сигнала | ||
| + | ; процедура SEND_SPACE | ||
| + | NBR_SPACE ; колво пропускаемых точек | ||
| + | CTR_DIT ; счетчик пропускаемых точек | ||
| + | ; процедура SEND_ONE_CHAR | ||
| + | CW_CHAR ; передаваемый символ | ||
| + | ENDC | ||
| + | |||
| + | |||
| + | ; | ||
| + | ; Именование регистров микроконтроллера | ||
| + | ; | ||
| + | CMCON EQU 0X19 ; регистр контроля компаратора | ||
| + | TMR0 EQU 0X01 ; timer0 | ||
| + | TMR1L EQU 0X0E ; timer1 младший байт | ||
| + | TMR1H EQU 0X0F ; timer1 старший байт | ||
| + | T1CON EQU 0X10 ; timer1 control register | ||
| + | PCL EQU 0X02 ; программный счетчик | ||
| + | STATUS EQU 0X03 ; регистр status | ||
| + | FSR EQU 0X04 ; указатель адреса в памяти данных | ||
| + | PORTA EQU 0X05 ; порт A | ||
| + | PORTC EQU 0X07 ; порт C | ||
| + | PCLATH EQU 0X0A ; верхние 5 бит программного счетчика | ||
| + | INTCON EQU 0X0B ; регистр контроля прерываний | ||
| + | TRISA EQU 0X85 ; управляющий регистр порта A | ||
| + | TRISC EQU 0X87 ; управляющий регистр порта C | ||
| + | OPTION_REG EQU 0X81 ; регистр option | ||
| + | EEADR EQU 0X9B ; адресный регистр EEPROM | ||
| + | EECON1 EQU 0X9C ; содержит бит RD | ||
| + | EEDAT EQU 0X9A ; прочитанные из EEPROM данные | ||
| + | PCON EQU 0X8E ; регистр power control | ||
| + | PIE1 EQU 0X8C ; регистр контроля периферийных прерываний | ||
| + | PIR1 EQU 0X0C ; регистр флагов прерываний от | ||
| + | ; периферийных модулей | ||
| + | |||
| + | ; | ||
| + | ; присвоение значений символьным константам | ||
| + | ; | ||
| + | RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS | ||
| + | W EQU 0X00 ; file register designator = W | ||
| + | F EQU 0X01 ; file register designator = F | ||
| + | Z EQU 0X02 ; бит нуля в STATUS | ||
| + | C EQU 0X00 ; бит преноса в STATUS | ||
| + | RD EQU 0X00 ; инициализация чтения EEPROM | ||
| + | POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был | ||
| + | ; сброс по включению питания | ||
| + | BOR EQU 0X00 ; сброс по снижению питания | ||
| + | TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1 | ||
| + | TMR1ON EQU 0X00 ; | ||
| + | GIE EQU 0X07 ; | ||
| + | TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1 | ||
| + | PON EQU 0X00 ; POWER ON IN FLAG | ||
| + | ; | ||
| + | ;================================================================= | ||
| + | ; vector table | ||
| + | ; | ||
| + | ORG 0X000 ; стартовый адрес | ||
| + | GOTO START ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ; TIMER1 INTERRUPT | ||
| + | ; | ||
| + | ORG 0X004 ; адрес прерывания | ||
| + | MOVWF TMPW ; сохраняем W | ||
| + | SWAPF STATUS,W | ||
| + | MOVWF TMPS ; сохраняем STATUS | ||
| + | |||
| + | BTFSC PIR1,0 ; прерывание от TMR1? | ||
| + | GOTO T1_INT ; да | ||
| + | NOP ; обработчик левого прерывания | ||
| + | GOTO END_ISR ; | ||
| + | |||
| + | T1_INT | ||
| + | MOVF TX_ALL_CNT,W ; вычитание | ||
| + | SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT | ||
| + | |||
| + | BCF FLAG,0 ; | ||
| + | SKPC ; пропустить, если результат >=0 | ||
| + | BSF FLAG,0 ; | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ; MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла | ||
| + | ; SUBLW D'125' ; ставим флаг, по которому во время передачи | ||
| + | ; SKPNZ ; меняем скорость | ||
| + | ; BSF FLAG,4 ; только при 5 мин цикле | ||
| + | |||
| + | ; использовать либо верхнее, либо нижнее | ||
| + | |||
| + | ;SUBLW D'250' ; а это костыль для ускорения за 10 сек | ||
| + | ;SKPNZ ; до конца любого цикла, даже если | ||
| + | ;BSF FLAG,4 ; работаем непрерывно | ||
| + | |||
| + | DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0 | ||
| + | GOTO POP_TX | ||
| + | MOVF TX_ALL,W ; восстанавливаем | ||
| + | MOVWF TX_ALL_CNT ; | ||
| + | |||
| + | ; BCF FLAG,4 ; в конце цикла сбросить флаг ускорения | ||
| + | POP_TX | ||
| + | |||
| + | DECFSZ SEC_CNT, F ; SEC_CNT-1 | ||
| + | GOTO POP ; | ||
| + | MOVLW D'150' ; 300 секунд = 5 мин | ||
| + | MOVWF SEC_CNT | ||
| + | |||
| + | BTFSS FLAG,2 ; если задержка активирована, то | ||
| + | BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг | ||
| + | ; отмены задержки включения | ||
| + | |||
| + | BTFSC FLAG,2 ; если флаг разрешения работы установлен, начинаем отсчет | ||
| + | ; задержки отключения | ||
| + | DECF MIN_CNT,F ; MIN_CNT-1 минуты работы считаем после | ||
| + | ; окончании задержки включения | ||
| + | |||
| + | |||
| + | DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0 | ||
| + | GOTO POP ; задержка окончилась | ||
| + | BSF FLAG,2 ; устанавливаем флаг разрешения работы | ||
| + | |||
| + | |||
| + | POP | ||
| + | BCF PIR1,0 ; сброс флага переполнения | ||
| + | |||
| + | END_ISR | ||
| + | SWAPF TMPS,W ; восстанавливаем регистры W and SATUS | ||
| + | MOVWF STATUS ; | ||
| + | SWAPF TMPW,F ; | ||
| + | SWAPF TMPW,W ; | ||
| + | RETFIE ; возврат из прерывания | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Начало основной программы | ||
| + | ;================================================================== | ||
| + | START | ||
| + | MOVLW B'10001110' ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF OPTION_REG ; инициализация регистра option | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF PORTA ; очистка порта A | ||
| + | CLRF PORTC ; очистка порта C | ||
| + | |||
| + | MOVLW B'00000111' ; | ||
| + | MOVWF CMCON ; запрещаем работу компаратора | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVLW B'00000000' ; | ||
| + | MOVWF TRISA ; порт A - все выходы | ||
| + | MOVLW B'11111111' ; | ||
| + | MOVWF TRISC ; порт C - все входы | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | CLRF TMR0 ; на всякий случай. Говорят, надо... | ||
| + | CLRWDT ; сбрасываем WDT | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; инициализация TMR1 | ||
| + | ; | ||
| + | CLRF T1CON ; очистить TIMER1 control register | ||
| + | CLRF TMR1H ; очистить верхний байт TMR1 | ||
| + | CLRF TMR1L ; очистить нижний байт TMR1 | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | CLRF PIE1 ; очистить рег контроля периферийных прерываний | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | CLRF PIR1 ; очистить рег флагов периферийных прерываний | ||
| + | MOVLW B'00001110' ; инициализация TIMER1 control register | ||
| + | MOVWF T1CON ; с этого момента генератор 32.768 включен | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | |||
| + | MOVLW D'150' ; инициализация счетчика пар секунд | ||
| + | MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин | ||
| + | DECF SEC_CNT,F ; имитируем прерывание | ||
| + | |||
| + | ;MOVLW D'2' ; сколько пятиминуток будем работать | ||
| + | MOVLW D'96' ; сколько пятиминуток будем работать | ||
| + | MOVWF MIN_CNT ; 96х5=8 час | ||
| + | |||
| + | ; MOVLW D'2' ; сколько пятиминуток задержка включения | ||
| + | MOVLW D'24' ; сколько пятиминуток задержка включения | ||
| + | MOVWF DELAY ; 24х5=120 мин | ||
| + | |||
| + | MOVLW D'178' ; тон звука, 178 ~ 1000 Гц | ||
| + | MOVWF SET_TONE ; чем больше, тем ниже частота | ||
| + | |||
| + | BSF FLAG,0 ; поднимаем флаг | ||
| + | |||
| + | ; BCF FLAG,4 | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; если это включение питания, то выполняется задержка для | ||
| + | ; гарантированного запуска генератора 32768 и его инициализация | ||
| + | ; если другой сброс, то инициализация и задержка пропускаются | ||
| + | ; | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVF PCON,W ; PCON -> W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | MOVWF TMPW ; W -> TMPW | ||
| + | BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс | ||
| + | GOTO DELAY_START ; по включению - задержка однозначно нужна | ||
| + | BTFSC TMPW,BOR ; а это был сброс по снижению напр питания | ||
| + | GOTO SKIP_DELAY ; или не был... | ||
| + | |||
| + | DELAY_START | ||
| + | |||
| + | BCF FLAG,3 ; при первом включении очистить FLAG,3 | ||
| + | |||
| + | ; задержка | ||
| + | MOVLW D'255' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | MOVLW 0X80 | ||
| + | MOVWF CW_CHAR ; | ||
| + | CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек | ||
| + | |||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BSF PCON,POR ; устанавливаем POR=1 | ||
| + | BSF PCON,BOR ; устанавливаем BOR=1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | SLEEP ; ожидаем запуск | ||
| + | |||
| + | SKIP_DELAY | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; читаем переключатель | ||
| + | ; | ||
| + | |||
| + | BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы, | ||
| + | ; подключенные к переключателю | ||
| + | ; после считывания напряжение с переключателя | ||
| + | ; снимается для экономии энергии | ||
| + | |||
| + | |||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00011100' ; маска | ||
| + | MOVWF SWITCH ; сохраняем состояние переключателя | ||
| + | |||
| + | MOVF PORTC,W ; читаем порт C | ||
| + | ANDLW B'00000011' ; маска двух младших бит | ||
| + | |||
| + | BCF FLAG,2 ; обнуляем флаг задержки | ||
| + | BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след. | ||
| + | BSF FLAG,2 ; устанавливаем флаг, можно работать | ||
| + | |||
| + | BCF PORTA,2 ; отключаем подтягивающие резисторы | ||
| + | |||
| + | ADDWF PCL,F ; таблица | ||
| + | GOTO SW00 | ||
| + | GOTO SW01 | ||
| + | GOTO SW10 | ||
| + | GOTO SW11 | ||
| + | SW00 ; непрерывно | ||
| + | MOVLW D'0' ; молчим последние 0 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'30' ; цикл 60 сек | ||
| + | GOTO END_SW | ||
| + | SW01 ; цикл 30сек/120сек | ||
| + | MOVLW D'60' ; молчим последние 120 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'75' ; цикл 150 сек | ||
| + | GOTO END_SW | ||
| + | SW10 ; цикл 1 мин/1 мин | ||
| + | MOVLW D'30' ; молчим последние 60 с | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'60' ; цикл 120 сек | ||
| + | GOTO END_SW | ||
| + | SW11 ; цикл 1 мин/4 мин | ||
| + | MOVLW D'120' ; молчим последние 4 m | ||
| + | MOVWF TX_OFF ; | ||
| + | MOVLW D'150' ; цикл 5 m | ||
| + | |||
| + | END_SW | ||
| + | MOVWF TX_ALL ; | ||
| + | MOVWF TX_ALL_CNT ; инициализация | ||
| + | DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Окончание инициализации TIMER1 | ||
| + | ; | ||
| + | |||
| + | MOVLW B'11000000' ; разрешить прерывания от периферийных модулей | ||
| + | MOVWF INTCON | ||
| + | |||
| + | BSF STATUS,RP0 ; bank 1 | ||
| + | BSF PIE1,TMR1IE ; разрешить прерывания от TMR1 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF T1CON,TMR1ON ; TMR1 ON | ||
| + | |||
| + | |||
| + | ;================================================================== | ||
| + | ; Если с момента запуска прошло 5 мин, то при сбросе задержку | ||
| + | ; включения игнорируем | ||
| + | |||
| + | BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала | ||
| + | ; работы | ||
| + | BSF FLAG,2 ; задержка включения не нужна | ||
| + | |||
| + | ;================================================================== | ||
| + | ; MAIN | ||
| + | ; передача последовательности символов | ||
| + | ; можно предавать любое количество, 0XFF означает конец последовательности, | ||
| + | ; после чего формируется пауза и передача циклически повторяется | ||
| + | ; | ||
| + | SEND_MSG | ||
| + | ; если автоотключение не нужно, то три | ||
| + | ; нижеследующих строчки надо закомментировать | ||
| + | MOVF MIN_CNT,F ; проверяем, не обнулился ли | ||
| + | SKPNZ ; счетчик пятиминуток | ||
| + | GOTO POWER_OFF ; если да, то выключаемся | ||
| + | |||
| + | BTFSS FLAG,2 ; пропустить след, если задержка включения | ||
| + | ; кончилась (1-разрешение работы) | ||
| + | GOTO FLASH ; мигнуть и sleep | ||
| + | |||
| + | BTFSS FLAG,0 ; если флаг сброшен | ||
| + | BSF PORTA,2 ; TX выключаем | ||
| + | |||
| + | BTFSS FLAG,0 ; если флаг сброшен, то идем спать | ||
| + | GOTO TO_SLEEP | ||
| + | |||
| + | |||
| + | BSF PORTA,2 ; на 11 ногу можно повесить управление TX | ||
| + | |||
| + | |||
| + | MOVF SWITCH,W | ||
| + | MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX | ||
| + | |||
| + | GET_MSG | ||
| + | MOVF CHAR_INDEX,W | ||
| + | BCF INTCON,GIE ; запрещаем прерывания | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM | ||
| + | BSF EECON1,RD ; разрешаем чтение EEPROM | ||
| + | MOVF EEDAT,W ; значение ячейки -> регистр W | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | BSF INTCON,GIE ; разрешаем прерывания | ||
| + | ;MOVLW 0x06 | ||
| + | MOVWF CW_CHAR ; W -> CW_CHAR | ||
| + | |||
| + | MOVLW 0XFF ; конец сообщения? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ | ||
| + | GOTO END_MSG ; да, перейти к END_MSG | ||
| + | |||
| + | ; MOVLW D'60' ; скорость передачи быстро | ||
| + | ; BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла | ||
| + | ; | ||
| + | MOVLW D'80' ; скорость передачи медленно | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | |||
| + | CALL SEND_CHAR ; передаем букву и паузу в 3 точки | ||
| + | ; или паузу 6 точек, если SPACE | ||
| + | INCF CHAR_INDEX ; CHAR_INDEX+1 | ||
| + | GOTO GET_MSG | ||
| + | |||
| + | END_MSG | ||
| + | CALL WORD_SPACE ; пауза 6 точек | ||
| + | GOTO SEND_MSG ; | ||
| + | |||
| + | ; время работы закончилось | ||
| + | POWER_OFF ; отсюда выход только через RESET | ||
| + | |||
| + | CLRF FLAG ; очистка регистра флагов | ||
| + | CLRF T1CON ; очистить TIMER1 control register, выключаем | ||
| + | ; генератор 32768 | ||
| + | ;BCF T1CON,TMR1ON ; TMR1 OFF | ||
| + | CLRF INTCON ; запретить прерывания | ||
| + | |||
| + | ; после сброса считаем, что это сброс по питанию | ||
| + | BSF STATUS, RP0 ; bank 1 | ||
| + | BCF PCON,POR ; устанавливаем POR=0 | ||
| + | BCF PCON,BOR ; устанавливаем BOR=0 | ||
| + | BCF STATUS, RP0 ; bank 0 | ||
| + | |||
| + | TO_SLEEP ; | ||
| + | CLRF PORTA | ||
| + | SLEEP | ||
| + | NOP | ||
| + | GOTO SEND_MSG | ||
| + | ;======================================================================== | ||
| + | ; индикатор включенной задержки | ||
| + | ; мигаем порт A.1 | ||
| + | FLASH | ||
| + | MOVLW D'60' ; скорость передачи | ||
| + | MOVWF CW_SPEED ; чем больше, тем медленней | ||
| + | BSF PORTA,1 | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; пауза в 1 точку | ||
| + | CALL SEND_SPACE ; | ||
| + | BCF PORTA,1 | ||
| + | GOTO TO_SLEEP | ||
| + | ;======================================================================== | ||
| + | ; SEND_CHAR | ||
| + | ; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает | ||
| + | ; его, и, в зависимости от состояния бита, передает: тире, если бит = 1; | ||
| + | ; точку, если бит = 0. | ||
| + | ; Знак передается, пока в слове есть хоть одна единица. Последняя единица | ||
| + | ; "съедается", она означает конец слова. | ||
| + | ; | ||
| + | SEND_CHAR | ||
| + | MOVLW 0X00 ; пауза? | ||
| + | SUBWF CW_CHAR,W ; | ||
| + | SKPNZ ; | ||
| + | GOTO WORD_SPACE | ||
| + | |||
| + | SEND_ONE_CHAR | ||
| + | BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен | ||
| + | RETURN | ||
| + | |||
| + | CLRC ; очистить бит переноса | ||
| + | RRF CW_CHAR, F ; сдвиг вправо через перенос | ||
| + | ; | ||
| + | MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0" | ||
| + | SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем | ||
| + | GOTO PAUSE2 ; конец буквы | ||
| + | SKPC ; проверить бит переноса, пропустить, если=1 | ||
| + | GOTO SEND_A_DIT ; перейти к SEND_A_DIT | ||
| + | |||
| + | SEND_A_DAH ; передаем тире | ||
| + | MOVLW 0X03 ; 1 тире = 3 точки | ||
| + | MOVWF NBR_DIT | ||
| + | MOVLW 0X01 ; | ||
| + | MOVWF NBR_SPACE ; после тире - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генериуем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | SEND_A_DIT | ||
| + | MOVLW 0X01 ; передаем точку | ||
| + | MOVWF NBR_DIT | ||
| + | MOVWF NBR_SPACE ; после точки - пауза в 1 точку | ||
| + | BSF PORTA,0 ; включаем PORT A.2 | ||
| + | CALL SEND_TONE ; генерируем звук, оно же - пауза | ||
| + | BCF PORTA,0 ; выключаем PORT A.2 | ||
| + | CALL SEND_SPACE | ||
| + | GOTO SEND_ONE_CHAR | ||
| + | |||
| + | PAUSE2 | ||
| + | MOVLW D'2' ; пауза в 2 точки после буквы | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | WORD_SPACE | ||
| + | MOVLW D'6' ; пауза в 6 точек между словами | ||
| + | MOVWF NBR_SPACE ; | ||
| + | CALL SEND_SPACE ; | ||
| + | RETURN | ||
| + | |||
| + | ;================================================================== | ||
| + | ; SEND_TONE | ||
| + | ; Подпрограмма осуществляет задержку и одновременно формирует сигнал | ||
| + | ; звуковой частоты (порт A.1) | ||
| + | ; | ||
| + | |||
| + | SEND_TONE | ||
| + | |||
| + | MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек | ||
| + | MOVWF CTR_NBR ; | ||
| + | |||
| + | DIT_LENGTH | ||
| + | MOVF CW_SPEED, W ; CW_SPEED скорость передачи | ||
| + | MOVWF CTR_DIT ; | ||
| + | |||
| + | START_CYCLE | ||
| + | BSF PORTA,1 ; A.1=1 в начале цикла | ||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE ; заносим значение в счетчик цикла задержки | ||
| + | |||
| + | HIGH_HALF | ||
| + | DECFSZ TONE, F ; считаем до нуля | ||
| + | GOTO HIGH_HALF | ||
| + | BCF PORTA,1 ; A.1=0 в конце цикла | ||
| + | |||
| + | MOVF SET_TONE,W ; | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================ | ||
| + | ; SEND_SPACE | ||
| + | ; Делает тоже самое, что и SEND_TONE, только вместо команд управления | ||
| + | ; портами стоит команда NOP | ||
| + | ; | ||
| + | |||
| + | SEND_SPACE | ||
| + | |||
| + | MOVF NBR_SPACE, W ; | ||
| + | MOVWF CTR_NBR | ||
| + | |||
| + | DIT_LENGTH_SP | ||
| + | MOVF CW_SPEED, W ; | ||
| + | MOVWF CTR_DIT | ||
| + | |||
| + | START_CYCLE_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE ; | ||
| + | |||
| + | HIGH_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO HIGH_HALF_SP | ||
| + | NOP | ||
| + | MOVF SET_TONE,W | ||
| + | MOVWF TONE | ||
| + | |||
| + | LOW_HALF_SP | ||
| + | DECFSZ TONE, F ; | ||
| + | GOTO LOW_HALF_SP | ||
| + | DECFSZ CTR_DIT, F ; | ||
| + | GOTO START_CYCLE_SP | ||
| + | DECFSZ CTR_NBR, F | ||
| + | GOTO DIT_LENGTH_SP ; | ||
| + | RETURN ; | ||
| + | |||
| + | ;================================================================== | ||
| + | ;================================================================== | ||
| + | ; Идентификатор | ||
| + | ORG 0x2000 ; стартовый адрес | ||
| + | |||
| + | DATA 0x0132 | ||
| + | DATA 0xF321 | ||
| + | DATA 0x0000 | ||
| + | DATA 0x0000 | ||
| + | |||
| + | ;================================================================== | ||
| + | ; Слово конфигурации | ||
| + | ORG 0x2007 ; стартовый адрес | ||
| + | |||
| + | ; DATA 0x31E4 | ||
| + | DATA 0x1024 ; вкл защиту данных | ||
| + | ; DATA 0x11A4 | ||
| + | ;================================================================== | ||
| + | ; Запись в EEPROM при программировании | ||
| + | ; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк | ||
| + | ; может передавать последовательно три символа Морзе, четвертым обязательно | ||
| + | ; должен быть EOM | ||
| + | ; В последнюю адресуемую ячейку можно записать большее количество символов | ||
| + | |||
| + | ORG 0X2100 ; стартовый адрес | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
DATA 0xFF ; EOM 11111111 | DATA 0xFF ; EOM 11111111 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x02 ; E . 00000010 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x04 ; I .. 00000100 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x08 ; S ... 00001000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x10 ; H .... 00010000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x20 ; 5 ..... 00100000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
| + | |||
| + | DATA 0x09 ; D | ||
| + | DATA 0x02 ; E | ||
| + | DATA 0x00 ; PAUSE | ||
| + | DATA 0x0A ; R .-. | ||
| + | DATA 0x06 ; A .- | ||
| + | DATA 0x3E ; 1 .---- | ||
| + | DATA 0x06 ; A .- | ||
| + | DATA 0x07 ; M -- | ||
| + | DATA 0x0E ; W --- | ||
| + | DATA 0x00 ; PAUSE | ||
| + | DATA 0x11 ; B | ||
| + | DATA 0x02 ; E | ||
| + | DATA 0x06 ; A | ||
| + | DATA 0x15 ; C | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x05 ; N | ||
DATA 0xFF ; EOM 11111111 | DATA 0xFF ; EOM 11111111 | ||
END | END | ||
| + | </pre> | ||
| + | |||
| + | ===Программирование кодов Морзе=== | ||
| + | |||
| + | <pre> | ||
| + | DATA 0x3F ; 0 ----- 00111111 | ||
| + | DATA 0x3E ; 1 .---- 00111110 | ||
| + | DATA 0x3C ; 2 ..--- 00111100 | ||
| + | DATA 0x38 ; 3 ...-- 00111000 | ||
| + | DATA 0x30 ; 4 ....- 00110000 | ||
| + | DATA 0x20 ; 5 ..... 00100000 | ||
| + | DATA 0x21 ; 6 -.... 00100001 | ||
| + | DATA 0x23 ; 7 --... 00100011 | ||
| + | DATA 0x27 ; 8 ---.. 00100111 | ||
| + | DATA 0x2F ; 9 ----. 00101111 | ||
| + | DATA 0x06 ; A .- 00000110 | ||
| + | DATA 0x11 ; B -... 00010001 | ||
| + | DATA 0x15 ; C -.-. 00010101 | ||
| + | DATA 0x09 ; D -.. 00001001 | ||
| + | DATA 0x02 ; E . 00000010 | ||
| + | DATA 0X14 ; F ..-. 00010100 | ||
| + | DATA 0X0B ; G --. 00001011 | ||
| + | DATA 0x10 ; H .... 00010000 | ||
| + | DATA 0x04 ; I .. 00000100 | ||
| + | DATA 0x1E ; J .--- 00011110 | ||
| + | DATA 0x0D ; K -.- 00001101 | ||
| + | DATA 0x12 ; L .-.. 00010010 | ||
| + | DATA 0x07 ; M -- 00000111 | ||
| + | DATA 0x05 ; N -. 00000101 | ||
| + | DATA 0x0F ; O --- 00001111 | ||
| + | DATA 0x16 ; P .--. 00010110 | ||
| + | DATA 0x1B ; Q --.- 00011011 | ||
| + | DATA 0x0A ; R .-. 00001010 | ||
| + | DATA 0x08 ; S ... 00001000 | ||
| + | DATA 0x03 ; T - 00000011 | ||
| + | DATA 0x0C ; U ..- 00001100 | ||
| + | DATA 0x18 ; V ...- 00011000 | ||
| + | DATA 0x0E ; W .-- 00001110 | ||
| + | DATA 0X19 ; X -..- 00011001 | ||
| + | DATA 0X1D ; Y -.-- 00011101 | ||
| + | DATA 0X13 ; Z --.. 00010011 | ||
| + | DATA 0x29 ; / -..-. 00101001 | ||
| + | DATA 0x00 ; PAUSE 00000000 | ||
| + | DATA 0xFF ; EOM 11111111 | ||
</pre> | </pre> | ||
Текущая версия на 12:57, 25 марта 2017
Содержание
Контроллер маяка на PIC16F630
Версия прошивки 3.0, циклы 30с/30с; 60с/60с; 1м/4м
;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, MOT, T). Вариант кода задается переключателем.
;-Может работать непрерывно или циклом: 30с/30с; 60с/60с; 1м/4м.
;-Есть выход 1000 Гц для модуляции маяка на 144 МГц.
;-Автоотключение через 8 часов.
;-Потребление в выключенном состоянии 0.08 ма, во время работы, при передаче позывного, 0.5 ма.
;-Уход часов определяется кварцем.
;-Код с переключателя считывается один раз после сброса.
;-Режим отложенного старта (ОС), задержка 120 минут
;-Ускорение передачи позывного за 10 сек до конца цикла (только для 5 мин цикла)
;-Питание от 3 до 5 вольт
;
; PIC16F630
; WDT off, intLC, MCLR on, BOR on, PWRTE on
;
list P=16F630
radix HEX
;====================================================================
; именование пользовательских регистров
;
CBLOCK 0X20 ; начальный адрес пользовательских регистров
TMPW ; временный регистр для хранения W во время прерывания
TMPS ; временный регистр для хранения STATUS
SEC_CNT ; счетчик пар секунд
MIN_CNT ; счетчик минут (пятиминуток, автовыключение)
FLAG ; регистр флагов:
; FLAG,0 разрешает передачу позывного в свое время
; FLAG,2 флаг задержки включения (1-можно работать)
; FLAG,3 флаг взводится через 5 мин после начала работы
; и отменяет задержку включения при сбросе
; FLAG,4 флаг устанавливается за 10 сек до конца цикла
DELAY ; счетчик пятиминуток, задержка включения
TX_ALL_CNT ; счетчик пар секунд в цикле
TX_OFF ; с какой секунды пауза
TX_ALL ; сколько пар секунд в цикле
SWITCH ; состояние переключателя
CHAR_INDEX ; номер передаваемого символа
CW_SPEED ; скорость передачи
; процедура SEND_TONE
NBR_DIT ; NBR_DIT кол-во пропускаемых точек
CTR_NBR ; счетчик пропускаемых точек
TONE ; счетчик частоты
SET_TONE ; установка тона передаваемого сигнала
; процедура SEND_SPACE
NBR_SPACE ; колво пропускаемых точек
CTR_DIT ; счетчик пропускаемых точек
; процедура SEND_ONE_CHAR
CW_CHAR ; передаваемый символ
ENDC
;
; Именование регистров микроконтроллера
;
CMCON EQU 0X19 ; регистр контроля компаратора
TMR0 EQU 0X01 ; timer0
TMR1L EQU 0X0E ; timer1 младший байт
TMR1H EQU 0X0F ; timer1 старший байт
T1CON EQU 0X10 ; timer1 control register
PCL EQU 0X02 ; программный счетчик
STATUS EQU 0X03 ; регистр status
FSR EQU 0X04 ; указатель адреса в памяти данных
PORTA EQU 0X05 ; порт A
PORTC EQU 0X07 ; порт C
PCLATH EQU 0X0A ; верхние 5 бит программного счетчика
INTCON EQU 0X0B ; регистр контроля прерываний
TRISA EQU 0X85 ; управляющий регистр порта A
TRISC EQU 0X87 ; управляющий регистр порта C
OPTION_REG EQU 0X81 ; регистр option
EEADR EQU 0X9B ; адресный регистр EEPROM
EECON1 EQU 0X9C ; содержит бит RD
EEDAT EQU 0X9A ; прочитанные из EEPROM данные
PCON EQU 0X8E ; регистр power control
PIE1 EQU 0X8C ; регистр контроля периферийных прерываний
PIR1 EQU 0X0C ; регистр флагов прерываний от
; периферийных модулей
;
; присвоение значений символьным константам
;
RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS
W EQU 0X00 ; file register designator = W
F EQU 0X01 ; file register designator = F
Z EQU 0X02 ; бит нуля в STATUS
C EQU 0X00 ; бит преноса в STATUS
RD EQU 0X00 ; инициализация чтения EEPROM
POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был
; сброс по включению питания
BOR EQU 0X00 ; сброс по снижению питания
TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1
TMR1ON EQU 0X00 ;
GIE EQU 0X07 ;
TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1
PON EQU 0X00 ; POWER ON IN FLAG
;
;=================================================================
; vector table
;
ORG 0X000 ; стартовый адрес
GOTO START ;
;==================================================================
; TIMER1 INTERRUPT
;
ORG 0X004 ; адрес прерывания
MOVWF TMPW ; сохраняем W
SWAPF STATUS,W
MOVWF TMPS ; сохраняем STATUS
BTFSC PIR1,0 ; прерывание от TMR1?
GOTO T1_INT ; да
NOP ; обработчик левого прерывания
GOTO END_ISR ;
T1_INT
MOVF TX_ALL_CNT,W ; вычитание
SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT
BCF FLAG,0 ;
SKPC ; пропустить, если результат >=0
BSF FLAG,0 ;
MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла
SUBLW D'125' ; ставим флаг, по которому во время передачи
SKPNZ ; меняем скорость
BSF FLAG,4 ; только при 5 мин цикле
; использовать либо верхнее, либо нижнее
;SUBLW D'250' ; а это костыль для ускорения за 10 сек
;SKPNZ ; до конца любого цикла, даже если
;BSF FLAG,4 ; работаем непрерывно
DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0
GOTO POP_TX
MOVF TX_ALL,W ; восстанавливаем
MOVWF TX_ALL_CNT ;
BCF FLAG,4 ; в конце цикла сбросить флаг ускорения
POP_TX
DECFSZ SEC_CNT, F ; SEC_CNT-1
GOTO POP ;
MOVLW D'150' ; 300 секунд = 5 мин
MOVWF SEC_CNT
BTFSS FLAG,2 ; если задержка активирована, то
BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг
; отмены задержки включения
DECF MIN_CNT,F ; MIN_CNT-1
DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0
GOTO POP
BSF FLAG,2 ; устанавливаем флаг разрешения работы
POP
BCF PIR1,0 ; сброс флага переполнения
END_ISR
SWAPF TMPS,W ; восстанавливаем регистры W and SATUS
MOVWF STATUS ;
SWAPF TMPW,F ;
SWAPF TMPW,W ;
RETFIE ; возврат из прерывания
;==================================================================
; Начало основной программы
;==================================================================
START
MOVLW B'10001110' ;
BSF STATUS, RP0 ; bank 1
MOVWF OPTION_REG ; инициализация регистра option
BCF STATUS, RP0 ; bank 0
CLRF PORTA ; очистка порта A
CLRF PORTC ; очистка порта C
MOVLW B'00000111' ;
MOVWF CMCON ; запрещаем работу компаратора
BSF STATUS, RP0 ; bank 1
MOVLW B'00000000' ;
MOVWF TRISA ; порт A - все выходы
MOVLW B'11111111' ;
MOVWF TRISC ; порт C - все входы
BCF STATUS, RP0 ; bank 0
CLRF TMR0 ; на всякий случай. Говорят, надо...
CLRWDT ; сбрасываем WDT
BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы,
; подключенные к переключателю
; после считывания напряжение с переключателя
; снимается для экономии энергии
;==================================================================
; инициализация TMR1
;
CLRF T1CON ; очистить TIMER1 control register
CLRF TMR1H ; очистить верхний байт TMR1
CLRF TMR1L ; очистить нижний байт TMR1
CLRF INTCON ; запретить прерывания
BSF STATUS,RP0 ; bank 1
CLRF PIE1 ; очистить рег контроля периферийных прерываний
BCF STATUS, RP0 ; bank 0
CLRF PIR1 ; очистить рег флагов периферийных прерываний
MOVLW B'00001110' ; инициализация TIMER1 control register
MOVWF T1CON ; с этого момента генератор 32.768 включен
;==================================================================
MOVLW D'150' ; инициализация счетчика пар секунд
MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин
DECF SEC_CNT,F ; имитируем прерывание
;MOVLW D'2' ; сколько пятиминуток будем работать
MOVLW D'96' ; сколько пятиминуток будем работать
MOVWF MIN_CNT ; 96х5=8 час
; MOVLW D'2' ; сколько пятиминуток задержка включения
MOVLW D'24' ; сколько пятиминуток задержка включения
MOVWF DELAY ; 24х5=120 мин
MOVLW D'178' ; тон звука, 178 ~ 1000 Гц
MOVWF SET_TONE ; чем больше, тем ниже частота
BSF FLAG,0 ; поднимаем флаг
BCF FLAG,4
;==================================================================
; если это включение питания, то выполняется задержка для
; гарантированного запуска генератора 32768 и его инициализация
; если другой сброс, то инициализация и задержка пропускаются
;
BSF STATUS, RP0 ; bank 1
MOVF PCON,W ; PCON -> W
BCF STATUS, RP0 ; bank 0
MOVWF TMPW ; W -> TMPW
BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс
GOTO DELAY_START ; по включению - задержка однозначно нужна
BTFSC TMPW,BOR ; а это был сброс по снижению напр питания
GOTO SKIP_DELAY ; или не был...
DELAY_START
BCF FLAG,3 ; при первом включении очистить FLAG,3
; задержка
MOVLW D'255' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
MOVLW 0X80
MOVWF CW_CHAR ;
CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек
BSF STATUS, RP0 ; bank 1
BSF PCON,POR ; устанавливаем POR=1
BSF PCON,BOR ; устанавливаем BOR=1
BCF STATUS, RP0 ; bank 0
SLEEP ; ожидаем запуск
SKIP_DELAY
;==================================================================
; читаем переключатель
;
MOVF PORTC,W ; читаем порт C
ANDLW B'00011100' ; маска
MOVWF SWITCH ; сохраняем состояние переключателя
MOVF PORTC,W ; читаем порт C
ANDLW B'00000011' ; маска двух младших бит
BCF FLAG,2 ; обнуляем флаг задержки
BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след.
BSF FLAG,2 ; устанавливаем флаг, можно работать
BCF PORTA,2 ; отключаем подтягивающие резисторы
ADDWF PCL,F ; таблица
GOTO SW00
GOTO SW01
GOTO SW10
GOTO SW11
SW00 ; непрерывно
MOVLW D'0' ; молчим последние 0 с
MOVWF TX_OFF ;
MOVLW D'30' ; цикл 60 сек
GOTO END_SW
SW01 ; цикл 30сек/30сек
MOVLW D'15' ; молчим последние 30 с
MOVWF TX_OFF ;
MOVLW D'30' ; цикл 60 сек
GOTO END_SW
SW10 ; цикл 1 мин/1 мин
MOVLW D'30' ; молчим последние 60 с
MOVWF TX_OFF ;
MOVLW D'60' ; цикл 120 сек
GOTO END_SW
SW11 ; цикл 1 мин/4 мин
MOVLW D'120' ; молчим последние 4 m
MOVWF TX_OFF ;
MOVLW D'150' ; цикл 5 m
END_SW
MOVWF TX_ALL ;
MOVWF TX_ALL_CNT ; инициализация
DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось
;==================================================================
; Окончание инициализации TIMER1
;
MOVLW B'11000000' ; разрешить прерывания от периферийных модулей
MOVWF INTCON
BSF STATUS,RP0 ; bank 1
BSF PIE1,TMR1IE ; разрешить прерывания от TMR1
BCF STATUS, RP0 ; bank 0
BSF T1CON,TMR1ON ; TMR1 ON
;==================================================================
; Если с момента запуска прошло 5 мин, то при сбросе задержку
; включения игнорируем
BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала
; работы
BSF FLAG,2 ; задержка включения не нужна
;==================================================================
; MAIN
; передача последовательности символов
; можно предавать любое количество, 0XFF означает конец последовательности,
; после чего формируется пауза и передача циклически повторяется
;
SEND_MSG
; если автоотключение не нужно, то три
; нижеследующих строчки надо закомментировать
MOVF MIN_CNT,F ; проверяем, не обнулился ли
SKPNZ ; счетчик пятиминуток
GOTO POWER_OFF ; если да, то выключаемся
BTFSS FLAG,2 ; пропустить след, если задержка включения
; кончилась (1-разрешение работы)
GOTO FLASH ; мигнуть и sleep
BTFSS FLAG,0 ; если флаг сброшен, то идем спать
GOTO TO_SLEEP
MOVF SWITCH,W
MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX
GET_MSG
MOVF CHAR_INDEX,W
BCF INTCON,GIE ; запрещаем прерывания
BSF STATUS, RP0 ; bank 1
MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM
BSF EECON1,RD ; разрешаем чтение EEPROM
MOVF EEDAT,W ; значение ячейки -> регистр W
BCF STATUS, RP0 ; bank 0
BSF INTCON,GIE ; разрешаем прерывания
;MOVLW 0x06
MOVWF CW_CHAR ; W -> CW_CHAR
MOVLW 0XFF ; конец сообщения?
SUBWF CW_CHAR,W ;
SKPNZ
GOTO END_MSG ; да, перейти к END_MSG
MOVLW D'60' ; скорость передачи быстро
BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла
MOVLW D'160' ; скорость передачи медленно
MOVWF CW_SPEED ; чем больше, тем медленней
CALL SEND_CHAR ; передаем букву и паузу в 3 точки
; или паузу 6 точек, если SPACE
INCF CHAR_INDEX ; CHAR_INDEX+1
GOTO GET_MSG
END_MSG
CALL WORD_SPACE ; пауза 6 точек
GOTO SEND_MSG ;
; время работы закончилось
POWER_OFF ; отсюда выход только через RESET
CLRF T1CON ; очистить TIMER1 control register, выключаем
; генератор 32768
;BCF T1CON,TMR1ON ; TMR1 OFF
CLRF INTCON ; запретить прерывания
; после сброса считаем, что это сброс по питанию
BSF STATUS, RP0 ; bank 1
BCF PCON,POR ; устанавливаем POR=0
BCF PCON,BOR ; устанавливаем BOR=0
BCF STATUS, RP0 ; bank 0
TO_SLEEP ;
CLRF PORTA
SLEEP
NOP
GOTO SEND_MSG
;========================================================================
; индикатор включенной задержки
; мигаем порт A.1
FLASH
MOVLW D'60' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
BSF PORTA,1
MOVLW 0X01 ;
MOVWF NBR_SPACE ; пауза в 1 точку
CALL SEND_SPACE ;
BCF PORTA,1
GOTO TO_SLEEP
;========================================================================
; SEND_CHAR
; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает
; его, и, в зависимости от состояния бита, передает: тире, если бит = 1;
; точку, если бит = 0.
; Знак передается, пока в слове есть хоть одна единица. Последняя единица
; "съедается", она означает конец слова.
;
SEND_CHAR
MOVLW 0X00 ; пауза?
SUBWF CW_CHAR,W ;
SKPNZ ;
GOTO WORD_SPACE
SEND_ONE_CHAR
BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен
RETURN
CLRC ; очистить бит переноса
RRF CW_CHAR, F ; сдвиг вправо через перенос
;
MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0"
SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем
GOTO PAUSE2 ; конец буквы
SKPC ; проверить бит переноса, пропустить, если=1
GOTO SEND_A_DIT ; перейти к SEND_A_DIT
SEND_A_DAH ; передаем тире
MOVLW 0X03 ; 1 тире = 3 точки
MOVWF NBR_DIT
MOVLW 0X01 ;
MOVWF NBR_SPACE ; после тире - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генериуем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
SEND_A_DIT
MOVLW 0X01 ; передаем точку
MOVWF NBR_DIT
MOVWF NBR_SPACE ; после точки - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генерируем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
PAUSE2
MOVLW D'2' ; пауза в 2 точки после буквы
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
WORD_SPACE
MOVLW D'6' ; пауза в 6 точек между словами
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
;==================================================================
; SEND_TONE
; Подпрограмма осуществляет задержку и одновременно формирует сигнал
; звуковой частоты (порт A.1)
;
SEND_TONE
MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек
MOVWF CTR_NBR ;
DIT_LENGTH
MOVF CW_SPEED, W ; CW_SPEED скорость передачи
MOVWF CTR_DIT ;
START_CYCLE
BSF PORTA,1 ; A.1=1 в начале цикла
MOVF SET_TONE,W ;
MOVWF TONE ; заносим значение в счетчик цикла задержки
HIGH_HALF
DECFSZ TONE, F ; считаем до нуля
GOTO HIGH_HALF
BCF PORTA,1 ; A.1=0 в конце цикла
MOVF SET_TONE,W ;
MOVWF TONE
LOW_HALF
DECFSZ TONE, F ;
GOTO LOW_HALF
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH ;
RETURN ;
;================================================================
; SEND_SPACE
; Делает тоже самое, что и SEND_TONE, только вместо команд управления
; портами стоит команда NOP
;
SEND_SPACE
MOVF NBR_SPACE, W ;
MOVWF CTR_NBR
DIT_LENGTH_SP
MOVF CW_SPEED, W ;
MOVWF CTR_DIT
START_CYCLE_SP
NOP
MOVF SET_TONE,W
MOVWF TONE ;
HIGH_HALF_SP
DECFSZ TONE, F ;
GOTO HIGH_HALF_SP
NOP
MOVF SET_TONE,W
MOVWF TONE
LOW_HALF_SP
DECFSZ TONE, F ;
GOTO LOW_HALF_SP
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE_SP
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH_SP ;
RETURN ;
;==================================================================
;==================================================================
; Идентификатор
ORG 0x2000 ; стартовый адрес
DATA 0x0000
DATA 0x0000
DATA 0x0000
DATA 0x0000
;==================================================================
; Слово конфигурации
ORG 0x2007 ; стартовый адрес
DATA 0x31E4
;==================================================================
; Запись в EEPROM при программировании
; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк
; может передавать последовательно три символа Морзе, четвертым обязательно
; должен быть EOM
; В последнюю адресуемую ячейку можно записать большее количество символов
ORG 0X2100 ; стартовый адрес
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x02 ; E . 00000010
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x04 ; I .. 00000100
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x08 ; S ... 00001000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x10 ; H .... 00010000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x20 ; 5 ..... 00100000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
END
Версия прошивки 3.1, циклы 30с/120с; 60с/60с; 1м/4м
;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, MOT, T). Вариант кода задается переключателем.
;-Может работать непрерывно или циклом: 30с/120с; 60с/60с; 1м/4м.
;-Есть выход 1000 Гц для модуляции маяка на 144 МГц.
;-Автоотключение через 8 часов.
;-Потребление в выключенном состоянии 0.08 ма, во время работы, при передаче позывного, 0.5 ма.
;-Уход часов определяется кварцем.
;-Код с переключателя считывается один раз после сброса.
;-Режим отложенного старта (ОС), задержка 60 минут
;-Ускорение передачи позывного за 10 сек до конца цикла (только для 5 мин цикла)
;-Питание от 3 до 5 вольт
;
; PIC16F630
; WDT off, intLC, MCLR on, BOR on, PWRTE on
;
list P=16F630
radix HEX
;====================================================================
; именование пользовательских регистров
;
CBLOCK 0X20 ; начальный адрес пользовательских регистров
TMPW ; временный регистр для хранения W во время прерывания
TMPS ; временный регистр для хранения STATUS
SEC_CNT ; счетчик пар секунд
MIN_CNT ; счетчик минут (пятиминуток, автовыключение)
FLAG ; регистр флагов:
; FLAG,0 разрешает передачу позывного в свое время
; FLAG,2 флаг задержки включения (1-можно работать)
; FLAG,3 флаг взводится через 5 мин после начала работы
; и отменяет задержку включения при сбросе
; FLAG,4 флаг устанавливается за 10 сек до конца цикла
DELAY ; счетчик пятиминуток, задержка включения
TX_ALL_CNT ; счетчик пар секунд в цикле
TX_OFF ; с какой секунды пауза
TX_ALL ; сколько пар секунд в цикле
SWITCH ; состояние переключателя
CHAR_INDEX ; номер передаваемого символа
CW_SPEED ; скорость передачи
; процедура SEND_TONE
NBR_DIT ; NBR_DIT кол-во пропускаемых точек
CTR_NBR ; счетчик пропускаемых точек
TONE ; счетчик частоты
SET_TONE ; установка тона передаваемого сигнала
; процедура SEND_SPACE
NBR_SPACE ; колво пропускаемых точек
CTR_DIT ; счетчик пропускаемых точек
; процедура SEND_ONE_CHAR
CW_CHAR ; передаваемый символ
ENDC
;
; Именование регистров микроконтроллера
;
CMCON EQU 0X19 ; регистр контроля компаратора
TMR0 EQU 0X01 ; timer0
TMR1L EQU 0X0E ; timer1 младший байт
TMR1H EQU 0X0F ; timer1 старший байт
T1CON EQU 0X10 ; timer1 control register
PCL EQU 0X02 ; программный счетчик
STATUS EQU 0X03 ; регистр status
FSR EQU 0X04 ; указатель адреса в памяти данных
PORTA EQU 0X05 ; порт A
PORTC EQU 0X07 ; порт C
PCLATH EQU 0X0A ; верхние 5 бит программного счетчика
INTCON EQU 0X0B ; регистр контроля прерываний
TRISA EQU 0X85 ; управляющий регистр порта A
TRISC EQU 0X87 ; управляющий регистр порта C
OPTION_REG EQU 0X81 ; регистр option
EEADR EQU 0X9B ; адресный регистр EEPROM
EECON1 EQU 0X9C ; содержит бит RD
EEDAT EQU 0X9A ; прочитанные из EEPROM данные
PCON EQU 0X8E ; регистр power control
PIE1 EQU 0X8C ; регистр контроля периферийных прерываний
PIR1 EQU 0X0C ; регистр флагов прерываний от
; периферийных модулей
;
; присвоение значений символьным константам
;
RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS
W EQU 0X00 ; file register designator = W
F EQU 0X01 ; file register designator = F
Z EQU 0X02 ; бит нуля в STATUS
C EQU 0X00 ; бит преноса в STATUS
RD EQU 0X00 ; инициализация чтения EEPROM
POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был
; сброс по включению питания
BOR EQU 0X00 ; сброс по снижению питания
TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1
TMR1ON EQU 0X00 ;
GIE EQU 0X07 ;
TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1
PON EQU 0X00 ; POWER ON IN FLAG
;
;=================================================================
; vector table
;
ORG 0X000 ; стартовый адрес
GOTO START ;
;==================================================================
; TIMER1 INTERRUPT
;
ORG 0X004 ; адрес прерывания
MOVWF TMPW ; сохраняем W
SWAPF STATUS,W
MOVWF TMPS ; сохраняем STATUS
BTFSC PIR1,0 ; прерывание от TMR1?
GOTO T1_INT ; да
NOP ; обработчик левого прерывания
GOTO END_ISR ;
T1_INT
MOVF TX_ALL_CNT,W ; вычитание
SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT
BCF FLAG,0 ;
SKPC ; пропустить, если результат >=0
BSF FLAG,0 ;
MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла
SUBLW D'125' ; ставим флаг, по которому во время передачи
SKPNZ ; меняем скорость
BSF FLAG,4 ; только при 5 мин цикле
; использовать либо верхнее, либо нижнее
;SUBLW D'250' ; а это костыль для ускорения за 10 сек
;SKPNZ ; до конца любого цикла, даже если
;BSF FLAG,4 ; работаем непрерывно
DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0
GOTO POP_TX
MOVF TX_ALL,W ; восстанавливаем
MOVWF TX_ALL_CNT ;
BCF FLAG,4 ; в конце цикла сбросить флаг ускорения
POP_TX
DECFSZ SEC_CNT, F ; SEC_CNT-1
GOTO POP ;
MOVLW D'150' ; 300 секунд = 5 мин
MOVWF SEC_CNT
BTFSS FLAG,2 ; если задержка активирована, то
BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг
; отмены задержки включения
DECF MIN_CNT,F ; MIN_CNT-1
DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0
GOTO POP
BSF FLAG,2 ; устанавливаем флаг разрешения работы
POP
BCF PIR1,0 ; сброс флага переполнения
END_ISR
SWAPF TMPS,W ; восстанавливаем регистры W and SATUS
MOVWF STATUS ;
SWAPF TMPW,F ;
SWAPF TMPW,W ;
RETFIE ; возврат из прерывания
;==================================================================
; Начало основной программы
;==================================================================
START
MOVLW B'10001110' ;
BSF STATUS, RP0 ; bank 1
MOVWF OPTION_REG ; инициализация регистра option
BCF STATUS, RP0 ; bank 0
CLRF PORTA ; очистка порта A
CLRF PORTC ; очистка порта C
MOVLW B'00000111' ;
MOVWF CMCON ; запрещаем работу компаратора
BSF STATUS, RP0 ; bank 1
MOVLW B'00000000' ;
MOVWF TRISA ; порт A - все выходы
MOVLW B'11111111' ;
MOVWF TRISC ; порт C - все входы
BCF STATUS, RP0 ; bank 0
CLRF TMR0 ; на всякий случай. Говорят, надо...
CLRWDT ; сбрасываем WDT
BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы,
; подключенные к переключателю
; после считывания напряжение с переключателя
; снимается для экономии энергии
;==================================================================
; инициализация TMR1
;
CLRF T1CON ; очистить TIMER1 control register
CLRF TMR1H ; очистить верхний байт TMR1
CLRF TMR1L ; очистить нижний байт TMR1
CLRF INTCON ; запретить прерывания
BSF STATUS,RP0 ; bank 1
CLRF PIE1 ; очистить рег контроля периферийных прерываний
BCF STATUS, RP0 ; bank 0
CLRF PIR1 ; очистить рег флагов периферийных прерываний
MOVLW B'00001110' ; инициализация TIMER1 control register
MOVWF T1CON ; с этого момента генератор 32.768 включен
;==================================================================
MOVLW D'150' ; инициализация счетчика пар секунд
MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин
DECF SEC_CNT,F ; имитируем прерывание
;MOVLW D'2' ; сколько пятиминуток будем работать
MOVLW D'96' ; сколько пятиминуток будем работать
MOVWF MIN_CNT ; 96х5=8 час
; MOVLW D'2' ; сколько пятиминуток задержка включения
MOVLW D'12' ; сколько пятиминуток задержка включения
MOVWF DELAY ; 12х5=60 мин
MOVLW D'178' ; тон звука, 178 ~ 1000 Гц
MOVWF SET_TONE ; чем больше, тем ниже частота
BSF FLAG,0 ; поднимаем флаг
BCF FLAG,4
;==================================================================
; если это включение питания, то выполняется задержка для
; гарантированного запуска генератора 32768 и его инициализация
; если другой сброс, то инициализация и задержка пропускаются
;
BSF STATUS, RP0 ; bank 1
MOVF PCON,W ; PCON -> W
BCF STATUS, RP0 ; bank 0
MOVWF TMPW ; W -> TMPW
BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс
GOTO DELAY_START ; по включению - задержка однозначно нужна
BTFSC TMPW,BOR ; а это был сброс по снижению напр питания
GOTO SKIP_DELAY ; или не был...
DELAY_START
BCF FLAG,3 ; при первом включении очистить FLAG,3
; задержка
MOVLW D'255' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
MOVLW 0X80
MOVWF CW_CHAR ;
CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек
BSF STATUS, RP0 ; bank 1
BSF PCON,POR ; устанавливаем POR=1
BSF PCON,BOR ; устанавливаем BOR=1
BCF STATUS, RP0 ; bank 0
SLEEP ; ожидаем запуск
SKIP_DELAY
;==================================================================
; читаем переключатель
;
MOVF PORTC,W ; читаем порт C
ANDLW B'00011100' ; маска
MOVWF SWITCH ; сохраняем состояние переключателя
MOVF PORTC,W ; читаем порт C
ANDLW B'00000011' ; маска двух младших бит
BCF FLAG,2 ; обнуляем флаг задержки
BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след.
BSF FLAG,2 ; устанавливаем флаг, можно работать
BCF PORTA,2 ; отключаем подтягивающие резисторы
ADDWF PCL,F ; таблица
GOTO SW00
GOTO SW01
GOTO SW10
GOTO SW11
SW00 ; непрерывно
MOVLW D'0' ; молчим последние 0 с
MOVWF TX_OFF ;
MOVLW D'30' ; цикл 60 сек
GOTO END_SW
SW01 ; цикл 30сек/120сек
MOVLW D'60' ; молчим последние 120 с
MOVWF TX_OFF ;
MOVLW D'75' ; цикл 150 сек
GOTO END_SW
SW10 ; цикл 1 мин/1 мин
MOVLW D'30' ; молчим последние 60 с
MOVWF TX_OFF ;
MOVLW D'60' ; цикл 120 сек
GOTO END_SW
SW11 ; цикл 1 мин/4 мин
MOVLW D'120' ; молчим последние 4 m
MOVWF TX_OFF ;
MOVLW D'150' ; цикл 5 m
END_SW
MOVWF TX_ALL ;
MOVWF TX_ALL_CNT ; инициализация
DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось
;==================================================================
; Окончание инициализации TIMER1
;
MOVLW B'11000000' ; разрешить прерывания от периферийных модулей
MOVWF INTCON
BSF STATUS,RP0 ; bank 1
BSF PIE1,TMR1IE ; разрешить прерывания от TMR1
BCF STATUS, RP0 ; bank 0
BSF T1CON,TMR1ON ; TMR1 ON
;==================================================================
; Если с момента запуска прошло 5 мин, то при сбросе задержку
; включения игнорируем
BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала
; работы
BSF FLAG,2 ; задержка включения не нужна
;==================================================================
; MAIN
; передача последовательности символов
; можно предавать любое количество, 0XFF означает конец последовательности,
; после чего формируется пауза и передача циклически повторяется
;
SEND_MSG
; если автоотключение не нужно, то три
; нижеследующих строчки надо закомментировать
MOVF MIN_CNT,F ; проверяем, не обнулился ли
SKPNZ ; счетчик пятиминуток
GOTO POWER_OFF ; если да, то выключаемся
BTFSS FLAG,2 ; пропустить след, если задержка включения
; кончилась (1-разрешение работы)
GOTO FLASH ; мигнуть и sleep
BTFSS FLAG,0 ; если флаг сброшен, то идем спать
GOTO TO_SLEEP
MOVF SWITCH,W
MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX
GET_MSG
MOVF CHAR_INDEX,W
BCF INTCON,GIE ; запрещаем прерывания
BSF STATUS, RP0 ; bank 1
MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM
BSF EECON1,RD ; разрешаем чтение EEPROM
MOVF EEDAT,W ; значение ячейки -> регистр W
BCF STATUS, RP0 ; bank 0
BSF INTCON,GIE ; разрешаем прерывания
;MOVLW 0x06
MOVWF CW_CHAR ; W -> CW_CHAR
MOVLW 0XFF ; конец сообщения?
SUBWF CW_CHAR,W ;
SKPNZ
GOTO END_MSG ; да, перейти к END_MSG
MOVLW D'60' ; скорость передачи быстро
BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла
MOVLW D'160' ; скорость передачи медленно
MOVWF CW_SPEED ; чем больше, тем медленней
CALL SEND_CHAR ; передаем букву и паузу в 3 точки
; или паузу 6 точек, если SPACE
INCF CHAR_INDEX ; CHAR_INDEX+1
GOTO GET_MSG
END_MSG
CALL WORD_SPACE ; пауза 6 точек
GOTO SEND_MSG ;
; время работы закончилось
POWER_OFF ; отсюда выход только через RESET
CLRF T1CON ; очистить TIMER1 control register, выключаем
; генератор 32768
;BCF T1CON,TMR1ON ; TMR1 OFF
CLRF INTCON ; запретить прерывания
; после сброса считаем, что это сброс по питанию
BSF STATUS, RP0 ; bank 1
BCF PCON,POR ; устанавливаем POR=0
BCF PCON,BOR ; устанавливаем BOR=0
BCF STATUS, RP0 ; bank 0
TO_SLEEP ;
CLRF PORTA
SLEEP
NOP
GOTO SEND_MSG
;========================================================================
; индикатор включенной задержки
; мигаем порт A.1
FLASH
MOVLW D'60' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
BSF PORTA,1
MOVLW 0X01 ;
MOVWF NBR_SPACE ; пауза в 1 точку
CALL SEND_SPACE ;
BCF PORTA,1
GOTO TO_SLEEP
;========================================================================
; SEND_CHAR
; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает
; его, и, в зависимости от состояния бита, передает: тире, если бит = 1;
; точку, если бит = 0.
; Знак передается, пока в слове есть хоть одна единица. Последняя единица
; "съедается", она означает конец слова.
;
SEND_CHAR
MOVLW 0X00 ; пауза?
SUBWF CW_CHAR,W ;
SKPNZ ;
GOTO WORD_SPACE
SEND_ONE_CHAR
BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен
RETURN
CLRC ; очистить бит переноса
RRF CW_CHAR, F ; сдвиг вправо через перенос
;
MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0"
SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем
GOTO PAUSE2 ; конец буквы
SKPC ; проверить бит переноса, пропустить, если=1
GOTO SEND_A_DIT ; перейти к SEND_A_DIT
SEND_A_DAH ; передаем тире
MOVLW 0X03 ; 1 тире = 3 точки
MOVWF NBR_DIT
MOVLW 0X01 ;
MOVWF NBR_SPACE ; после тире - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генериуем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
SEND_A_DIT
MOVLW 0X01 ; передаем точку
MOVWF NBR_DIT
MOVWF NBR_SPACE ; после точки - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генерируем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
PAUSE2
MOVLW D'2' ; пауза в 2 точки после буквы
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
WORD_SPACE
MOVLW D'6' ; пауза в 6 точек между словами
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
;==================================================================
; SEND_TONE
; Подпрограмма осуществляет задержку и одновременно формирует сигнал
; звуковой частоты (порт A.1)
;
SEND_TONE
MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек
MOVWF CTR_NBR ;
DIT_LENGTH
MOVF CW_SPEED, W ; CW_SPEED скорость передачи
MOVWF CTR_DIT ;
START_CYCLE
BSF PORTA,1 ; A.1=1 в начале цикла
MOVF SET_TONE,W ;
MOVWF TONE ; заносим значение в счетчик цикла задержки
HIGH_HALF
DECFSZ TONE, F ; считаем до нуля
GOTO HIGH_HALF
BCF PORTA,1 ; A.1=0 в конце цикла
MOVF SET_TONE,W ;
MOVWF TONE
LOW_HALF
DECFSZ TONE, F ;
GOTO LOW_HALF
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH ;
RETURN ;
;================================================================
; SEND_SPACE
; Делает тоже самое, что и SEND_TONE, только вместо команд управления
; портами стоит команда NOP
;
SEND_SPACE
MOVF NBR_SPACE, W ;
MOVWF CTR_NBR
DIT_LENGTH_SP
MOVF CW_SPEED, W ;
MOVWF CTR_DIT
START_CYCLE_SP
NOP
MOVF SET_TONE,W
MOVWF TONE ;
HIGH_HALF_SP
DECFSZ TONE, F ;
GOTO HIGH_HALF_SP
NOP
MOVF SET_TONE,W
MOVWF TONE
LOW_HALF_SP
DECFSZ TONE, F ;
GOTO LOW_HALF_SP
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE_SP
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH_SP ;
RETURN ;
;==================================================================
;==================================================================
; Идентификатор
ORG 0x2000 ; стартовый адрес
DATA 0x0000
DATA 0x0000
DATA 0x0000
DATA 0x0000
;==================================================================
; Слово конфигурации
ORG 0x2007 ; стартовый адрес
DATA 0x31E4
;==================================================================
; Запись в EEPROM при программировании
; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк
; может передавать последовательно три символа Морзе, четвертым обязательно
; должен быть EOM
; В последнюю адресуемую ячейку можно записать большее количество символов
ORG 0X2100 ; стартовый адрес
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x02 ; E . 00000010
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x04 ; I .. 00000100
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x08 ; S ... 00001000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x10 ; H .... 00010000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x20 ; 5 ..... 00100000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
END
Версия прошивки 3.2, циклы 30с/120с; 60с/60с; 1м/4м
;-Передает в режиме лисы код Морзе (MO, MOE, MOI, MOS, MOH, MO5, RA1AMO). Вариант кода задается переключателем.
;-Может работать непрерывно или циклом: 30с/120с; 60с/60с; 1м/4м.
;-Есть выход 1000 Гц для модуляции маяка на 144 МГц.
;-Автоотключение через 8 часов, без учета ОС.
;-Потребление в выключенном состоянии менее 0.08 ма, во время работы, при передаче позывного, 0.5 ма.
;-Уход часов определяется кварцем.
;-Код с переключателя считывается один раз после сброса.
;-Режим отложенного старта (ОС), задержка 120 минут
;-Питание от 3 до 5 вольт
;
; PIC16F630
; WDT off, intLC, MCLR on, BOR on, PWRTE on
;
list P=16F630
radix HEX
;====================================================================
; именование пользовательских регистров
;
CBLOCK 0X20 ; начальный адрес пользовательских регистров
TMPW ; временный регистр для хранения W во время прерывания
TMPS ; временный регистр для хранения STATUS
SEC_CNT ; счетчик пар секунд
MIN_CNT ; счетчик минут (пятиминуток, автовыключение)
FLAG ; регистр флагов:
; FLAG,0 разрешает передачу позывного в свое время
; FLAG,2 флаг задержки включения (1-можно работать)
; FLAG,3 флаг взводится через 5 мин после начала работы
; и отменяет задержку включения при сбросе
; FLAG,4 флаг устанавливается за 10 сек до конца цикла
DELAY ; счетчик пятиминуток, задержка включения
TX_ALL_CNT ; счетчик пар секунд в цикле
TX_OFF ; с какой секунды пауза
TX_ALL ; сколько пар секунд в цикле
SWITCH ; состояние переключателя
CHAR_INDEX ; номер передаваемого символа
CW_SPEED ; скорость передачи
; процедура SEND_TONE
NBR_DIT ; NBR_DIT кол-во пропускаемых точек
CTR_NBR ; счетчик пропускаемых точек
TONE ; счетчик частоты
SET_TONE ; установка тона передаваемого сигнала
; процедура SEND_SPACE
NBR_SPACE ; колво пропускаемых точек
CTR_DIT ; счетчик пропускаемых точек
; процедура SEND_ONE_CHAR
CW_CHAR ; передаваемый символ
ENDC
;
; Именование регистров микроконтроллера
;
CMCON EQU 0X19 ; регистр контроля компаратора
TMR0 EQU 0X01 ; timer0
TMR1L EQU 0X0E ; timer1 младший байт
TMR1H EQU 0X0F ; timer1 старший байт
T1CON EQU 0X10 ; timer1 control register
PCL EQU 0X02 ; программный счетчик
STATUS EQU 0X03 ; регистр status
FSR EQU 0X04 ; указатель адреса в памяти данных
PORTA EQU 0X05 ; порт A
PORTC EQU 0X07 ; порт C
PCLATH EQU 0X0A ; верхние 5 бит программного счетчика
INTCON EQU 0X0B ; регистр контроля прерываний
TRISA EQU 0X85 ; управляющий регистр порта A
TRISC EQU 0X87 ; управляющий регистр порта C
OPTION_REG EQU 0X81 ; регистр option
EEADR EQU 0X9B ; адресный регистр EEPROM
EECON1 EQU 0X9C ; содержит бит RD
EEDAT EQU 0X9A ; прочитанные из EEPROM данные
PCON EQU 0X8E ; регистр power control
PIE1 EQU 0X8C ; регистр контроля периферийных прерываний
PIR1 EQU 0X0C ; регистр флагов прерываний от
; периферийных модулей
;
; присвоение значений символьным константам
;
RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS
W EQU 0X00 ; file register designator = W
F EQU 0X01 ; file register designator = F
Z EQU 0X02 ; бит нуля в STATUS
C EQU 0X00 ; бит преноса в STATUS
RD EQU 0X00 ; инициализация чтения EEPROM
POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был
; сброс по включению питания
BOR EQU 0X00 ; сброс по снижению питания
TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1
TMR1ON EQU 0X00 ;
GIE EQU 0X07 ;
TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1
PON EQU 0X00 ; POWER ON IN FLAG
;
;=================================================================
; vector table
;
ORG 0X000 ; стартовый адрес
GOTO START ;
;==================================================================
; TIMER1 INTERRUPT
;
ORG 0X004 ; адрес прерывания
MOVWF TMPW ; сохраняем W
SWAPF STATUS,W
MOVWF TMPS ; сохраняем STATUS
BTFSC PIR1,0 ; прерывание от TMR1?
GOTO T1_INT ; да
NOP ; обработчик левого прерывания
GOTO END_ISR ;
T1_INT
MOVF TX_ALL_CNT,W ; вычитание
SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT
BCF FLAG,0 ;
SKPC ; пропустить, если результат >=0
BSF FLAG,0 ;
; MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла
; SUBLW D'125' ; ставим флаг, по которому во время передачи
; SKPNZ ; меняем скорость
; BSF FLAG,4 ; только при 5 мин цикле
; использовать либо верхнее, либо нижнее
;SUBLW D'250' ; а это костыль для ускорения за 10 сек
;SKPNZ ; до конца любого цикла, даже если
;BSF FLAG,4 ; работаем непрерывно
DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0
GOTO POP_TX
MOVF TX_ALL,W ; восстанавливаем
MOVWF TX_ALL_CNT ;
; BCF FLAG,4 ; в конце цикла сбросить флаг ускорения
POP_TX
DECFSZ SEC_CNT, F ; SEC_CNT-1
GOTO POP ;
MOVLW D'150' ; 300 секунд = 5 мин
MOVWF SEC_CNT
BTFSS FLAG,2 ; если задержка активирована, то
BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг
; отмены задержки включения
BTFSC FLAG,2 ; если флаг разрешения работы установлен, начинаем отсчет
; задержки отключения
DECF MIN_CNT,F ; MIN_CNT-1 минуты работы считаем после
; окончании задержки включения
DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0
GOTO POP ; задержка окончилась
BSF FLAG,2 ; устанавливаем флаг разрешения работы
POP
BCF PIR1,0 ; сброс флага переполнения
END_ISR
SWAPF TMPS,W ; восстанавливаем регистры W and SATUS
MOVWF STATUS ;
SWAPF TMPW,F ;
SWAPF TMPW,W ;
RETFIE ; возврат из прерывания
;==================================================================
; Начало основной программы
;==================================================================
START
MOVLW B'10001110' ;
BSF STATUS, RP0 ; bank 1
MOVWF OPTION_REG ; инициализация регистра option
BCF STATUS, RP0 ; bank 0
CLRF PORTA ; очистка порта A
CLRF PORTC ; очистка порта C
MOVLW B'00000111' ;
MOVWF CMCON ; запрещаем работу компаратора
BSF STATUS, RP0 ; bank 1
MOVLW B'00000000' ;
MOVWF TRISA ; порт A - все выходы
MOVLW B'11111111' ;
MOVWF TRISC ; порт C - все входы
BCF STATUS, RP0 ; bank 0
CLRF TMR0 ; на всякий случай. Говорят, надо...
CLRWDT ; сбрасываем WDT
BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы,
; подключенные к переключателю
; после считывания напряжение с переключателя
; снимается для экономии энергии
;==================================================================
; инициализация TMR1
;
CLRF T1CON ; очистить TIMER1 control register
CLRF TMR1H ; очистить верхний байт TMR1
CLRF TMR1L ; очистить нижний байт TMR1
CLRF INTCON ; запретить прерывания
BSF STATUS,RP0 ; bank 1
CLRF PIE1 ; очистить рег контроля периферийных прерываний
BCF STATUS, RP0 ; bank 0
CLRF PIR1 ; очистить рег флагов периферийных прерываний
MOVLW B'00001110' ; инициализация TIMER1 control register
MOVWF T1CON ; с этого момента генератор 32.768 включен
;==================================================================
MOVLW D'150' ; инициализация счетчика пар секунд
MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин
DECF SEC_CNT,F ; имитируем прерывание
;MOVLW D'2' ; сколько пятиминуток будем работать
MOVLW D'96' ; сколько пятиминуток будем работать
MOVWF MIN_CNT ; 96х5=8 час
; MOVLW D'2' ; сколько пятиминуток задержка включения
MOVLW D'24' ; сколько пятиминуток задержка включения
MOVWF DELAY ; 24х5=120 мин
MOVLW D'178' ; тон звука, 178 ~ 1000 Гц
MOVWF SET_TONE ; чем больше, тем ниже частота
BSF FLAG,0 ; поднимаем флаг
; BCF FLAG,4
;==================================================================
; если это включение питания, то выполняется задержка для
; гарантированного запуска генератора 32768 и его инициализация
; если другой сброс, то инициализация и задержка пропускаются
;
BSF STATUS, RP0 ; bank 1
MOVF PCON,W ; PCON -> W
BCF STATUS, RP0 ; bank 0
MOVWF TMPW ; W -> TMPW
BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс
GOTO DELAY_START ; по включению - задержка однозначно нужна
BTFSC TMPW,BOR ; а это был сброс по снижению напр питания
GOTO SKIP_DELAY ; или не был...
DELAY_START
BCF FLAG,3 ; при первом включении очистить FLAG,3
; задержка
MOVLW D'255' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
MOVLW 0X80
MOVWF CW_CHAR ;
CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек
BSF STATUS, RP0 ; bank 1
BSF PCON,POR ; устанавливаем POR=1
BSF PCON,BOR ; устанавливаем BOR=1
BCF STATUS, RP0 ; bank 0
SLEEP ; ожидаем запуск
SKIP_DELAY
;==================================================================
; читаем переключатель
;
MOVF PORTC,W ; читаем порт C
ANDLW B'00011100' ; маска
MOVWF SWITCH ; сохраняем состояние переключателя
MOVF PORTC,W ; читаем порт C
ANDLW B'00000011' ; маска двух младших бит
BCF FLAG,2 ; обнуляем флаг задержки
BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след.
BSF FLAG,2 ; устанавливаем флаг, можно работать
BCF PORTA,2 ; отключаем подтягивающие резисторы
ADDWF PCL,F ; таблица
GOTO SW00
GOTO SW01
GOTO SW10
GOTO SW11
SW00 ; непрерывно
MOVLW D'0' ; молчим последние 0 с
MOVWF TX_OFF ;
MOVLW D'30' ; цикл 60 сек
GOTO END_SW
SW01 ; цикл 30сек/120сек
MOVLW D'60' ; молчим последние 120 с
MOVWF TX_OFF ;
MOVLW D'75' ; цикл 150 сек
GOTO END_SW
SW10 ; цикл 1 мин/1 мин
MOVLW D'30' ; молчим последние 60 с
MOVWF TX_OFF ;
MOVLW D'60' ; цикл 120 сек
GOTO END_SW
SW11 ; цикл 1 мин/4 мин
MOVLW D'120' ; молчим последние 4 m
MOVWF TX_OFF ;
MOVLW D'150' ; цикл 5 m
END_SW
MOVWF TX_ALL ;
MOVWF TX_ALL_CNT ; инициализация
DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось
;==================================================================
; Окончание инициализации TIMER1
;
MOVLW B'11000000' ; разрешить прерывания от периферийных модулей
MOVWF INTCON
BSF STATUS,RP0 ; bank 1
BSF PIE1,TMR1IE ; разрешить прерывания от TMR1
BCF STATUS, RP0 ; bank 0
BSF T1CON,TMR1ON ; TMR1 ON
;==================================================================
; Если с момента запуска прошло 5 мин, то при сбросе задержку
; включения игнорируем
BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала
; работы
BSF FLAG,2 ; задержка включения не нужна
;==================================================================
; MAIN
; передача последовательности символов
; можно предавать любое количество, 0XFF означает конец последовательности,
; после чего формируется пауза и передача циклически повторяется
;
SEND_MSG
; если автоотключение не нужно, то три
; нижеследующих строчки надо закомментировать
MOVF MIN_CNT,F ; проверяем, не обнулился ли
SKPNZ ; счетчик пятиминуток
GOTO POWER_OFF ; если да, то выключаемся
BTFSS FLAG,2 ; пропустить след, если задержка включения
; кончилась (1-разрешение работы)
GOTO FLASH ; мигнуть и sleep
BTFSS FLAG,0 ; если флаг сброшен, то идем спать
GOTO TO_SLEEP
MOVF SWITCH,W
MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX
GET_MSG
MOVF CHAR_INDEX,W
BCF INTCON,GIE ; запрещаем прерывания
BSF STATUS, RP0 ; bank 1
MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM
BSF EECON1,RD ; разрешаем чтение EEPROM
MOVF EEDAT,W ; значение ячейки -> регистр W
BCF STATUS, RP0 ; bank 0
BSF INTCON,GIE ; разрешаем прерывания
;MOVLW 0x06
MOVWF CW_CHAR ; W -> CW_CHAR
MOVLW 0XFF ; конец сообщения?
SUBWF CW_CHAR,W ;
SKPNZ
GOTO END_MSG ; да, перейти к END_MSG
; MOVLW D'60' ; скорость передачи быстро
; BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла
MOVLW D'160' ; скорость передачи медленно
MOVWF CW_SPEED ; чем больше, тем медленней
CALL SEND_CHAR ; передаем букву и паузу в 3 точки
; или паузу 6 точек, если SPACE
INCF CHAR_INDEX ; CHAR_INDEX+1
GOTO GET_MSG
END_MSG
CALL WORD_SPACE ; пауза 6 точек
GOTO SEND_MSG ;
; время работы закончилось
POWER_OFF ; отсюда выход только через RESET
CLRF FLAG ; очистка регистра флагов
CLRF T1CON ; очистить TIMER1 control register, выключаем
; генератор 32768
;BCF T1CON,TMR1ON ; TMR1 OFF
CLRF INTCON ; запретить прерывания
; после сброса считаем, что это сброс по питанию
BSF STATUS, RP0 ; bank 1
BCF PCON,POR ; устанавливаем POR=0
BCF PCON,BOR ; устанавливаем BOR=0
BCF STATUS, RP0 ; bank 0
TO_SLEEP ;
CLRF PORTA
SLEEP
NOP
GOTO SEND_MSG
;========================================================================
; индикатор включенной задержки
; мигаем порт A.1
FLASH
MOVLW D'60' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
BSF PORTA,1
MOVLW 0X01 ;
MOVWF NBR_SPACE ; пауза в 1 точку
CALL SEND_SPACE ;
BCF PORTA,1
GOTO TO_SLEEP
;========================================================================
; SEND_CHAR
; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает
; его, и, в зависимости от состояния бита, передает: тире, если бит = 1;
; точку, если бит = 0.
; Знак передается, пока в слове есть хоть одна единица. Последняя единица
; "съедается", она означает конец слова.
;
SEND_CHAR
MOVLW 0X00 ; пауза?
SUBWF CW_CHAR,W ;
SKPNZ ;
GOTO WORD_SPACE
SEND_ONE_CHAR
BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен
RETURN
CLRC ; очистить бит переноса
RRF CW_CHAR, F ; сдвиг вправо через перенос
;
MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0"
SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем
GOTO PAUSE2 ; конец буквы
SKPC ; проверить бит переноса, пропустить, если=1
GOTO SEND_A_DIT ; перейти к SEND_A_DIT
SEND_A_DAH ; передаем тире
MOVLW 0X03 ; 1 тире = 3 точки
MOVWF NBR_DIT
MOVLW 0X01 ;
MOVWF NBR_SPACE ; после тире - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генериуем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
SEND_A_DIT
MOVLW 0X01 ; передаем точку
MOVWF NBR_DIT
MOVWF NBR_SPACE ; после точки - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генерируем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
PAUSE2
MOVLW D'2' ; пауза в 2 точки после буквы
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
WORD_SPACE
MOVLW D'6' ; пауза в 6 точек между словами
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
;==================================================================
; SEND_TONE
; Подпрограмма осуществляет задержку и одновременно формирует сигнал
; звуковой частоты (порт A.1)
;
SEND_TONE
MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек
MOVWF CTR_NBR ;
DIT_LENGTH
MOVF CW_SPEED, W ; CW_SPEED скорость передачи
MOVWF CTR_DIT ;
START_CYCLE
BSF PORTA,1 ; A.1=1 в начале цикла
MOVF SET_TONE,W ;
MOVWF TONE ; заносим значение в счетчик цикла задержки
HIGH_HALF
DECFSZ TONE, F ; считаем до нуля
GOTO HIGH_HALF
BCF PORTA,1 ; A.1=0 в конце цикла
MOVF SET_TONE,W ;
MOVWF TONE
LOW_HALF
DECFSZ TONE, F ;
GOTO LOW_HALF
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH ;
RETURN ;
;================================================================
; SEND_SPACE
; Делает тоже самое, что и SEND_TONE, только вместо команд управления
; портами стоит команда NOP
;
SEND_SPACE
MOVF NBR_SPACE, W ;
MOVWF CTR_NBR
DIT_LENGTH_SP
MOVF CW_SPEED, W ;
MOVWF CTR_DIT
START_CYCLE_SP
NOP
MOVF SET_TONE,W
MOVWF TONE ;
HIGH_HALF_SP
DECFSZ TONE, F ;
GOTO HIGH_HALF_SP
NOP
MOVF SET_TONE,W
MOVWF TONE
LOW_HALF_SP
DECFSZ TONE, F ;
GOTO LOW_HALF_SP
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE_SP
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH_SP ;
RETURN ;
;==================================================================
;==================================================================
; Идентификатор
ORG 0x2000 ; стартовый адрес
DATA 0x0132
DATA 0xF321
DATA 0x0000
DATA 0x0000
;==================================================================
; Слово конфигурации
ORG 0x2007 ; стартовый адрес
; DATA 0x31E4
DATA 0x1024 ; вкл защиту данных
; DATA 0x11A4
;==================================================================
; Запись в EEPROM при программировании
; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк
; может передавать последовательно три символа Морзе, четвертым обязательно
; должен быть EOM
; В последнюю адресуемую ячейку можно записать большее количество символов
ORG 0X2100 ; стартовый адрес
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x02 ; E . 00000010
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x04 ; I .. 00000100
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x08 ; S ... 00001000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x10 ; H .... 00010000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x20 ; 5 ..... 00100000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0x0A ; R .-.
DATA 0x06 ; A .-
DATA 0x3E ; 1 .----
DATA 0x06 ; A .-
DATA 0x07 ; M --
DATA 0x0F ; O ---
DATA 0xFF ; EOM 11111111
END
Вариант для управления радиостанцией, 30с/120с; 60с/60с; 1м/4м, передача позывного
; на 11 ногу можно повесить управление TX (высокий уровень при передаче)
; PIC16F630
; WDT off, intLC, MCLR on, BOR on, PWRTE on
;
list P=16F630
radix HEX
;====================================================================
; именование пользовательских регистров
;
CBLOCK 0X20 ; начальный адрес пользовательских регистров
TMPW ; временный регистр для хранения W во время прерывания
TMPS ; временный регистр для хранения STATUS
SEC_CNT ; счетчик пар секунд
MIN_CNT ; счетчик минут (пятиминуток, автовыключение)
FLAG ; регистр флагов:
; FLAG,0 разрешает передачу позывного в свое время
; FLAG,2 флаг задержки включения (1-можно работать)
; FLAG,3 флаг взводится через 5 мин после начала работы
; и отменяет задержку включения при сбросе
; FLAG,4 флаг устанавливается за 10 сек до конца цикла
DELAY ; счетчик пятиминуток, задержка включения
TX_ALL_CNT ; счетчик пар секунд в цикле
TX_OFF ; с какой секунды пауза
TX_ALL ; сколько пар секунд в цикле
SWITCH ; состояние переключателя
CHAR_INDEX ; номер передаваемого символа
CW_SPEED ; скорость передачи
; процедура SEND_TONE
NBR_DIT ; NBR_DIT кол-во пропускаемых точек
CTR_NBR ; счетчик пропускаемых точек
TONE ; счетчик частоты
SET_TONE ; установка тона передаваемого сигнала
; процедура SEND_SPACE
NBR_SPACE ; колво пропускаемых точек
CTR_DIT ; счетчик пропускаемых точек
; процедура SEND_ONE_CHAR
CW_CHAR ; передаваемый символ
ENDC
;
; Именование регистров микроконтроллера
;
CMCON EQU 0X19 ; регистр контроля компаратора
TMR0 EQU 0X01 ; timer0
TMR1L EQU 0X0E ; timer1 младший байт
TMR1H EQU 0X0F ; timer1 старший байт
T1CON EQU 0X10 ; timer1 control register
PCL EQU 0X02 ; программный счетчик
STATUS EQU 0X03 ; регистр status
FSR EQU 0X04 ; указатель адреса в памяти данных
PORTA EQU 0X05 ; порт A
PORTC EQU 0X07 ; порт C
PCLATH EQU 0X0A ; верхние 5 бит программного счетчика
INTCON EQU 0X0B ; регистр контроля прерываний
TRISA EQU 0X85 ; управляющий регистр порта A
TRISC EQU 0X87 ; управляющий регистр порта C
OPTION_REG EQU 0X81 ; регистр option
EEADR EQU 0X9B ; адресный регистр EEPROM
EECON1 EQU 0X9C ; содержит бит RD
EEDAT EQU 0X9A ; прочитанные из EEPROM данные
PCON EQU 0X8E ; регистр power control
PIE1 EQU 0X8C ; регистр контроля периферийных прерываний
PIR1 EQU 0X0C ; регистр флагов прерываний от
; периферийных модулей
;
; присвоение значений символьным константам
;
RP0 EQU 0X05 ; бит-указатель страницы данных в STATUS
W EQU 0X00 ; file register designator = W
F EQU 0X01 ; file register designator = F
Z EQU 0X02 ; бит нуля в STATUS
C EQU 0X00 ; бит преноса в STATUS
RD EQU 0X00 ; инициализация чтения EEPROM
POR EQU 0X01 ; бит POR регистра PCON обнуляется, если был
; сброс по включению питания
BOR EQU 0X00 ; сброс по снижению питания
TMR1IF EQU 0X00 ; бит переполнения TMR1 in register PIR1
TMR1ON EQU 0X00 ;
GIE EQU 0X07 ;
TMR1IE EQU 0X00 ; бит разрешения прерываний от TMR1
PON EQU 0X00 ; POWER ON IN FLAG
;
;=================================================================
; vector table
;
ORG 0X000 ; стартовый адрес
GOTO START ;
;==================================================================
; TIMER1 INTERRUPT
;
ORG 0X004 ; адрес прерывания
MOVWF TMPW ; сохраняем W
SWAPF STATUS,W
MOVWF TMPS ; сохраняем STATUS
BTFSC PIR1,0 ; прерывание от TMR1?
GOTO T1_INT ; да
NOP ; обработчик левого прерывания
GOTO END_ISR ;
T1_INT
MOVF TX_ALL_CNT,W ; вычитание
SUBWF TX_OFF,W ; TX_OFF-TX_ALL_CNT
BCF FLAG,0 ;
SKPC ; пропустить, если результат >=0
BSF FLAG,0 ;
; MOVF TX_ALL_CNT,W ; ускоряемся за 10 сек до конца цикла
; SUBLW D'125' ; ставим флаг, по которому во время передачи
; SKPNZ ; меняем скорость
; BSF FLAG,4 ; только при 5 мин цикле
; использовать либо верхнее, либо нижнее
;SUBLW D'250' ; а это костыль для ускорения за 10 сек
;SKPNZ ; до конца любого цикла, даже если
;BSF FLAG,4 ; работаем непрерывно
DECFSZ TX_ALL_CNT,F ; TX_ALL_CNT-1, пропустить, если 0
GOTO POP_TX
MOVF TX_ALL,W ; восстанавливаем
MOVWF TX_ALL_CNT ;
; BCF FLAG,4 ; в конце цикла сбросить флаг ускорения
POP_TX
DECFSZ SEC_CNT, F ; SEC_CNT-1
GOTO POP ;
MOVLW D'150' ; 300 секунд = 5 мин
MOVWF SEC_CNT
BTFSS FLAG,2 ; если задержка активирована, то
BSF FLAG,3 ; через 5 мин после запуска поднимаем флаг
; отмены задержки включения
BTFSC FLAG,2 ; если флаг разрешения работы установлен, начинаем отсчет
; задержки отключения
DECF MIN_CNT,F ; MIN_CNT-1 минуты работы считаем после
; окончании задержки включения
DECFSZ DELAY,F ; DELAY-1, пропустить след, если 0
GOTO POP ; задержка окончилась
BSF FLAG,2 ; устанавливаем флаг разрешения работы
POP
BCF PIR1,0 ; сброс флага переполнения
END_ISR
SWAPF TMPS,W ; восстанавливаем регистры W and SATUS
MOVWF STATUS ;
SWAPF TMPW,F ;
SWAPF TMPW,W ;
RETFIE ; возврат из прерывания
;==================================================================
; Начало основной программы
;==================================================================
START
MOVLW B'10001110' ;
BSF STATUS, RP0 ; bank 1
MOVWF OPTION_REG ; инициализация регистра option
BCF STATUS, RP0 ; bank 0
CLRF PORTA ; очистка порта A
CLRF PORTC ; очистка порта C
MOVLW B'00000111' ;
MOVWF CMCON ; запрещаем работу компаратора
BSF STATUS, RP0 ; bank 1
MOVLW B'00000000' ;
MOVWF TRISA ; порт A - все выходы
MOVLW B'11111111' ;
MOVWF TRISC ; порт C - все входы
BCF STATUS, RP0 ; bank 0
CLRF TMR0 ; на всякий случай. Говорят, надо...
CLRWDT ; сбрасываем WDT
;==================================================================
; инициализация TMR1
;
CLRF T1CON ; очистить TIMER1 control register
CLRF TMR1H ; очистить верхний байт TMR1
CLRF TMR1L ; очистить нижний байт TMR1
CLRF INTCON ; запретить прерывания
BSF STATUS,RP0 ; bank 1
CLRF PIE1 ; очистить рег контроля периферийных прерываний
BCF STATUS, RP0 ; bank 0
CLRF PIR1 ; очистить рег флагов периферийных прерываний
MOVLW B'00001110' ; инициализация TIMER1 control register
MOVWF T1CON ; с этого момента генератор 32.768 включен
;==================================================================
MOVLW D'150' ; инициализация счетчика пар секунд
MOVWF SEC_CNT ; 150 пар = 300 сек = 5 мин
DECF SEC_CNT,F ; имитируем прерывание
;MOVLW D'2' ; сколько пятиминуток будем работать
MOVLW D'96' ; сколько пятиминуток будем работать
MOVWF MIN_CNT ; 96х5=8 час
; MOVLW D'2' ; сколько пятиминуток задержка включения
MOVLW D'24' ; сколько пятиминуток задержка включения
MOVWF DELAY ; 24х5=120 мин
MOVLW D'178' ; тон звука, 178 ~ 1000 Гц
MOVWF SET_TONE ; чем больше, тем ниже частота
BSF FLAG,0 ; поднимаем флаг
; BCF FLAG,4
;==================================================================
; если это включение питания, то выполняется задержка для
; гарантированного запуска генератора 32768 и его инициализация
; если другой сброс, то инициализация и задержка пропускаются
;
BSF STATUS, RP0 ; bank 1
MOVF PCON,W ; PCON -> W
BCF STATUS, RP0 ; bank 0
MOVWF TMPW ; W -> TMPW
BTFSS TMPW,POR ; проверяем состояние POR, если 0, то был сброс
GOTO DELAY_START ; по включению - задержка однозначно нужна
BTFSC TMPW,BOR ; а это был сброс по снижению напр питания
GOTO SKIP_DELAY ; или не был...
DELAY_START
BCF FLAG,3 ; при первом включении очистить FLAG,3
; задержка
MOVLW D'255' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
MOVLW 0X80
MOVWF CW_CHAR ;
CALL SEND_ONE_CHAR ; в качестве задержки предаем 7 точек
BSF STATUS, RP0 ; bank 1
BSF PCON,POR ; устанавливаем POR=1
BSF PCON,BOR ; устанавливаем BOR=1
BCF STATUS, RP0 ; bank 0
SLEEP ; ожидаем запуск
SKIP_DELAY
;==================================================================
; читаем переключатель
;
BSF PORTA,2 ; на 11 ноге висят подтягивающие резисторы,
; подключенные к переключателю
; после считывания напряжение с переключателя
; снимается для экономии энергии
MOVF PORTC,W ; читаем порт C
ANDLW B'00011100' ; маска
MOVWF SWITCH ; сохраняем состояние переключателя
MOVF PORTC,W ; читаем порт C
ANDLW B'00000011' ; маска двух младших бит
BCF FLAG,2 ; обнуляем флаг задержки
BTFSC PORTC,5 ; если перекл. on (на землю, 0) пропуск. след.
BSF FLAG,2 ; устанавливаем флаг, можно работать
BCF PORTA,2 ; отключаем подтягивающие резисторы
ADDWF PCL,F ; таблица
GOTO SW00
GOTO SW01
GOTO SW10
GOTO SW11
SW00 ; непрерывно
MOVLW D'0' ; молчим последние 0 с
MOVWF TX_OFF ;
MOVLW D'30' ; цикл 60 сек
GOTO END_SW
SW01 ; цикл 30сек/120сек
MOVLW D'60' ; молчим последние 120 с
MOVWF TX_OFF ;
MOVLW D'75' ; цикл 150 сек
GOTO END_SW
SW10 ; цикл 1 мин/1 мин
MOVLW D'30' ; молчим последние 60 с
MOVWF TX_OFF ;
MOVLW D'60' ; цикл 120 сек
GOTO END_SW
SW11 ; цикл 1 мин/4 мин
MOVLW D'120' ; молчим последние 4 m
MOVWF TX_OFF ;
MOVLW D'150' ; цикл 5 m
END_SW
MOVWF TX_ALL ;
MOVWF TX_ALL_CNT ; инициализация
DECF TX_ALL_CNT,F ; считаем, что 1 прерывание уже случилось
;==================================================================
; Окончание инициализации TIMER1
;
MOVLW B'11000000' ; разрешить прерывания от периферийных модулей
MOVWF INTCON
BSF STATUS,RP0 ; bank 1
BSF PIE1,TMR1IE ; разрешить прерывания от TMR1
BCF STATUS, RP0 ; bank 0
BSF T1CON,TMR1ON ; TMR1 ON
;==================================================================
; Если с момента запуска прошло 5 мин, то при сбросе задержку
; включения игнорируем
BTFSC FLAG,3 ; FLAG,3 поднимается через 5 м после начала
; работы
BSF FLAG,2 ; задержка включения не нужна
;==================================================================
; MAIN
; передача последовательности символов
; можно предавать любое количество, 0XFF означает конец последовательности,
; после чего формируется пауза и передача циклически повторяется
;
SEND_MSG
; если автоотключение не нужно, то три
; нижеследующих строчки надо закомментировать
MOVF MIN_CNT,F ; проверяем, не обнулился ли
SKPNZ ; счетчик пятиминуток
GOTO POWER_OFF ; если да, то выключаемся
BTFSS FLAG,2 ; пропустить след, если задержка включения
; кончилась (1-разрешение работы)
GOTO FLASH ; мигнуть и sleep
BTFSS FLAG,0 ; если флаг сброшен
BSF PORTA,2 ; TX выключаем
BTFSS FLAG,0 ; если флаг сброшен, то идем спать
GOTO TO_SLEEP
BSF PORTA,2 ; на 11 ногу можно повесить управление TX
MOVF SWITCH,W
MOVWF CHAR_INDEX ; SWITCH -> CHAR_INDEX
GET_MSG
MOVF CHAR_INDEX,W
BCF INTCON,GIE ; запрещаем прерывания
BSF STATUS, RP0 ; bank 1
MOVWF EEADR ; значение CHAR_INDEX = адресу кода в EEPROM
BSF EECON1,RD ; разрешаем чтение EEPROM
MOVF EEDAT,W ; значение ячейки -> регистр W
BCF STATUS, RP0 ; bank 0
BSF INTCON,GIE ; разрешаем прерывания
;MOVLW 0x06
MOVWF CW_CHAR ; W -> CW_CHAR
MOVLW 0XFF ; конец сообщения?
SUBWF CW_CHAR,W ;
SKPNZ
GOTO END_MSG ; да, перейти к END_MSG
; MOVLW D'60' ; скорость передачи быстро
; BTFSS FLAG,4 ; устанавливается за 10 с до конца цикла
;
MOVLW D'80' ; скорость передачи медленно
MOVWF CW_SPEED ; чем больше, тем медленней
CALL SEND_CHAR ; передаем букву и паузу в 3 точки
; или паузу 6 точек, если SPACE
INCF CHAR_INDEX ; CHAR_INDEX+1
GOTO GET_MSG
END_MSG
CALL WORD_SPACE ; пауза 6 точек
GOTO SEND_MSG ;
; время работы закончилось
POWER_OFF ; отсюда выход только через RESET
CLRF FLAG ; очистка регистра флагов
CLRF T1CON ; очистить TIMER1 control register, выключаем
; генератор 32768
;BCF T1CON,TMR1ON ; TMR1 OFF
CLRF INTCON ; запретить прерывания
; после сброса считаем, что это сброс по питанию
BSF STATUS, RP0 ; bank 1
BCF PCON,POR ; устанавливаем POR=0
BCF PCON,BOR ; устанавливаем BOR=0
BCF STATUS, RP0 ; bank 0
TO_SLEEP ;
CLRF PORTA
SLEEP
NOP
GOTO SEND_MSG
;========================================================================
; индикатор включенной задержки
; мигаем порт A.1
FLASH
MOVLW D'60' ; скорость передачи
MOVWF CW_SPEED ; чем больше, тем медленней
BSF PORTA,1
MOVLW 0X01 ;
MOVWF NBR_SPACE ; пауза в 1 точку
CALL SEND_SPACE ;
BCF PORTA,1
GOTO TO_SLEEP
;========================================================================
; SEND_CHAR
; Подпрограмма получает код символа в регистре CW_CHAR, побитно перебирает
; его, и, в зависимости от состояния бита, передает: тире, если бит = 1;
; точку, если бит = 0.
; Знак передается, пока в слове есть хоть одна единица. Последняя единица
; "съедается", она означает конец слова.
;
SEND_CHAR
MOVLW 0X00 ; пауза?
SUBWF CW_CHAR,W ;
SKPNZ ;
GOTO WORD_SPACE
SEND_ONE_CHAR
BTFSS FLAG,0 ; обрываем передачу, если флаг сброшен
RETURN
CLRC ; очистить бит переноса
RRF CW_CHAR, F ; сдвиг вправо через перенос
;
MOVF CW_CHAR, F ; проверяем содержимое CW_CHAR, если все "0"
SKPNZ ; то Z=1, выполняем RETURN, иначе пропускаем
GOTO PAUSE2 ; конец буквы
SKPC ; проверить бит переноса, пропустить, если=1
GOTO SEND_A_DIT ; перейти к SEND_A_DIT
SEND_A_DAH ; передаем тире
MOVLW 0X03 ; 1 тире = 3 точки
MOVWF NBR_DIT
MOVLW 0X01 ;
MOVWF NBR_SPACE ; после тире - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генериуем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
SEND_A_DIT
MOVLW 0X01 ; передаем точку
MOVWF NBR_DIT
MOVWF NBR_SPACE ; после точки - пауза в 1 точку
BSF PORTA,0 ; включаем PORT A.2
CALL SEND_TONE ; генерируем звук, оно же - пауза
BCF PORTA,0 ; выключаем PORT A.2
CALL SEND_SPACE
GOTO SEND_ONE_CHAR
PAUSE2
MOVLW D'2' ; пауза в 2 точки после буквы
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
WORD_SPACE
MOVLW D'6' ; пауза в 6 точек между словами
MOVWF NBR_SPACE ;
CALL SEND_SPACE ;
RETURN
;==================================================================
; SEND_TONE
; Подпрограмма осуществляет задержку и одновременно формирует сигнал
; звуковой частоты (порт A.1)
;
SEND_TONE
MOVF NBR_DIT, W ; NBR_DIT кол-во пропускаемых точек
MOVWF CTR_NBR ;
DIT_LENGTH
MOVF CW_SPEED, W ; CW_SPEED скорость передачи
MOVWF CTR_DIT ;
START_CYCLE
BSF PORTA,1 ; A.1=1 в начале цикла
MOVF SET_TONE,W ;
MOVWF TONE ; заносим значение в счетчик цикла задержки
HIGH_HALF
DECFSZ TONE, F ; считаем до нуля
GOTO HIGH_HALF
BCF PORTA,1 ; A.1=0 в конце цикла
MOVF SET_TONE,W ;
MOVWF TONE
LOW_HALF
DECFSZ TONE, F ;
GOTO LOW_HALF
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH ;
RETURN ;
;================================================================
; SEND_SPACE
; Делает тоже самое, что и SEND_TONE, только вместо команд управления
; портами стоит команда NOP
;
SEND_SPACE
MOVF NBR_SPACE, W ;
MOVWF CTR_NBR
DIT_LENGTH_SP
MOVF CW_SPEED, W ;
MOVWF CTR_DIT
START_CYCLE_SP
NOP
MOVF SET_TONE,W
MOVWF TONE ;
HIGH_HALF_SP
DECFSZ TONE, F ;
GOTO HIGH_HALF_SP
NOP
MOVF SET_TONE,W
MOVWF TONE
LOW_HALF_SP
DECFSZ TONE, F ;
GOTO LOW_HALF_SP
DECFSZ CTR_DIT, F ;
GOTO START_CYCLE_SP
DECFSZ CTR_NBR, F
GOTO DIT_LENGTH_SP ;
RETURN ;
;==================================================================
;==================================================================
; Идентификатор
ORG 0x2000 ; стартовый адрес
DATA 0x0132
DATA 0xF321
DATA 0x0000
DATA 0x0000
;==================================================================
; Слово конфигурации
ORG 0x2007 ; стартовый адрес
; DATA 0x31E4
DATA 0x1024 ; вкл защиту данных
; DATA 0x11A4
;==================================================================
; Запись в EEPROM при программировании
; Переключателем адресуется номер ячейки, кратный 4. Соответственно, маяк
; может передавать последовательно три символа Морзе, четвертым обязательно
; должен быть EOM
; В последнюю адресуемую ячейку можно записать большее количество символов
ORG 0X2100 ; стартовый адрес
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0xFF ; EOM 11111111
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x02 ; E . 00000010
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x04 ; I .. 00000100
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x08 ; S ... 00001000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x10 ; H .... 00010000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x20 ; 5 ..... 00100000
DATA 0xFF ; EOM 11111111
DATA 0x07 ; M -- 00000111
DATA 0x0F ; O --- 00001111
DATA 0x03 ; T - 00000011
DATA 0xFF ; EOM 11111111
DATA 0x09 ; D
DATA 0x02 ; E
DATA 0x00 ; PAUSE
DATA 0x0A ; R .-.
DATA 0x06 ; A .-
DATA 0x3E ; 1 .----
DATA 0x06 ; A .-
DATA 0x07 ; M --
DATA 0x0E ; W ---
DATA 0x00 ; PAUSE
DATA 0x11 ; B
DATA 0x02 ; E
DATA 0x06 ; A
DATA 0x15 ; C
DATA 0x0F ; O --- 00001111
DATA 0x05 ; N
DATA 0xFF ; EOM 11111111
END
Программирование кодов Морзе
DATA 0x3F ; 0 ----- 00111111 DATA 0x3E ; 1 .---- 00111110 DATA 0x3C ; 2 ..--- 00111100 DATA 0x38 ; 3 ...-- 00111000 DATA 0x30 ; 4 ....- 00110000 DATA 0x20 ; 5 ..... 00100000 DATA 0x21 ; 6 -.... 00100001 DATA 0x23 ; 7 --... 00100011 DATA 0x27 ; 8 ---.. 00100111 DATA 0x2F ; 9 ----. 00101111 DATA 0x06 ; A .- 00000110 DATA 0x11 ; B -... 00010001 DATA 0x15 ; C -.-. 00010101 DATA 0x09 ; D -.. 00001001 DATA 0x02 ; E . 00000010 DATA 0X14 ; F ..-. 00010100 DATA 0X0B ; G --. 00001011 DATA 0x10 ; H .... 00010000 DATA 0x04 ; I .. 00000100 DATA 0x1E ; J .--- 00011110 DATA 0x0D ; K -.- 00001101 DATA 0x12 ; L .-.. 00010010 DATA 0x07 ; M -- 00000111 DATA 0x05 ; N -. 00000101 DATA 0x0F ; O --- 00001111 DATA 0x16 ; P .--. 00010110 DATA 0x1B ; Q --.- 00011011 DATA 0x0A ; R .-. 00001010 DATA 0x08 ; S ... 00001000 DATA 0x03 ; T - 00000011 DATA 0x0C ; U ..- 00001100 DATA 0x18 ; V ...- 00011000 DATA 0x0E ; W .-- 00001110 DATA 0X19 ; X -..- 00011001 DATA 0X1D ; Y -.-- 00011101 DATA 0X13 ; Z --.. 00010011 DATA 0x29 ; / -..-. 00101001 DATA 0x00 ; PAUSE 00000000 DATA 0xFF ; EOM 11111111


