Обсуждаем контроллеры компании Atmel.
Пн ноя 20, 2017 19:32:58
так не проще?
if _day > 28 and _month = 2 then _day = 1
if _day > 30 then
if _month = 4 or _month = 6 or _month = 9 or _month = 11 then _day = 1
end if
if _day > 31 then _day = 1
Благодарствую! Влезло. 5401 байт. 6-разрядные часы-календарь на Ин-12.
Пн ноя 20, 2017 20:17:51
Добрый вечер! Такая проблема. Измеряю частоту. Необходимо измерять от 10 до 250гц чтобы точно было. Выставил таймер
Config Timer1 = Timer , Prescale = 64 , Capture Edge = Falling
частота 16мгц.
Таймер переполняется каждые 0,26с. Т.е. частоту до 4гц измеряет некорректно. Оно мне и не надо. Но если на входе частота находится ниже этих 4гц, то на выходе после пересчета выскакивают ненужные мне неправильные цифры. Понятно что из-за переполнения таймера. Только как сделать так чтобы если частота на входе ниже этих 4-5гц чтобы на выходе после пересчета был 0?
Пытался чтобы по переполнению таймера частота на выходе устанавливалась в ноль. Но между переполнениями из регистра захвата по прерыванию успевает записываться какое-либо число и частота прыгает от 0 до случайного значения.
Просто если реализовывать чтобы по переполнению таймера частота не считалась то ведь на один прогон программы таймер переполнится, а на следующий может не успеть и из регистра захвата будет прочитано число которое неверно отобразит частоту.
Помогите разобраться.
Вт ноя 21, 2017 04:01:27
при переполнении ставь блокирующий флаг.
потом, когда пришел импульс:
если флаг сброшен: обнуляем счетчик, считаем частоту
если флаг установлен: обнуляем счетчик, сбрасываем флаг.
Вт ноя 21, 2017 05:25:24
...Таймер переполняется каждые 0,26с. Т.е. частоту до 4гц измеряет некорректно...
Получается, что программа работает неправильно, т.к при частоте 4/сек (250'000 мкс) и дискрете таймера 4 мкс значение в оном не превысит 62'500.
Dnepr_1186 писал(а):...Оно мне и не надо...
Можно задействовать режим сравнения по одному из каналов A(B) и в регистр OCR1A(B) загрузить 100'000/4. Тогда все частоты меньше 10/сек игнорировать.
-----
По мне, толкаться в пределах разрядности таймера как-то не очень. Можно увеличить разрядность таймера добавлением всего 1 регистра куда складывать число переполнений и получить добротный НЧ частотомер. Для примера, программа измерения прямым счетом. Автор её использует переполнения. Думаю, легко адаптировать под метод обратного счета
Ср ноя 22, 2017 21:32:12
Уперся в DS1307. Расхотела генерить. Кварцы менял, не помогает. Есть подозрение, что тактовый генератор принудительно включился. Какв баскравре его включить?
Ср ноя 22, 2017 22:40:30
при переполнении ставь блокирующий флаг.
потом, когда пришел импульс:
если флаг сброшен: обнуляем счетчик, считаем частоту
если флаг установлен: обнуляем счетчик, сбрасываем флаг.
я был так близок к этому! Блокирующий флаг сделал, но ставил его не то место программы
Всем спасибо
Пт ноя 24, 2017 11:11:34
Уперся в DS1307.
Упрись в даташит.
Есть подозрение, что тактовый генератор принудительно включился.
Какв баскравре его включить?
Закусывать нада(с)
Из какой высказанной "золотым скифом" плесени пенициллин можно выжать?
Пт ноя 24, 2017 12:14:03
Грубиян.
Впрочем, и правда ничерта непонятно, что сие значит, и в чем вопрос. Я так подозреваю, что речь идет про 7- бит регистра секунд, и про то что генератор наоборот остановлен. Только в чем проблема так и не могу понять.
goldskif, будьте добры, код покажите, в котором проблема у Вас.
Пт ноя 24, 2017 13:58:08
При старте программы записать принудительно в регистр секунд ноль. Если все остальное нормально - часы пойдут. Можно посмотреть на 2 ноге генерацию кварца.
Пт ноя 24, 2017 14:33:55
Грубиян.
Впрочем, и правда ничерта непонятно, что сие значит, и в чем вопрос. Только в чем проблема так и не могу понять.
goldskif, будьте добры, код покажите, в котором проблема у Вас.
Не грубиян, а хам и циник.
Ежели я задам вопрос:
Мужики, телевизор у меня помрал, чё делать-то.
Какие ответы меня ожидают?
Нету тела, нету дела!
Пт ноя 24, 2017 15:25:23
Кварц может не генерить, при отсутствии батарейки (контакта или низкого напряжения), проблемы с кварцем(тоже не редкость), не правильной разводки (см. описание на микру).
Пт ноя 24, 2017 21:47:53
Всем спасибо. Проблема была в том ,что на 7 выводе DS1307 не было колебаний 1 Гц. Хотя в коде кусок есть
- Код:
I2cstart ' DS1307 - LED-1Hz моргалка секунд
I2cwbyte &HD0 ' посылаем команду записи
I2cwbyte &H07
I2cwbyte &B00010000
I2cstop
Причем часы так работали и моргали пару лет. Но как оказалось, обычно на схемах в протеусе светодиод от вывод 7 идет на минус (через резистор), и он вполне себе моргает. А вот в железе оказалось довольно глючно. Моргал, потом перестал и никакие попытки воткнуть другие кварцы и DS-ки результата не давали. Я уж думал, что DS-ка плохо запускалась или запрет где стоит.
А оказалось, что вывод 7 DS1307 это вывод с общим коллектором и правильно было цеплять светодиод или другую моргалку/нагрузку на плюс, а не на землю. Вот ведь блин..
А теперь другая проблема. Знаю, что общеизвестная. Паразитная засветка оптронов к газоразрядным индикаторам. Происходит от того, что анодный импульс после пропадания не сразу рассасывается в оптроне.
Вот думаю, как можно раздвинуть анодные импульсы, чтобы между ними зазор был для гашения, а не сразу друг за другом шли..
Кусок кода обычный
Спойлер
- Код:
' **********************[Основной цикл] **************************
Do ' основной цикл
Gosub Getdatetime ' считываем время и дату из DS1307
If _sec < 50 Then
Gosub Break_time ' показываем время
Else
Gosub Break_date ' показ даты последние 10 сек каждой минуты
End If
Debounce B_set , 0 , Setup_timedate , Sub ' обработка кнопки "SET"
Waitms 500
Loop
End
'***********************[Процедуры обработки подпрограмм и прерываний]*******************************
Refresh: ' прерывание таймера Т0 (индикация)
Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4 : Reset Dig5 : Reset Dig6 ' гасим индикатор
Incr Count : If Count > 6 Then Count = 1 ' выбираем какой разряд сейчас включать
Portd = Lookup(i(count) , Digits) ' закидываем в порт код цифры
Select Case Count ' включаем соответствующий разряд индикатора
Case 1 : Set Dig1
Case 2 : Set Dig2
Case 3 : Set Dig3
Case 4 : Set Dig4
Case 5 : Set Dig5
Case 6 : Set Dig6
End Select
Return
Последний раз редактировалось
goldskif Сб ноя 25, 2017 20:29:35, всего редактировалось 1 раз.
Сб ноя 25, 2017 20:10:36
goldskif писал(а):Вот думаю, как можно обрезать анодные импульсы по длительности?
В простом случае нужно использовать два прерывания - по переполнению и по совпадению. В прерывании по переполнению зажигается нужный разряд, а в прерывании по совпадению - гасятся все разряды. Тогда ширина анодного импульса будет пропорциональна числу в регистре сравнения.
Если же таймера с прерыванием по совпадению нет или он уже занят, можно сделать так:
Завести глобальную переменную-флаг, в которой будет храниться тип следующего прерывания. При входе в прерывание проверяем флаг. Если он равен 0, то зажигаем разряд и загружаем в счётный регистр таймера число, определяющее ширину импульса (время до переполнения таймера). Если же флаг равен 1, то гасим все разряды и загружаем в счётный регистр число, определяющее длительность паузы. В конце каждого прерывания инвертируем флаг (из 0 в 1 и наоборот).
Сб ноя 25, 2017 20:36:16
goldskif писал(а):Вот думаю, как можно обрезать анодные импульсы по длительности?
В простом случае нужно использовать два прерывания - по переполнению и по совпадению. В прерывании по переполнению зажигается нужный разряд, а в прерывании по совпадению - гасятся все разряды. Тогда ширина анодного импульса будет пропорциональна числу в регистре сравнения.
Если же таймера с прерыванием по совпадению нет или он уже занят, можно сделать так:
Завести глобальную переменную-флаг, в которой будет храниться тип следующего прерывания. При входе в прерывание проверяем флаг. Если он равен 0, то зажигаем разряд и загружаем в счётный регистр таймера число, определяющее ширину импульса (время до переполнения таймера). Если же флаг равен 1, то гасим все разряды и загружаем в счётный регистр число, определяющее длительность паузы. В конце каждого прерывания инвертируем флаг (из 0 в 1 и наоборот).
А просто впихнуть Waitms 5 где-нибудь между Set Dig* нельзя?
Сб ноя 25, 2017 21:20:08
после "Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4 : Reset Dig5 : Reset Dig6" вставить задежку ,только не 5 мсек а много меньше (подобрать экспериментально),например Waitus 10
Сб ноя 25, 2017 22:02:15
после "Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4 : Reset Dig5 : Reset Dig6" вставить задежку ,только не 5 мсек а много меньше (подобрать экспериментально),например Waitus 10
Отлично. Паразитка исчезла где-то при Waitus 400. Благодарствую!
--
Вообще это весьма ценная информация. Я когда планировал часы на ГРИ с оптронами, знал, проблема паразитной засветки вылезет.
И народ советует по незнанию всякую хрень, кто анодное напряжение крутит, кто предлагает бросить все и делать на транзисторных ключах.. Длительность послесвечения оптрона, вот и все..
Вс ноя 26, 2017 02:08:46
Задержки в прерываниях - дурной тон. Прерывание должно выполняться за максимально короткое время.
Конкретно в этом случае лишние 80 тактов (10 мкс при 8 мГц) ничего плохого не сделают, но лучше сразу привыкать делать правильно.
Вс ноя 26, 2017 07:53:40
Полностью согласен, задержек в прерывании быть не должно. Вариант с прерыванием по совпадению очень прост, и позволяет лишь средствами таймера регулировать длительность включенного состояния при неизменной частоте. Например, так легко регулируется яркость семисегментного индикатора, одним только изменением содержимого регистра сравнения.
- Код:
Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0 ' конфигурируем таймер индикации (~500 Гц)
On Ovf0 Refresh ' вектор прерывания по переполнению
On Oc0a Dimmer ' вектор прерывания по совпадению (длительность импульса)
Ocr0a = 127 ' загрузка значения в регистр сравнения
'***********************************[Процедуры обработки подпрограмм и прерываний]*******************************
Refresh: ' прерывание таймера Т0 (индикация)
Set Dig1 : Set Dig2 : Set Dig3 : Set Dig4 : Set Dig5 : Set Dig6 ' гасим индикатор
Incr Count : If Count > 6 Then Count = 1 ' выбираем какой разряд сейчас включать
Portd = Lookup(i(count) , Digits) ' закидываем в порт код цифры
Select Case Count ' и включаем соответствующий разряд индикатора
Case 1 : Reset Dig1
Case 2 : Reset Dig2
Case 3 : Reset Dig3
Case 4 : Reset Dig4
Case 5 : Reset Dig5
Case 6 : Reset Dig6
End Select
Return ' выход из обработчика прерывания
'----------
Dimmer: ' прерывание таймера Т0 (регулировка яркости)
Set Dig1 : Set Dig2 : Set Dig3 : Set Dig4 : Set Dig5 : Set Dig6 ' гасим индикатор
Return ' выход из обработчика прерывания
Вс ноя 26, 2017 09:20:38
А длительность равную Waitus 400 как поставить? Пока засветка есть
Последний раз редактировалось
goldskif Вс ноя 26, 2017 09:35:53, всего редактировалось 1 раз.
Вс ноя 26, 2017 09:40:53
Та всё нормально. Соль тоже нельзя жрать. Но если знаешь сколько, то можно.
На счёт таймера, то не нужен доп. Там один и тот же таймер может вызывать прерывание и по совпадению и прерыванию. Код не сильно увеличиться. Внимательно смотрите пример.
Добавлено after 7 minutes 26 seconds:
Кроме того, код можно существенно сократить, если в прерывании не сохранять все регистры, а только нужные. Сделать это очень просто. Открывайте проект в протеусе, запуск\пауза, находите кусок кода с прерыванием. включаем Дизасемблер. Увидите в начале прерывание сохранение всех регистров, в конце восстановление. В теле прерывания смотрите какие регистры используются,записываете. Остальные все удаляете из \сохранения и востановления\. Для 2313 сокращение будет существенно. Не забудьте в конфигурацию таймера добавить "nosave"
з.ы.
зачем сообщение удалили про доп таймер. Мне тоже ответ удалять?
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.