Пока на ум приходит использовать второй таймер, по прерыванию которого отключать все сегменты.
BASCOM AVR в вопросах и ответах
Подскажите, кто как реализовывал регулировку яркости придинамической индикации?
Пока на ум приходит использовать второй таймер, по прерыванию которого отключать все сегменты.
Пока на ум приходит использовать второй таймер, по прерыванию которого отключать все сегменты.
Все делают ошибки, только мудрецы - новые, а дураки - старые.
- Реклама
http://arv.radioliga.com/content/view/101/49/kip96 писал(а):Подскажите, кто как реализовывал регулировку яркости придинамической индикации?
Только в баскоме я не ШИМ режим настраивал а просто один таймер конфигурировал на два прерывания. По совпадению и по переполнению. Главное, дописать Clear Timer = 0, чтобы таймер при совпадении не сбрасывался. В железе все работает великолепно.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Идею понял, но никак не врублюсь , как в баскоме это сделать. Как таймер на два прерывания оформить?, при Compare a управляется вывод OC1A.
Все делают ошибки, только мудрецы - новые, а дураки - старые.
Ну генерация на выводе-то нам зачем? Сейчас покажу. Убрал всякие порты и прочее, и так понятно. Цифры включаются в прерывании по совпадению, индикация обновляется каждые 4 мс (250 Гц). При чем, частота остается стабильной что бы нибыло записано в регистр сравнения. Потому как что от 10 до 10 и что от 250 до 250 - все равно 255 тиков. А вот в прерывании переполнения индикатор гасится. Таким образом при одинаковой частоте обновления регулируем время свечения. Допустим, в регистре сравнения записано 10. Таймер считает, при 10 уходим и зажигаем цифру. А при 255 (переполнение) - ее гасим. Горела она от 10 до 255. То бишь яркость почти максимальная. Теперь загружаем 230. Таймер считает, но цифра включится только при 230. И гореть будет от 230 до 255. Затем погаснет. Яркость почти минимальная. Главное, при совпадении не сбрасывать счетный регистр.kip96 писал(а):Идею понял, но никак не врублюсь , как в баскоме это сделать. Как таймер на два прерывания оформить?, при Compare a управляется вывод OC1A.
Код: Выделить всё
$regfile = "attiny2313.dat" ' тип МК
$crystal = 4000000 ' выбор кристала для расчета задержек
'***[Определение переменных и констант]***
Dim Count As Byte
Dim I(3) As Byte ' три разряда
'***[Инициализация прерываний]***
' конфигурируем таймер (ТАЙМЕР ПРИ СОВПАДЕНИИ НЕ СБРАСЫВАЕМ)
Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0
On Oc0a Refresh ' обзываем прерывание индикации
On Ovf0 Res_ind ' гашение индикации
Ocr0a = 100 ' регистр совпадения
Enable Interrupts ' разрешаем все прерывания
Enable Oc0a ' и для таймера в частности
Enable Ovf0
'***[Присвоение уникальных имен]***
Dig1 Alias Portd.4 ' обзываем разряды
Dig2 Alias Portd.5
Dig3 Alias Portd.6
'***[Начало основной программы]***
I(1) = 3
I(2) = 2
I(3) = 1
Do
Loop
End
'***[Процедуры обработки прерываний]***
Refresh: ' прерывание индикации (каждые 4 мс)
Reset Dig1 : Reset Dig2 : Reset Dig3
Incr Count : If Count > 3 Then Count = 1
Portb = Lookup(i(count) , Digits)
Select Case Count
Case 1 : Set Dig1
Case 2 : Set Dig2
Case 3 : Set Dig3
End Select
Return
'-------------------------
Res_ind: ' прерывание по переполнению
Reset Dig1 : Reset Dig2 : Reset Dig3
Return
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Можно кстати наоборот по переполнению сделать индикацию (как обычно) а по совпадению - гашение. Суть та же но привычнее будет 0 - минимальная яркость а 254 - максимальная. 
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
- Реклама
Всё понял. спасибо.
Вот про эту On Oc0a Refresh бяку не знал, в хелпе пробижался -не встретил.
On Ovf0 Res_ind а эт, я так понял, равно как On Timer0 Res_ind.
Вот про эту On Oc0a Refresh бяку не знал, в хелпе пробижался -не встретил.
On Ovf0 Res_ind а эт, я так понял, равно как On Timer0 Res_ind.
У меня , кстати так и вышло, я ж сначало индикацию сделал, а потом яркость мудрилedm2007 писал(а):Можно кстати наоборот по переполнению сделать индикацию (как обычно) а по совпадению - гашение
Все делают ошибки, только мудрецы - новые, а дураки - старые.
Да, все верно, в баскоме TIMER0 это то же самое что OVF0 (overflow - переполнение).kip96 писал(а):On Ovf0 Res_ind а эт, я так понял, равно как On Timer0 Res_ind.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
To edm2007: Привет! Я тут на основании твоей индикации попытался частотомер забабахать, но только чегой-то он всякую фигню кажет. Просмотри код пожалуйста на предмет ошибок и косяков.
Схему не выкладываю - там все то же самое, что и у тебя, только вместо ATTINY2313 поставил ATMEGA48 - это для дальнейших целей (планируется цифровой генератор сигнала с индикацией частоты и управлением энкодером). Импульсы считаются по прерываниям INT1 и TIMER1.
Код: Выделить всё
$regfile = "m48def.dat" ' тип МК
$crystal = 400000 ' выбор кристала для расчета задержек
'*****************************************[Определение переменных и констант]************************************
Dim I(8) As Byte ' 8 разрядов
Dim Count As Byte ' переменная для работы с индикацией
Dim Ledout As Byte ' переменная для загрузки в регистры сдвига
Dim F As Integer , F1 As Integer
F = 0
'***********************************************[Инициализация портов]*******************************************
Config Portb = Output
'*********************************************[Инициализация прерываний]*****************************************
Config Int1 = Rising
On Int1 Schet
Config Timer1 = Timer , Prescale = 64
On Timer1 Frequency
Config Timer0 = Timer , Prescale = 64 ' конфигурируем таймер индикации (~250 Гц)
On Timer0 Refresh ' обзываем прерывание
Enable Interrupts ' разрешаем все прерывания
Enable Int1
Enable Timer0 ' и для таймера в частности
Enable Timer1
'********************************************[Присвоение уникальных имен]****************************************
595data Alias Portb.1 : 595takt Alias Portb.2 : 595latch Alias Portb.0 ' выводы 74HC595
'*********************************************[Начало основной программы]****************************************
Do
Loop
'***********************************[Процедуры обработки подпрограмм и прерываний]*******************************
Schet:
Incr F
Return
Frequency:
Stop Timer1
I(1) = F / 10000000
I(2) = F / 1000000
I(3) = F / 100000
I(4) = F / 10000
I(5) = F / 1000
I(6) = F / 100
I(7) = F / 10
I(8) = F Mod 10
Timer1 = &HCFFF
Start Timer1
F = 0
Return
Refresh: ' прерывание таймера Т0 (переполнение каждые ~4 мс)
Incr Count : If Count > 8 Then Count = 1 ' выбираем какой разряд сейчас включать
Ledout = Lookup(i(count) , Digits) ' забираем код цифры
If Count = 2 Or Count = 5 Or Count = 8 Then ' в 2, 5 и 8 разряде ставим точки
Ledout = Ledout Xor &B00000001
End If
Shiftout 595data , 595takt , Ledout ' закидываем в регистр
Ledout = Lookup(count , Rank) ' забираем номер разряда
Shiftout 595data , 595takt , Ledout ' закидываем в регистр
Set 595latch ' защелкиваем всю эту кучу
Reset 595latch
Return
'******************************************************[DATA]****************************************************
Digits: ' цифры
Data &B11111100 , &B01100000 , &B11011010 , &B11110010 , &B01100110 ' 0 1 2 3 4
Data &B10110110 , &B10111110 , &B11100000 , &B11111110 , &B11100110 ' 5 6 7 8 9
'-------------------------
Rank: ' разряды
Data &B11111111 ' выкл
Data &B11111110 , &B11111101 , &B11111011 , &B11110111 ' 1 2 3 4
Data &B11101111 , &B11011111 , &B10111111 , &B01111111 ' 5 6 7 8
'****************************************************************************************************************
Цапу крутить надо!!! Ку или не ку?
Igor_67, привет. Разумеется, ерунду будет показывать. Ты как по разрядам-то раскидываешь? Если переменная F равна 1234, например?
Что он по указателю 123 считает?
P.S. Кварц неверно указан, кстати. Нуля не хватает... А вобще, проверка в железе показала что индикация работоспособна (спасибо Александру (saschai)), но частоту стоит выставить на 8 МГц, при 4 мерцание видно.
Код: Выделить всё
I(7) = F / 10
P.S. Кварц неверно указан, кстати. Нуля не хватает... А вобще, проверка в железе показала что индикация работоспособна (спасибо Александру (saschai)), но частоту стоит выставить на 8 МГц, при 4 мерцание видно.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Впрочем, при отсутствии счета нули в любом случае должны быть. А чего не таймер в режиме Counter?
P.S. И еще, у массива должен быть такой же тип как и у переменной, с которой он работает.
P.S. И еще, у массива должен быть такой же тип как и у переменной, с которой он работает.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
При отсутствии счета нули горят и запятые стоят в нужных местах. Но как только начинается счет - всякая шняга!
Кварц исправил на 8МГц, с типом данных в массиве разобрался. А вот с этим что делать:

