'-------------------------- Описание проекта --------------------------------- 'Проект : Применение модуля захвата для вычисления периода импульса ' '-------------------------- Опции компилятора -------------------------------- Declare SHOW_SYSTEM_VARIABLES = off ' При симуляции в Proteus не показывать внутренние переменные Declare Reminders = OFF ' Выключить напоминания компилятора Declare Warnings = On ' Выключить предупреждения компилятора ;-------------------------- Общие настройки------------------------------------ Device = 16F877A ' Используемый микроконтроллер Declare Xtal = 20 ' Частота осциллятора 20 МГц ' Чем выше частота, тем выше точность измерения Symbol OSC = 4000000 '-------------------------- Конфигурация программирования -------------------- Config CP_ALL, DEBUG_OFF, WRT_OFF, CPD_ON, LVP_OFF, BODEN_OFF, PWRTE_ON, WDT_OFF, HS_OSC '-------------------------- Настройки портов --------------------------------- Declare All_Digital = On ' Установить все порты цифровыми входами/выходами Dim PERIOD As Word ' Переменная для захвата значения периода Dim PERIOD_1 As Word Dim FREQUENCY As Dword ' Переменная для расчета частоты Dim DigitDisp As Byte ' Переменная для вывода текущей цифры в порт Dim i As Word ' Переменная-счетчик Dim j As Word ' Переменная-счетчик Dim A As Word ' Счетчик фазы А Dim B As Word ' Счетчик фазы В Dim C As Word ' Счетчик фазы С Dim ZAD_VAR As Word Dim Fa As Bit Dim Fb As Bit Dim Fc As Bit Symbol Number = 2 * OSC/4 ' Постоянная величина - частота осциллятора деленная на 4 ' и умноженная на 2 (так как предделитель TMR1 = 1:8, ' а захват производится по каждому 16 фронту) Symbol PortOut = PORTC ' Порт для сегментов '-------------------------- Регистры специального назначения------------------- '-------------------------- INTCON -------------------------------------------- Symbol GIE = INTCON.7 ' Бит глобального разрешения прерываний Symbol PEIE = INTCON.6 ' Бит разрешения прерывания от периферийных устройств Symbol TOIE= INTCON.5 'разрешение прерывания tmr0 ,1=разрешено Symbol INTE= INTCON.4 'Маска внешнего прерывания 1=прерывание по входу RB0 разрешено Symbol RBIE= INTCON.3 'Розрешение прерывания по порту RB Symbol T0IF= INTCON.2 'флаг прерывания тмр0 Symbol INTF= INTCON.1 'флаг по если произошло прерывание по В.0 Symbol TIMER_1 = TMR1L.Word ' 16-разрядная переменная TMR1 '----------------------------------------------------------------------------------------- Symbol CAPTURE = PIR1.2 ' Флаг прерывания от модуля CCP Symbol TIMER_0=TMR0 Symbol CCP1IE = PIE1.2 ' Бит разрешения прерывания от модуля CCP '-------------------------- Начало ------------------------------------------- '------------LCD-----------' Declare LCD_DTPin = PORTB.0 Declare LCD_RSPin = PORTB.4 Declare LCD_ENPin = PORTB.5 Declare LCD_Interface = 4 ' 4-bit Interface Declare LCD_Lines = 2 Declare LCD_Type = 0 On_Interrupt GoTo Int_Label ' При возникновении прерывания перейти на Int_label PORTA = %00000000 ' Обнулим PORTA PORTB = %00000000 ' PORTB PORTC = %00000000 ' PORTC PORTD = %00000000 ' portd PORTE = %000 ' PORTE TRISA = %00000000 ' Порт A - на выход TRISB = %00000000 ' Порт B - на выход TRISC = %00000100 ' Порт C - на выход, за исключением вывода CCP1 TRISD = %00000000 ' Порт D - управление анодами TRISE = %000 ' Порт E - на выход OPTION_REG = %000001 ' 1:2, по переднему фронту, внутрен. синхр., подтягив резисторы вкл INTCON = 0 ' Запретим все прерывания CCP1CON = %00000101 ' Модуль CCP - в режиме захвата по каждому фронту T1CON = %00000001 ' Тактирование TMR1 от внутреннего источника предделитель 1:1 TIMER_0=0 TIMER_1 = 0 FREQUENCY = 0 PERIOD = 0 CCP1IE = 1 PEIE = 1 GIE = 1 ' Разрешение глобального прерывания 'toie=1 'разрешение прерывания тмр0 T0IF=0 ZAD_VAR=20 ' переменная заданя угла включения тиристора j=0 ' переменная подсчета колличества прерывания за период от ТМR0 Fa=0 'Флаг выдач импульса фазы А за данный период ( 1 импульс в течении периода) Fb=0 'Флаг выдач импульса фазы В за данный период ( 1 импульс в течении периода) Fc=0 'Флаг выдач импульса фазы С за данный период ( 1 импульс в течении периода) GoTo MainProgram '-------------------------- Обратный отсчет-------------------------- Int_Label: '-------------Захват периода----------------------------- If CAPTURE = 1 Then ' Проверка флага прерывания от модуля ССР PORTD.0=1 ' Для проверки в протеусе (осцолограмма) момента прерывания PERIOD = TIMER_1 ' Захват в переменную значения, которое насчитал ' TMR1 с последнего прерывания TIMER_1 = 0 ' Обнуление TMR1, чтобы он опять считал с нуля CAPTURE = 0 ' Сброс флага прерывания PORTD.0=0 TIMER_0=150 TOIE=1 'разрешение прерывания тмр0 A=0 B=0 C=0 Fa=0 'Обнуление флагов - разрешение, что в этом периоде можно выводить импульс управления тиристора Fb=0 Fc=0 j=0 EndIf If T0IF=1 Then j=j+1 T0IF=0 'сброс флага прерывания тмр0 TIMER_0=150 EndIf Context Restore ' Возврат из обработчика прерывания ' с восстановлением регистров W и Status '-------------------------- Главная программа ------------------------- MainProgram: A=ZAD_VAR - j ' определяем сдвиги (соответственно и регулируем мощность) для каждой фазы B=(ZAD_VAR +10)-j ' значения взяты условно для проверки самой идеи C=(ZAD_VAR + 15)-j If A=1 And Fa=0 Then ' определяем момент когда необходимо выдать управляющий импульс запуска тиристора фазы А PORTD.1=1 Fa=1 Else PORTD.1=0 EndIf If B=1 And Fb=0 Then PORTD.2=1 Fb=1 Else PORTD.2=0 EndIf If C=1 And Fc=0 Then PORTD.3=1 Fc=1 j=0 'TOIE=1 Else PORTD.3=0 EndIf GoTo MainProgram End