Вот такие нюансы должны где-то в мануалах на Си описываться с особым акцентом. ))) Иначе можно много раз прочитать и не обратить внимание, что переменная не портится.
вообще говоря, это такие АЗЫ, что описывать их никакого смысла еще детальнее нет.
выражения - это основа основ!
вы же не считаете, что в математическом уравнении Y = X/2 + X портится значение Х? с чего вдруг в программном выражении оно попортится?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Ну как бы да, т.к. слева от присваивания стоит coefficient, то меняться будет только он. Также как и в математике.
Вообще всё это определено как lvalue и rvalue и про них пишут в стандартах и учебниках.... только там настолько много нюансов, что всё гораздо сложнее. Лучше в это пока не лезть )
Ну, вот как-то так получается, что уже не раз читаю про Си в разных источниках, начиная с нуля постоянно. Однако эта информация до меня так и не дошла. Либо я не так читаю, либо не так написано.
Как я всегда понимал, что переменную можно испортить везде. В том числе в цикле.
испортить её можно, это так. но умышленно.
например, оператор ++ или -- "портит" переменную, поэтому в одном выражении нельзя использовать переменную с этим оператором и без оного - компилятор не поймет, что делать первее.
еще портит переменную оператор =, но это и логично: присваивание значения по определению уничтожает предыдущее значение.
можно попортить переменную через указатель, но, опять-таки, в одном выражении использовать и испортить переменную будет непросто...
во всех прочих случаях содержимое переменной ИСПОЛЬЗУЕТСЯ, но НЕ МЕНЯЕТСЯ внутри одного и того же выражения.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
и опять же флот тут вообще не нужен, всё можно сделать в целых числах.
СКАЗОЧНИК, набираешь переключателями ЦЕЛОЕ число, равно количеству десятых.
если нужно делать умножение, то свое число умножаешь на число с порта, потом делишь на 10.
если нужно делать деление, то свое число сначала умножаешь на 10, потом делишь на число с порта.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Собрал все в железе. Работает. Даже вполне идеально. Но...
Есть пара нюансов. Первый, это воткнуть ВотчДог таймер, чтобы когда хватаешь плату руками и сбиваешь генерацию от кварца, не зависало все. А само перезагружалось и работало дальше.
Второй - это косяк в том, что таймер по захвату не самый лучший вариант. Т.к. он в отсутствии импульсов на входе тупо не может получить захват. И продолжает выдавать на выходе то, что было в переменных до этого. Как его скидывать не придумал еще.
З.Ы. Тойотовский тахометр кладет стрелку в 7000 оборотов при 700 Гц. )))) При 100 Гц показывает примерно 1000 оборотов. (значения приблизительные, т.к. точно не измерялись). Но умножает на 7 вполне четко.
СКАЗОЧНИК,
2ой нюанс решается по переполнению прерыванием. Сработало переполнение - значит нет на входе ничего (или слишком малая частота) - тогда останавливаем генерацию выхода.
Ну а первый просто надо настроить вотчдог на адекватный интервал и где-то в вашей выходной генерации сбрасывать.
Не. Умножает он на 7. На вход тахометра подавали 100 Гц. И тахометр показывал 1000 оборотов. Потом те же 100 Гц пропустил через свое устройство с умножением в 7 раз. На выходе получилось 700 Гц. А на тахометре стало 7000 оборотов.
Это в прерывании - у ПИКа один вектор прерывания, в нём флаги надо проверять, чтобы понять какое прерывание произошло. И вот PIR1bits.T1IF соб-но флаг переполнения таймера1, на котором захват. inval.word - это я сбрасываю соб-но захваченное значение до 0 (не обязательно) и потом поднимаю флаг t1ovf - что у меня было переполнение таймера. Его и проверяю дальше в основном цикле:
// Input overflow condition (too low freq or not changing)
if (flag.t1ovf) {
OUT = 0;
flag.inrun = false;
// Stop Timer0
T0IE = 0;
}
И соб-но останавливаю таймер0, который генерит выходной сигнал и выход перевожу в низкий уровень. Ну и снимаю бит флага flag.inrun, что у меня означает что на входе нет сигнала (и это в других местах кода позволяет пропускать некоторые вещи).
У меня основной цикл пустой вообще.. Думаю именно по Вашему предложению и сделать. Только по переполнению Т1 вызывать прерывание, в котором тупо обнулять обе переменные. И пусть делит ноль на коэффициент. Так можно? И выводит его дальше в порт. Просто получится ноль на выходе.
Т1 по переполнению настроить как самая медленная входная частота. И в прерывании по захвату обнулять счетчик таймера. (он и так обнуляется, когда записывает в переменные длину импульса и длину паузы), а если завис (не может поймать очередной фронт импульса, то счетчик переполнится и сработает прерывание по переполнению. Ну ли по сравнению с заданным значением. Без разницы.
Добавлено after 2 minutes 57 seconds:
А если точнее, то Т1 у меня свой счетчик никак не использует вообще. Значит буду его тупо сбрасывать, чтобы переполнение в штатной работе не происходило.
Добавлено after 7 minutes 9 seconds:
И даже не сбрасывать а обновлять такое значение, чтобы переполнение происходило с частотой в 1-2 Гц. Тогда нижняя частота будет ограничена этой частотой с которой он тупо на выходе будет выдавать ноль. И ронять стрелку тахометра.
Добавлено after 3 minutes 3 seconds:
Вотчдог настроить на 500 мс. И в выходном таймере Т0 все время его сбрасывать. если МК завис, то выхода не будет. Вотчдог переполнится и все перезагрузит.
СКАЗОЧНИК писал(а):А если точнее, то Т1 у меня свой счетчик никак не использует вообще
как же не используется? Т1 делает захват, и по его счетчику определяется период сигнала.
СКАЗОЧНИК писал(а):Значит буду его тупо сбрасывать, чтобы переполнение в штатной работе не происходило.
не нужен тебе ватчдог, пусть Т1 переполняется - прошел Т1 полный оборот, значит, не было захвата. и по прерыванию от переполнения Т1 отправляем ноль на выход.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
У меня изначально Т1 по захвату не использовал свои регистры.... Он тупо по захвату уходил в прерывание, где использовал Т0.... Не могу пока подробно объяснить. Я измеряю от фронта до фронта не самим захватом Т1, а количеством переполнений Т0.... А Т0 переполняется каждые 12 мкс. Т.е. он задает системные тики, от которых идет расчет и периода и вывода импульсов... Я выкладывал в начале ссылку на такую реализацию умножителя на Тини13.
ВотчДог мне нужен тупо для надежности от зависания МК. Если кто-нибудь при настройке возьмется руками за выводы кварца, чтобы он сам перезагрузился.
Переполнения Т1 каждые 500 мс у меня используются для отслеживания того, что входные импульсы пропали (т.е. машину заглушили) в нем он просто роняет стрелку тахометра в ноль.
Таймер1 вроде точно правильно настроил. В Протеусе работает. В железе буду проверять через пару часов. Вывел светодиод на одну ногу порта Д, чтобы отслеживать прерывания по переполнению Т1. Сбрасывается счетный регистр Т1 у меня в прерывании по захвату. ))) Когда есть входные импульсы, он все время выставляет новое значение 26473. Если входных нет, то он переполнится и сбросит выходные переменные в ноль. На выходе тоже будет ноль.
Остался вопрос во ВотчДогу. Правильно ли он настроен? ВотчДог сбрасывается в прерывании Т0 каждые 12 мкс. Если МК повис, то и Т0 не считает, а значит ВотчДог переполнится через секунду. И перезагрузит все.
Добавлено after 3 minutes 2 seconds:
Да! Огромное СПАСИБИЩЕ, что помогаете мне постигать азы программирования микроконтроллеров. ) Здоровья Вам всем и денег побольше!
СКАЗОЧНИК писал(а):Если у меня частота 20 МГц. Я настраиваю таймер1 по переполнению каждые 500 мс.
Выбираю делитель 256. В нормальном режиме он считает вверх, значит значение изначальное в счетный регистр закидываю 26473?
20 МГц - это период 0,05 мкс.
500 мс - это 500000 мкс.
делим 500000 / 0,05 = 10000000 (10 миллионов).
если выбрать предделитель 256, то число должно быть
10000000 / 256 = 39062,5.
округляем до 39063.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.