Свежие обсуждения
Электроника в автомобиле

Подсветка днища автомобиля ночью.

1 8 14

Zandy: Не понял вопроса.

Как вычислить нужную константу для получения требуемой задержки - до прерывания по таймеру и длительность паузы между переключением светодиодов в другое состояние?
У Вас стоят коэффициенты (.50 и .200) но Вы же их не с потолка взяли?..

Zandy: Вы забыли про сам таймер и его установку в нужное число в каждом прерывании (KTMR0 equ .50)

Не забыл, а не знал...
И как определить время, через которое сработает таймер? с такими установками, как Вы указали в проге?

Zandy: Это просто, только надо ли?

Если вариантов - штук 5, то, наверно, не нужна эта кнопка. А если менять частоту с более мелким шагом, когда количество комбинаций будет... например, 20, когда частота переключения может меняться с шагом в 1 Гц, то листать варианты только в одну сторону будет не удобно...

Zandy: ...переводить МК в слип, погасив светодиоды? Это сложнее. Проще поставить обычный выключатель.

Понятно, что рубильник поставить - значительно проще, но реализовать функцию "рубильника" в самом МК, думаю, интереснее...

Хотя, только что пришла идея.
Заказчик говорит, что два эффекта должны быть в любом случае - "Горят все светодиоды" и "Не горит ни один".
Добавляем в список эффектов эти два варианта и всё...

При этом сразу возникают два вопроса:

1) А что, если эффект "Горят все светодиоды" реализовать, как обычный, когда все светодиоды переключаются по очереди, но только с большой частотой, не заметной глазу?
Это позволит уменьшить потребляемый ток. Хоть немного...

2) Эффект "Не горит ни один" - то же эффект, только в порты записать постоянно состояние, когда все светодиоды погашены.
В этом случае потребление будет только по цепи МК, а так как оно небольшое, то можно считать, что устройство находится в состоянии "Выключено".

Zandy: Что за файл? Наверное биты конфигурации.

Да, биты конфигурации.
Просто, у Вас указано значение:
__CONFIG 3F70h ;биты конфигурации
А что при этом включено, а что выключено - не понятно. Приходится вычислять самому...

 

DWD:
Получается коэффициент "110". Это сколько?
Невнимательно даташит читаете. Это 1:128.

KTMR0 equ .50 ; Установка таймера TMR0
Koption equ B'00000110' ; Установка OPTION_REG

Директива equ используется для присвоения какому-то буквенному набору цифрового значения. Для в/у примера, теперь, при подстановке KTMR0 Ассемблер воспримет его как число 50. Если потом необходимо скорректировать это значение, достаточно будет изменить его только в одной строке (с директивой). Во всех остальных (где использовано KTMR0) оно поменяется автоматически. Чтобы TMR0 отсчитывал нужное значение, необходимо, после каждого переполнения (и выполнения прерывания) записывать в его регистр некоторое начальное число, что видимо, и сделано в программе. По этой причине, кстати, я предпочитаю использовать TMR2, так как в него достаточно записать значение один раз.

А как же тогда просчитать время паузы, например?
Или через какое время сработает прерывание по таймеру?

Это не имеет никакого отношения к байту конфигурации. Я это имел ввиду. Я просто пишу строчку вида: _CONFIG _CP_ON & _DATA_CP_ON & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC , а Ассемблер сам всё считает. Время паузы считаю по количеству комманд, а таймера - по количеству тактов. Естественно потом всё окончательно проверяю в МПлабе по StopWatch, выставив контрольные точки.

 

