Статья №15
Рассматривая применение таймеров микроконтроллеров AVR в свете Bascom, мы не затронули вопроса организации счёта внешних импульсов, которые могут приходить на вход ТО (PORTD.4) для Timer0 и ТО1 (PORTD.5) для Timer1.
Для работы в данном режиме конфигурация Timer0 должна быть следующей:
Config Timer0 = Counter, Prescale=1|8|64|256|1024, Edge= Falling|Rising
Здесь Edge – конфигурирование внешних импульсов, считывание которых происходит либо по спаду – Falling, либо по фронту – Rising. PORTD.4, естественно, необходимо сконфигурировать как вход:
Config PORTD.4 = Output
Счёт импульсов происходит от нижнего значения – ВОТТОМ, которое может варьироваться, до переполнения счётчика – 0xFF. Далее счётчик сбрасывается до ВОТТОМ и снова считает до значения 0xFF.
Ниже приведёна, как пример, программа «Timer0», где значение ВОТТОМ равно некой константе Z (=120), которая задаётся таймеру в начале программы и в подпрограмме обработки прерываний по переполнению. Изменяя значение константы, можно задавать различные временные интервалы и регистрировать определенное количество внешних импульсов.
В основном цикле программы значения Timer0 считываются при низком логическом уровне на выводе PD4 и выводятся на ЖКИ – индикатор.
Текст программы приведён ниже:
$regfile = "attiny2313a.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32
Config Pind.4 = Input 'вход ТО
Config Portb.2 = Output 'выход ОС0А
Config Timer0 = Counter , Prescale = 1 , Edge = Falling 'счётчик ‘внеш.имп,синхронизир. по спаду
Const Z = 120 ' нижний предел счёта ВОТТОМ
Stop Timer0 'начальные установки
Timer0 = Z
Reset Portb.2
Dim Counters As Byte 'объявление переменной
On Timer0 Pulse 'определение подпрограммы обраб. прерываний
Enable Interrupts 'разрешение прерываний
Enable Timer0 'по переполнению
Start Timer0 'пуск таймера
Do 'основной цикл
If Portd.4 = 0 Then 'если на РD4-лог.0
Counters = Timer0 ' то считывание значений тaймера
End If
Cls
Lcd "count= " ; Counters 'вывод на ЖКИ
Loop
Pulse: 'подпрограмма обр. прерыв. по переполнению
Stop Timer0
Toggle Portb.2 'переключение РВ.2
Timer0 = Z 'задание ВОТТОМ на след. цикл
Start Timer0
Return
End 'end program
Сконфигурировать Timer1 для счёта импульсов, приходящих на вход ТО1, можно следующим образом:
Config Timer1=Counter, Prescale=1, Edge=Falling, Compare A=Toggle, Clear Timer=1
Подробно все команды в конфигурации описаны в предыдущей статье (№14).
Применяя метод подсчёта внешних импульсов, можно улучшить схему регулятора мощности, схема которого была представлена в статье №14. Так как теперь импульсы синхронизации с началом полупериодов сетевого напряжения подаются не на вход внешнего прерывания (INT0), а на ТО1, то можно осуществлять регулирование мощности в процессе работы устройства, не отключая подачу синхроимпульсов на контроллер. Т.е тумблер в новой схеме не нужен.
Схема данного регулятора мощности изображена на Рис.1.
Программа «Timer1», которую необходимо будет запихнуть в контроллер, состоит из уже известной вам подпрограммы обработки прерываний по приёму. Здесь задаётся первоначальное количество импульсов, определяющих длительность сигнала лог.1 в ШИМ. Следует отметить, что данном случае во избежание появления в сетевом напряжении постоянной составляющей, задаются только чётные значения величин количества полупериодов. Здесь же включается светодиод.
В подпрограмме обработки прерываний по совпадению рассчитывается количество полупериодов для остальной части ШИМ – сигнала (лог.0): Nновое=10 – Nпрежнее, и переключается светодиод.
В следующем цикле выражением N = 10 – N снова задается количество полупериодов сетевого напряжения сигнала лог.1.
В основном цикле DO…Loop cчитывается значение Timer1 и выводится на ЖКИ – индикатор.
Текст программы “Timer1” приведён ниже:
$regfile = "attiny2313a.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32
Config Portd.6 = Output 'светодиод
Config Pind.5 = Input 'ТО1- вход синхроимпульсов
Config Portb.3 = Output 'ОС1А- нагрузка
Config Pinb.0 = Input 'RXD
Config Portb.1 = Output 'TXD
'счёт внешних импульсов по спаду, перекл. ОС1А при счёте=Compare1A и ‘очистка таймера
Config Timer1 = Counter , Prescale = 1 , Edge = Falling , Compare A = Toggle , Clear Timer = 1
Stop Timer1 'задание начальных условий
Timer1 = 0
Compare1a = 2 ’небоходимо задать,чтобы не было совпадения по 0
Reset Portb.3
Reset Portd.6
Dim Counters As Byte 'объявление переменных
Dim N As Byte
On Urxc Rxd 'определение подпрограмм обраб. прерыв.
On Timer1 Pulse
Enable Interrupts 'разрешение прерываний
Enable Urxc 'по приёму
Enable Timer1 'по совпадению
Do 'основной цикл
If Portd.5 = 0 Then 'если РD5=0,счит.знач.счётчика
Counters = Timer1
End If
Cls
Lcd "count= " ; Counters 'вывод на ЖКИ знач. счётчика
Loop
Rxd: 'обработка прер.по приёму
Reset Portb.3
Reset Portd.6 'отключение нагрузки и светодиода
Input "ENTER N=2,4,6,8 =" , N 'задание первонач. кол-ва полупупериодов
Compare1a = N 'запись в регистр сравнения
Set Portb.3
Set Portd.6 'включение нагрузки и светодиода
Start Timer1
Return
Pulse: 'обработ. прер. по совпадению
Stop Timer1
N = 10 - N 'пересчёт числа полупериодов
Compare1a = N 'запись нового числа полупериодов
Timer1 = 0
Toggle Portd.6 'переключение светодиода
Start Timer1
Return
End 'end program
Программы находятся в приложении 1.