|  |  |  | 
|  | Zandy: Не понял вопроса. Как вычислить нужную константу для получения требуемой задержки - до прерывания по таймеру и длительность паузы между переключением светодиодов в другое состояние?У Вас стоят коэффициенты (.50 и .200) но Вы же их не с потолка взяли?..
  Zandy: Вы забыли про сам таймер и его установку в нужное число в каждом прерывании (KTMR0 equ .50) Не забыл, а не знал...  И как определить время, через которое сработает таймер? с такими установками, как Вы указали в проге?
 Zandy: Это просто, только надо ли? Если вариантов - штук 5, то, наверно, не нужна эта кнопка. А если менять частоту с более мелким шагом, когда количество комбинаций будет... например, 20, когда частота переключения может меняться с шагом в 1 Гц, то листать варианты только в одну сторону будет не удобно... Zandy: ...переводить МК в слип, погасив светодиоды? Это сложнее. Проще поставить обычный выключатель. Понятно, что рубильник поставить - значительно проще, но реализовать функцию "рубильника" в самом МК, думаю, интереснее...  Хотя, только что пришла идея.Заказчик говорит, что два эффекта должны быть в любом случае - "Горят все светодиоды" и "Не горит ни один".
 Добавляем в список эффектов эти два варианта и всё...
  При этом сразу возникают два вопроса: 1) А что, если эффект "Горят все светодиоды" реализовать, как обычный, когда все светодиоды переключаются по очереди, но только с большой частотой, не заметной глазу?Это позволит уменьшить потребляемый ток. Хоть немного...
  2) Эффект "Не горит ни один" - то же эффект, только в порты записать постоянно состояние, когда все светодиоды погашены.В этом случае потребление будет только по цепи МК, а так как оно небольшое, то можно считать, что устройство находится в состоянии "Выключено".
 Zandy: Что за файл? Наверное биты конфигурации. Да, биты конфигурации.Просто, у Вас указано значение:
 __CONFIG    3F70h             ;биты конфигурации
 А что при этом включено, а что выключено - не понятно. Приходится вычислять самому...
 | 
 | 
|  | DWD:Получается коэффициент "110". Это сколько?
 Невнимательно даташит читаете.
  Это 1:128. KTMR0 equ .50 ; Установка таймера TMR0Koption 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 | 
 | 
|  |  |  |