Обьясняю "на пальцах".
Koption equ B'00000110'
...........................................
ld OPTION_REG,Koption
Эти строки означают, что в регистр OPTION_REG мы записываем число B'110'. При этом предделитель будет иметь Кдел. = 1:128.
Рабочая частота равна 1 МГц, т. к. она в 4 раза меньше тактовой. Следовательно, период частоты предделителя будет равен 128 мксек.
Строки
KTMR0 equ .50
..............................
ld TMR0,KTMR0
означают, что в таймер мы записываем число .50. Причем делается это в начале обработки прерывания, т. е., когда прерывание произошло. А происходит оно по переполнению таймера TMR0, т. е., когда он досчитал до 255. Таким образом мы заставляем таймер считать не с 0, а с числа .50. В результате цикл счета таймера будет 255 - 50 = 205 импульсов.
Остается перемножить длительность импульса на их количество 128мкс х 205 = 26, 2 мсек Это и есть период наших прерываний. Строгости ради, чтобы точно получить 20 мсек, нам надо в таймер записывать не .50, а .99. Тогда 128 х (255 - 99) = 20 мсек
Дело в том, что период прерываний в данной программе влияет только на антидребезговую обработку кнопок и при том алгоритме, который здесь реализован, вы можете безболезненно уменьшить это время до 10 мсек или еще меньше. Я же говорил, что это дело вкуса. На частоту мигалок, естественно, это никакого влияния не оказывает.
Если вам "в лом" делать такие "сложные" расчеты, в процессе симуляции поставьте точку останова на первую команду прерывания. Выводите окошко "Stopwatch". Меряете период прерывания, не забывая нажимать кнопочку "Zero" и пропустив первую остановку, так как в это время входит еще время на выполнение команд инициализации и других, до команды разрешения прерываний (хотя оно крайне мало по сравнением с периодом прерывания). По результатам измерения корректируете цифири и опять меряете. Метод т. н. "научного тыка".
Остальные вопросы вроде чисто риторические? Или нет?

 

Zandy:
Koption equ B'00000110'
...........................................
ld OPTION_REG,Koption

Если не ошибаюсь, Id где-то сперва "создаётся". Т.е. какой-то последовательности команд (в нашем случае movlw и movwf) присваивается имя. Где-то я такое читал, но никогда не пользовал, по причине, что искажается подлинная картина количества выполняемых операций.

 

Gregory: Если не ошибаюсь, Id где-то сперва "создаётся".
Ну да, это макрос. Используется исключительно для простоты и сокращения записи. Выполняется за время, равное времени выполнения входящих в него команд. Все используемые макросы смотрите в начале текста программы. В данном случае, это:
ld MACRO DEST2,CONST2 ; пересылка константы в регистр
movlw CONST2
movwf DEST2
endm

 

Gregory и Zandy - спасибо за объяснения.

Zandy: Если вам "в лом" делать такие "сложные" расчеты...

Как раз наоборот - я ХОЧУ делать эти сложные расчёты, по этому меня интересует каждая мелочь...
В доке на 628-й МК получение этих расчётов для TMR0, оказалось, явно не прозрачным... Видимо, одной доки на МК мало.

Коэффициент предделителя 1:128 я понял сам, но как его дальше сопоставить со значением 50 - это было проблемой.
Спасибо, теперь понятно.
Не совсем ясен, правда, смысл всех этих подстановок, но это, видимо, из-за слабого понимания структуры МК. Буду копать дальше...

На текущий момент осталось два вопроса - расшифровка бита конфигурации по значению (__CONFIG 3F70h) и расчёт длительности паузы по записиываемым коэффициентам (например, ,200 и .169).
Это нужно хотя бы потому, что я собираюсь, всё таки, ставить ещё одну кнопку для изменения частоты не только в "+", но и в "-".

Zandy, всю Вашу прогу до конца ещё не понял, но набрался наглости кое-что изменить...

Первым и вторым по счёту эффектами стали "Всё включено" и Всё выключено" соответсвенно.
Те два эффекта, которые были у Вас первыми двумя, стали последними. Итого - 10 эффектов. А так как циклический счётчик эффектов у Вас ограничен числом 8, то пришлось подправить и его...
Получилось...
Правда, опасение вызывает факт, что получилось со второго раза...
По принципу - если прога заработала сразу, значит она написана неправильно...
Тем не менее, прогон в Протеусе показывает, что работает - нажатие на кнопку переключения эффектов переключает их по очереди и зациклено числом 10.
Так как я "додумался" сразу создать переменную, определяющую это значение, то дальнейший рост числа эффектов проблемы, надеюсь, не создаст...