не соображу. Как правильно раскинуть по разрядам?Разумеется, ерунду будет показывать. Ты как по разрядам-то раскидываешь? Если переменная F равна 1234, например?
Код:
I(7) = F / 10
Что он по указателю 123 считает?
Цапу крутить надо!!! Ку или не ку?
Ну тут целое поле для деятельности.
Рисуем на бумажке число 12345678 и думаем как нужное выдрать.
Мне вот такой вариант в голову пришел, например:
Можешь посмотреть в софтовых часах как разбивается, например. Стоит только помнить что подобный расчет занимает довольно много времени, и если он будет выполняться в прерывании то на это время индикация работать не будет.
Код: Выделить всё
For S = 8 To 2 Step -1 ' заполняем разряды, начиная с конца
I(s) = F Mod 10 ' выдергиваем последнюю цифру в массив
F = F / 10 ' далее, отсекаем ее
Next
I(1) = F ' а тут уже останется только один разряд
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Нет,.. так, видимо, не пойдет. При входной частоте 10кГц в первый момент (по первому прерыванию TIMER1) показывает 00.010.487. То есть, примерно правильно. А при последующих прерываниях TIMER1 показывает 00.001.967. Последняя цифра может меняться с 7 на 8 и обратно. И что интересно, показания напрямую зависят от предделителя TIMER1. Чем больше коэффициент предделителя, тем ближе к истине результат... 10487 получено при : Config Timer1 = Timer , Prescale = 1024. Кварц сменил на 16 МГц.
В архиве - скриншоты с протеуса.
В архиве - скриншоты с протеуса.
- Вложения
-
- screen.rar
- (52.05 КБ) 178 скачиваний
Цапу крутить надо!!! Ку или не ку?
Так я просто про разнос по разрядам говорил.
Индикатор показывает что в F находится, а вот что там и как считается - это уже я без понятия, тебе виднее.
Есть же подсчет импульсов на ноге, например, или тот же режим захвата... В каком диапазоне частот он должен работать-то хоть?
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Ну, хотябы мегагерц до 10...20 
Цапу крутить надо!!! Ку или не ку?
А то что он сначала одно показывает а потом другое - это вполне объяснимо. Сначала-то таймер считает от 0 до переполнения. И только в обработке начинает писать в счетный регистр:
Код: Выделить всё
Timer1 = &HCFFF
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Если в таймер загрузить значение &HFFFF, то индикатор показывает одно и то же число все время, но опять же неточно. Как его точно подсчитать то?
Цапу крутить надо!!! Ку или не ку?
Я о том что сначала он посчитает колличество импульсов от 0 до &HFFFF, и только потом будет считать от &HCFFF до &HFFFF. Так в коде. Ну ты же не с потолка взял Timer1 = &HCFFF ?
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
То есть, теоретически можно предположить, что если в TIMER1 записать 0 перед выходом из прерывания, то он опять будет считать от нуля до FFFF? На практике получается не совсем так. Досчитав до FFFF, счет какое то время продолжается, пока таймер не остановится (хотя это невозможно) ИЛИ надо считать не до FFFF, а до заранее загруженного точного значения. И еще одно, к сожалению в протеусе частота более 35кГц не правильно индицируется. Надо попробовать в железе. Вот такие рассуждения. Правильный ход мыслей или нет?
Цапу крутить надо!!! Ку или не ку?
Конечно проще настроить прерывание не по переполнению а по совпадению. Просто тут дело-то в другом, при высокой частоте он из внешнего прерывания вообще вылазить не будет...
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон


