//;--------------------------------- "ШАПКА" ПРОГРАММЫ ----------------------------------------
//;*********************************************************************************************
//; Файл текста программы: cus_1.asm ВАРИАНТ КОММЕНТАРИЯ № 1
//; Программа разработана для устройства тонального вызова с частотой 1450 Гц.
//;*********************************************************************************************
//; Автор: Корабельников Евгений Александрович г.Липецк, январь 2005г.
//; E-mail: karabea@lipetsk.ru URL:
http://ikarab.narod.ru //;*********************************************************************************************
//; Используется микроконтроллер PIC16F84A. Частота кварца 4000кГц.
//;*********************************************************************************************
//; Объем программы: 46 слов в памяти программ.
//;*********************************************************************************************
// LIST p=16F84A ; Назначение типа ПИКа: PIC16F84A.
// __CONFIG 03FF5H ; Установка битов конфигурации: стандартный XT-генератор,
// ; WDT включен, бит защиты не установлен, таймер включения
// ; питания отключен (0000 0101).
#include<16f628.h>
#use delay (clock=4M)
#fuses XT, WDT,NOPROTECT,NOPUT
#opt 9
//;=============================================================================================
//; Определение адресов регистров специального назначения.
//;=============================================================================================
//OptionR equ 01h ; Регистр Option - банк1
//Status equ 03h ; Регистр Status
//PortB equ 06h ; Порт B
//TrisB equ 06h ; Регистр Tris B - Банк1
//IntCon equ 0Bh ; Регистр IntCon
#byte OPTION = 0x81
#byte TRISB = 0x86
#byte INTCON = 0x0B
#byte STATUS = 0x03
#byte PORTB = 0x06
#bit RB0 = 0x06.0
#bit RB1 = 0x06.1
#bit RB2 = 0x06.2
#bit RB3 = 0x06.3
#bit RB4 = 0x06.4
#bit RB5 = 0x06.5
#bit RB6 = 0x06.6
#bit RB7 = 0x06.7
//;=============================================================================================
//; Определение названия и адресов регистров общего назначения.
//;=============================================================================================
//Sec equ 0Ch ; Счетчик времени полупериода.
//SecH equ 0Dh ; Старший байт таймера.
//SecL equ 0Eh ; Младший байт таймера.
#locate Sec=0x20
#locate SecL=0x21
#locate SecH=0x22
//;=============================================================================================
//; Присвоение буквенного обозначения операции направления результата выполнения команды в
//; регистр, с содержимым которого производится действие (для удобства восприятия текста
//; программы).
//;=============================================================================================
//F equ 1 ; Результат направить в регистр, с содержимым которого
// ; производится действие.
//;=============================================================================================
//; Присвоение биту выбора банка регистра STATUS (пятому) его стандартного названия
//; для удобства восприятия текста программы).
//;=============================================================================================
//RP0 equ 5 ; Присвоение 5-му биту STATUS (выбор банка) названия RP0.
//;=============================================================================================
//; Определение точки входа в программу.
//;=============================================================================================
// org 0 ; Начать выполнение программы
// goto START ; с первой команды подпрограммы START.
//;*********************************************************************************************
//;------------------------------- РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ -----------------------------------
//;*********************************************************************************************
//; Подготовительные операции.
//;---------------------------------------------------------------------------------------------
//START clrf IntCon ; Запрещение всех прерываний.
void main() {
START:
INTCON=0;
// clrwdt ; Сброс сторожевого таймера WDT.
restart_wdt();
// bsf Status,RP0 ; Установка банка 1.
// movlw .65 ; RB0,RB6 работают на вход, (.65 = 0100 0001)
// movwf TrisB ; остальные - на выход.
TRISB=0b01000001;
// movlw .143 ; Выключение подтягивающих резисторов порта В.
// movwf OptionR ; Предделитель включен перед WDT с Кдел.=128
// ; (18мс.*128=2,3сек.), остальное - не важно.
// ; (.143 = 1000 1111)
OPTION=0b10001111;
// bcf Status,RP0 ; Установка банка 0.
//;--------------------------------------------------------------------------------------------
//; Запись констант времени работы таймера.
//;--------------------------------------------------------------------------------------------
// movlw .15 ; Запись в регистр SecH
// movwf SecH ; константы .15
SecH=15;
// movlw .255 ; Запись в регистр SecL
// movwf SecL ; константы .255
SecL=255;
//;--------------------------------------------------------------------------------------------
//; Проверка наличия включения на передачу (опрос клавиатуры).
//;--------------------------------------------------------------------------------------------
//CYCLE btfsc PortB,0 ; Если передача не включена(1) - переход в ПП START.
// goto START ; Если включена(0) - программа исполняется далее.
CYCLE:
if(RB0==1) goto START;
//;--------------------------------------------------------------------------------------------
//; Проверка: режим тонального вызова включен или выключен ?
//;--------------------------------------------------------------------------------------------
// btfss PortB,6 ; Если режим тонального вызова выключен(0) - уход в PRD.
// goto PRD ; Если включен(1) - программа исполняется далее.
if(RB6==0) goto PRD;
//;--------------------------------------------------------------------------------------------
//; Формирование времени отрицательного полупериода сигнала тонального вызова.
//;--------------------------------------------------------------------------------------------
// bcf PortB,2 ; Начало формирования отрицательного полупериода.
RB2=0;
// nop ; Пустые машинные циклы точной калибровки
// nop ; времени отрицательного полупериода (точная доводка).
// nop ; ----------------------"------------------------
delay_cycles(3);
// movlw .85 ; Запись в регистр Sec
// movwf Sec ; константы .85
Sec=85;
//PAUSE_1 clrwdt ; Сброс сторожевого таймера WDT.
//PAUSE_1:
//restart_wdt();
// decfsz Sec,F ;(--), if==1->goto "Грубый" отсчет интервала времени
// goto PAUSE_1 ; отрицательного полупериода.
//Sec--;
//if(Sec) goto PAUSE_1;
do{
restart_wdt();
Sec--;
}
while(Sec>0);
//;--------------------------------------------------------------------------------------------
//; Формирование времени положительного полупериода сигнала тонального вызова.
//;--------------------------------------------------------------------------------------------
// bsf PortB,2 ; Начало формирования положительного полупериода.
RB2=1;
// nop ; Пустые машинные циклы точной калибровки
// nop ; времени положительного полупериода (точная доводка).
// nop ; ----------------------"----------------------
delay_cycles(3);
// movlw .83 ; Запись в регистр Sec
// movwf Sec ; константы .83
Sec=83;
//PAUSE_2 clrwdt ; Сброс сторожевого таймера WDT.
PAUSE_2:
restart_wdt();
// decfsz Sec,F ; "Грубый" отсчет интервала времени
// goto PAUSE_2 ; положительного полупериода.
Sec--;
if(Sec==1) goto PAUSE_2;
//;--------------------------------------------------------------------------------------------
//; "Очистка" (декремент) таймера.
//;--------------------------------------------------------------------------------------------
// decfsz SecL,F ; Декремент содержимого регистра SecL.
// goto CYCLE ; Если результат декремента не=0 - переход на ПП CYCLE.
// ; Если результат декремента =0 - программа исполняется далее.
//SecL--;
if(SecL--) goto CYCLE;
// decfsz SecH,F ; Декремент содержимого регистра SecH.
// goto CYCLE ; Если результат декремента не=0 - переход на ПП CYCLE.
// ; Если результат декремента =0 - программа исполняется далее.
SecH--;
if(SecH==1) goto CYCLE;
// bcf PortB,2 ; Установить на выходе RB2 ноль.
RB2=0;
//;--------------------------------------------------------------------------------------------
//; Уход рабочей точки программы в "вечное" кольцо и выход из него после
//; переключения р/станции с передачи на прием.
//;--------------------------------------------------------------------------------------------
//PRD clrwdt ; Сброс сторожевого таймера WDT.
PRD:
restart_wdt();
// btfss PortB,0 ; Передача включена?
// goto PRD ; Если да, то переход на ПП PRD.
// ; Если нет, то программа исполняется далее.
if(RB0==0) goto PRD;
//; Еще одна проверка.
// btfss PortB,0 ; Передача включена?
// goto PRD ; Если да, то переход на ПП PRD.
if(RB0==0) goto PRD;
// goto START ; Конец полного цикла программы, переход на
// ; новый полный цикл программы.
goto START;
//;============================================================================================
// end ; Конец программы.
//---436 byte----
}
//////////////////////////////////////
//////////////////////////////////
CCS PCM C Compiler, Version 4.084, 36728 16-фев-11 23:32
Filename: E:\MK\project\ N2_cus_1_asm--C\N2_cus_1_asm--C.lst
ROM used: 63 words (3%) (Объем программы asm: 46 слов в памяти программ.)
Largest free fragment is 1985
RAM used: 10 (4%) at main() level
10 (4%) worst case
Stack: 0 locations
*
0000: MOVLW 00
0001: MOVWF 0A
0002: GOTO 004
0003: NOP
....................
.................... //;--------------------------------- "ШАПКА" ПРОГРАММЫ ----------------------------------------
.................... //;*********************************************************************************************
.................... //; Файл текста программы: cus_1.asm ВАРИАНТ КОММЕНТАРИЯ № 1
.................... //; Программа разработана для устройства тонального вызова с частотой 1450 Гц.
.................... //;*********************************************************************************************
.................... //; Автор: Корабельников Евгений Александрович г.Липецк, январь 2005г.
.................... //; E-mail: karabea@lipetsk.ru URL:
http://ikarab.narod.ru .................... //;*********************************************************************************************
.................... //; Используется микроконтроллер PIC16F84A. Частота кварца 4000кГц.
.................... //;*********************************************************************************************
.................... //; Объем программы: 46 слов в памяти программ.
.................... //;*********************************************************************************************
.................... // LIST p=16F84A ; Назначение типа ПИКа: PIC16F84A.
.................... // __CONFIG 03FF5H ; Установка битов конфигурации: стандартный XT-генератор,
.................... // ; WDT включен, бит защиты не установлен, таймер включения
.................... // ; питания отключен (0000 0101).
.................... #include<16f628.h>
.................... //////// Standard Header file for the PIC16F628 device ////////////////
.................... #device PIC16F628
.................... #list
....................
.................... #use delay (clock=4M)
.................... #fuses XT, WDT,NOPROTECT,NOPUT
.................... #opt 9
.................... //;=============================================================================================
.................... //; Определение адресов регистров специального назначения.
.................... //;=============================================================================================
.................... //OptionR equ 01h ; Регистр Option - банк1
.................... //Status equ 03h ; Регистр Status
.................... //PortB equ 06h ; Порт B
.................... //TrisB equ 06h ; Регистр Tris B - Банк1
.................... //IntCon equ 0Bh ; Регистр IntCon
.................... #byte OPTION = 0x81
.................... #byte TRISB = 0x86
.................... #byte INTCON = 0x0B
.................... #byte STATUS = 0x03
.................... #byte PORTB = 0x06
.................... #bit RB0 = 0x06.0
.................... #bit RB1 = 0x06.1
.................... #bit RB2 = 0x06.2
.................... #bit RB3 = 0x06.3
.................... #bit RB4 = 0x06.4
.................... #bit RB5 = 0x06.5
.................... #bit RB6 = 0x06.6
.................... #bit RB7 = 0x06.7
.................... //;=============================================================================================
.................... //; Определение названия и адресов регистров общего назначения.
.................... //;=============================================================================================
.................... //Sec equ 0Ch ; Счетчик времени полупериода.
.................... //SecH equ 0Dh ; Старший байт таймера.
.................... //SecL equ 0Eh ; Младший байт таймера.
.................... #locate Sec=0x20
.................... #locate SecL=0x21
.................... #locate SecH=0x22
.................... //;=============================================================================================
.................... //; Присвоение буквенного обозначения операции направления результата выполнения команды в
.................... //; регистр, с содержимым которого производится действие (для удобства восприятия текста
.................... //; программы).
.................... //;=============================================================================================
.................... //F equ 1 ; Результат направить в регистр, с содержимым которого
.................... // ; производится действие.
.................... //;=============================================================================================
.................... //; Присвоение биту выбора банка регистра STATUS (пятому) его стандартного названия
.................... //; для удобства восприятия текста программы).
.................... //;=============================================================================================
.................... //RP0 equ 5 ; Присвоение 5-му биту STATUS (выбор банка) названия RP0.
.................... //;=============================================================================================
.................... //; Определение точки входа в программу.
.................... //;=============================================================================================
.................... // org 0 ; Начать выполнение программы
.................... // goto START ; с первой команды подпрограммы START.
.................... //;*********************************************************************************************
....................
.................... //;------------------------------- РАБОЧАЯ ЧАСТЬ ПРОГРАММЫ -----------------------------------
.................... //;*********************************************************************************************
.................... //; Подготовительные операции.
.................... //;---------------------------------------------------------------------------------------------
.................... //START clrf IntCon ; Запрещение всех прерываний.
.................... void main() {
0004: CLRF 04
0005: BCF 03.7
0006: MOVLW 1F
0007: ANDWF 03,F
0008: MOVLW 07
0009: MOVWF 1F
.................... START:
.................... INTCON=0;
000A: CLRF 0B
.................... // clrwdt ; Сброс сторожевого таймера WDT.
.................... restart_wdt();
000B: CLRWDT
.................... // bsf Status,RP0 ; Установка банка 1.
....................
.................... // movlw .65 ; RB0,RB6 работают на вход, (.65 = 0100 0001)
.................... // movwf TrisB ; остальные - на выход.
.................... TRISB=0b01000001;
000C: MOVLW 41
000D: BSF 03.5
000E: MOVWF 06
.................... // movlw .143 ; Выключение подтягивающих резисторов порта В.
.................... // movwf OptionR ; Предделитель включен перед WDT с Кдел.=128
.................... // ; (18мс.*128=2,3сек.), остальное - не важно.
.................... // ; (.143 = 1000 1111)
.................... OPTION=0b10001111;
000F: MOVLW 8F
0010: MOVWF 01
.................... // bcf Status,RP0 ; Установка банка 0.
.................... //;--------------------------------------------------------------------------------------------
.................... //; Запись констант времени работы таймера.
.................... //;--------------------------------------------------------------------------------------------
.................... // movlw .15 ; Запись в регистр SecH
.................... // movwf SecH ; константы .15
.................... SecH=15;
0011: MOVLW 0F
0012: BCF 03.5
0013: MOVWF 22
.................... // movlw .255 ; Запись в регистр SecL
.................... // movwf SecL ; константы .255
.................... SecL=255;
0014: MOVLW FF
0015: MOVWF 21
.................... //;--------------------------------------------------------------------------------------------
.................... //; Проверка наличия включения на передачу (опрос клавиатуры).
.................... //;--------------------------------------------------------------------------------------------
.................... //CYCLE btfsc PortB,0 ; Если передача не включена(1) - переход в ПП START.
.................... // goto START ; Если включена(0) - программа исполняется далее.
.................... CYCLE:
.................... if(RB0==1) goto START;
0016: BTFSC 06.0
0017: GOTO 00A
.................... //;--------------------------------------------------------------------------------------------
.................... //; Проверка: режим тонального вызова включен или выключен ?
.................... //;--------------------------------------------------------------------------------------------
.................... // btfss PortB,6 ; Если режим тонального вызова выключен(0) - уход в PRD.
.................... // goto PRD ; Если включен(1) - программа исполняется далее.
.................... if(RB6==0) goto PRD;
0018: BTFSS 06.6
0019: GOTO 038
.................... //;--------------------------------------------------------------------------------------------
.................... //; Формирование времени отрицательного полупериода сигнала тонального вызова.
.................... //;--------------------------------------------------------------------------------------------
.................... // bcf PortB,2 ; Начало формирования отрицательного полупериода.
.................... RB2=0;
001A: BCF 06.2
.................... // nop ; Пустые машинные циклы точной калибровки
.................... // nop ; времени отрицательного полупериода (точная доводка).
.................... // nop ; ----------------------"------------------------
.................... delay_cycles(3);
001B: GOTO 01C
001C: NOP
.................... // movlw .85 ; Запись в регистр Sec
.................... // movwf Sec ; константы .85
.................... Sec=85;
001D: MOVLW 55
001E: MOVWF 20
.................... //PAUSE_1 clrwdt ; Сброс сторожевого таймера WDT.
.................... //PAUSE_1:
.................... //restart_wdt();
.................... // decfsz Sec,F ;(--), if==1->goto "Грубый" отсчет интервала времени
.................... // goto PAUSE_1 ; отрицательного полупериода.
.................... //Sec--;
.................... //if(Sec) goto PAUSE_1;
.................... do{
.................... restart_wdt();
001F: CLRWDT
.................... Sec--;
0020: DECF 20,F
.................... }
.................... while(Sec>0);
0021: MOVF 20,F
0022: BTFSS 03.2
0023: GOTO 01F
.................... //;--------------------------------------------------------------------------------------------
.................... //; Формирование времени положительного полупериода сигнала тонального вызова.
.................... //;--------------------------------------------------------------------------------------------
.................... // bsf PortB,2 ; Начало формирования положительного полупериода.
.................... RB2=1;
0024: BSF 06.2
.................... // nop ; Пустые машинные циклы точной калибровки
.................... // nop ; времени положительного полупериода (точная доводка).
.................... // nop ; ----------------------"----------------------
.................... delay_cycles(3);
0025: GOTO 026
0026: NOP
.................... // movlw .83 ; Запись в регистр Sec
.................... // movwf Sec ; константы .83
.................... Sec=83;
0027: MOVLW 53
0028: MOVWF 20
.................... //PAUSE_2 clrwdt ; Сброс сторожевого таймера WDT.
.................... PAUSE_2:
.................... restart_wdt();
0029: CLRWDT
.................... // decfsz Sec,F ; "Грубый" отсчет интервала времени
.................... // goto PAUSE_2 ; положительного полупериода.
.................... Sec--;
002A: DECF 20,F
.................... if(Sec==1) goto PAUSE_2;
002B: DECFSZ 20,W
002C: GOTO 02E
002D: GOTO 029
.................... //;--------------------------------------------------------------------------------------------
.................... //; "Очистка" (декремент) таймера.
.................... //;--------------------------------------------------------------------------------------------
.................... // decfsz SecL,F ; Декремент содержимого регистра SecL.
.................... // goto CYCLE ; Если результат декремента не=0 - переход на ПП CYCLE.
.................... // ; Если результат декремента =0 - программа исполняется далее.
.................... //SecL--;
.................... if(SecL--) goto CYCLE;
002E: MOVF 21,W
002F: DECF 21,F
0030: XORLW 00
0031: BTFSS 03.2
0032: GOTO 016
.................... // decfsz SecH,F ; Декремент содержимого регистра SecH.
.................... // goto CYCLE ; Если результат декремента не=0 - переход на ПП CYCLE.
.................... // ; Если результат декремента =0 - программа исполняется далее.
.................... SecH--;
0033: DECF 22,F
.................... if(SecH==1) goto CYCLE;
0034: DECFSZ 22,W
0035: GOTO 037
0036: GOTO 016
.................... // bcf PortB,2 ; Установить на выходе RB2 ноль.
.................... RB2=0;
0037: BCF 06.2
.................... //;--------------------------------------------------------------------------------------------
.................... //; Уход рабочей точки программы в "вечное" кольцо и выход из него после
.................... //; переключения р/станции с передачи на прием.
.................... //;--------------------------------------------------------------------------------------------
.................... //PRD clrwdt ; Сброс сторожевого таймера WDT.
.................... PRD:
.................... restart_wdt();
0038: CLRWDT
.................... // btfss PortB,0 ; Передача включена?
.................... // goto PRD ; Если да, то переход на ПП PRD.
.................... // ; Если нет, то программа исполняется далее.
.................... if(RB0==0) goto PRD;
0039: BTFSS 06.0
003A: GOTO 038
.................... //; Еще одна проверка.
.................... // btfss PortB,0 ; Передача включена?
.................... // goto PRD ; Если да, то переход на ПП PRD.
.................... if(RB0==0) goto PRD;
003B: BTFSS 06.0
003C: GOTO 038
.................... // goto START ; Конец полного цикла программы, переход на
.................... // ; новый полный цикл программы.
.................... goto START;
003D: GOTO 00A
.................... //;============================================================================================
.................... // end ; Конец программы.
.................... //---436 byte----
....................
.................... }
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
003E: SLEEP
Configuration Fuses:
Word 1: 3F6D XT WDT NOPUT NOPROTECT BROWNOUT MCLR NOLVP NOCPD