Кстати, Zandy, получилось со "второй" попытки потому, что первой была - описать переменную в "cblock", а потом присваивать ей значение, используя готовый макрос, но до конца я это не проверил, так как способ мне не понравился...
Сначала описываешь переменную, потом присваиваешь ей значение. Потом проверяешь текущее состояние счётчика эффектов, используя операции пересылки в аккумулятор и сравнение с помощью команды "XORWF f,d"...
Но есть, ведь, команда "XORLW k" - работа с константой.
По этому, я создал не переменную, а константу, описав в одной строке сразу саму переменную и её значение.
Потом, просто сравнивал состояние счётчика с константой.

В связи с этим вопрос - почему Вы не использовали это? Или я не прав в принципе, и этот вариант, скажем, случайно подошёл только в данном случае, а не вообще?

Может, это не существенно, но мне показалось, что таким способом можно было бы избавиться от "двойной" операции - создание переменной и присвоение ей значения. А у Вас в проге много таких переменных, которые "тянут" на константы.

 

DWD: На текущий момент осталось два вопроса - расшифровка бита конфигурации по значению (__CONFIG 3F70h)
Выбираете в меню Configure, в нем подменю - Configuration Bits. Щелкаете по нему. Откроется картиночка. В ней увидите и число 3F70h, и все установки конфигурационных битов наглядно. Щелкая мышкой по значениям, можете установить все то, что вам нужно. При этом изменится и число 3F70h. Просто берете и измененное число переписываете в программе вместо того, которое было.
Если не нравится так, делайте так, как вам подсказал Gregory
Gregory: Я просто пишу строчку вида: _CONFIG _CP_ON & _DATA_CP_ON & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC , а Ассемблер сам всё считает.
Синтаксис написания берете из файла P16F628.INC
Ну или третий путь. Читаете документацию, раздел 14.1 Там прописаны все эти биты и их значения при разных вариантах конфигурации.

DWD: расчёт длительности паузы по записиываемым коэффициентам (например, ,200 и .169).
Паузой управляют строки с 423 по 430. Там организован двухбайтовый счетчик паузы. Имеется два цикла: малый (декрементируется с проверкой на 0 счетчик PauseL) и большой (декрементируется с проверкой на 0 счетчик PauseH), когда PauseL обнуляется. Время исполнения цикла равно времени исполнения команд в цикле, умноженное на количество малых циклов и умноженное на количество больших циклов. Не забывайте, что время исполнения некоторых команд (например goto) составляет 2 такта. Конкретный подсчет я делаю так. Сперва грубо прикидываю значения начальных установок счетчика паузы (просчитать с точностью до 1 такта - довольно муторное занятие), а затем в процессе симуляции с помощью стоп - меток и "Stopwatch" уточняю значения. Точный расчет в каждой программе будет разный, т. к. количество команд, входящих в цикл тоже разное. Здесь нет универсальной формулы, а общий подход к расчету я вам уже описал. Гляньте еще вот это http://ikarab.narod.ru/pause.htm Я сам не пользовался, не знаю, но может вам понравится. И вообще, почитайте http://ikarab.narod.ru/Kea_20.html . Там настолько все "разжевано", что дальше некуда. Правда некоторые вещи не используются, например .inc файл. Все регистры спец. назначения прописываются в шапке и т. д.

DWD: Сначала описываешь переменную, потом присваиваешь ей значение. Потом проверяешь текущее состояние счётчика эффектов, используя операции пересылки в аккумулятор и сравнение с помощью команды "XORWF f,d"...
Но есть, ведь, команда "XORLW k" - работа с константой.
По этому, я создал не переменную, а константу, описав в одной строке сразу саму переменную и её значение.
Потом, просто сравнивал состояние счётчика с константой.

Все правильно. Если в процессе исполнения программы какое-то число не изменяется, то это константа и нет смысла отводить под нее регистр, а затем прописывать туда число.

DWD: Может, это не существенно, но мне показалось, что таким способом можно было бы избавиться от "двойной" операции - создание переменной и присвоение ей значения. А у Вас в проге много таких переменных, которые "тянут" на константы.
Да нет, у меня таких переменных нету. Смотрите внимательнее. Если я при инициализации (начальная установка) или в процессе выполнения программы, записываю в регистр (переменную) какое-то число, то это не значит, что это число будет там храниться вечно.

DWD: Итого - 10 эффектов. А так как циклический счётчик эффектов у Вас ограничен числом 8, то пришлось подправить и его...
Получилось...
Правда, опасение вызывает факт, что получилось со второго раза...

Ну здесь заочно сложно что-либо сказать. Выложите ваш кусок программы - посмотрим, проверим, обсудим.

 

Zandy:
Сперва грубо прикидываю значения начальных установок счетчика паузы
Аналогично.

 

Понял, спасибо.
Прога у меня дома, завтра принесу и с утра выложу.

 

Zandy: Выбираете в меню Configure, в нем подменю - Configuration Bits. Щелкаете по нему. Откроется картиночка. В ней увидите и число 3F70h, и все установки конфигурационных битов наглядно.

В 5-й версии такого нет. Видимо, у Вас 6-я? Там такое есть.

Ещё вопрос по биту конфигурации.
Почему в Протеусе установлено значение 3F30h, а в листинге проги - 3F70h?

Zandy: Выложите ваш кусок программы - посмотрим, проверим, обсудим.

Выкладываю (аттач).
Изменения:

1) KNOP7 equ .10 ; Количество эффектов.

2) "Перебор вариантов при нажатии на A7". Две Ваши команды "заремлены", и дописаны 4 новых:
; movlw b'00001111' ; затираем лишние биты
; andwf COUNT_KNOP7,F ; кроме трех младших
movf COUNT_KNOP7,w ;
XORlW KNOP7 ; Если счётчик числа эффектов достиг
jnz PER2 ; максимального значения,
clrf COUNT_KNOP7 ; то обнуляем его.

3) Перебор вариантов эффектов. Добавлено две строки:
goto LIGHT9
goto LIGHT10

Следом подряд идут 2 эффекта - "Всё включено" и "Всё выключено".
Получены переделкой Ваших двух эффектов.
Те 2 эффекта, которые у Вас были первыми двумя, перенесены на последние - 9-й и 10-й.

4) Гудок. Изменена одна команда:
H2 bcf GPORTA,4 ;Было bsf. На выходе не импульсы, а постоянный уровень 0.

В результате, на выводе мк RA4 не импульсы, а постоянный уровень нуля. Просто, я расчитываю использовать зуммер от китайского будильника со встроенным генератором, для которого достаточно подать постоянное напряжение, что бы он "запищал".
Включу его между выводом питания и портом RA4. О согласовании уровней думаю, так как для зуммера нужно 1,5В...
Возможно, хватит включения последовательно с самим зумером стабилитрона на 2,7-3,3В.

Пока всё.
Дальше хочу думать о пристройке дополнительной кнопки на порт RA5 и изменении программы для получения возможности менять с каким-то шагом частоту эффектов как в сторону увеличения, так и уменьшения.
Частота менее 1Гц, вряд ли, понадобится. Не нужна частота и выше 20Гц, так как будет казаться, что светодиоды не мигают, а горят постоянно. По этому, пределы изменения частоты 1-20Гц. При таком малом числе, думаю, можно сделать изменение частоты с шагом в 1 Гц. Как думаете?

67298.zip