Страница 1 из 5
Поверка секундомеров
Добавлено: Пн мар 16, 2009 22:38:01
Юрий Климчук
Я начинающий, нашел на уроках на одном сайте прогу на СИ, так мне проще. Кое что переделал, вроде работает ( в протеусе), но что то не то. Во первых в протеусе работает только один раз, сброс не действует, но если остановить симуляцию и снова начать все ОК.
Ну немного коряво для первого раза, если есть энтузиасты, помогите.
Если, не понятно для чего эта прога, спрашивайте объясню.
В принципе должно быть понятно в проге, там много комментариев и в протеусе есть.
Спасибо отзывчивым!!!
Добавлено: Вт мар 17, 2009 07:33:27
asteroid7
Правильней делать так:
TCCR1B = 0; //стоп таймер 1
TCCR1B = 0b00000101; //старт таймер 1
и строчки с "//защита переполнения переменной..." можно убрать. Это лишнее. Правда, я не знаю как протеус симулирует

, но в железе unsignet байт - байтом и останется.
Добавлено: Вт мар 17, 2009 21:51:37
Юрий Климчук
Все пошло как по маслу, останавливается и сбрасывается в "0", и больше не считает плюс еще один, главное, что повторно пуск работает.
Теперь хочу попробывать изменять время импульса подачи напряжения на светодиод (соленоид в дальнейшем) ну кнопками, а как подступиться к этому вопросу, не знаю с чего начать и как реализовать.
И как в конце счета при сбросе в "0" написать на ЖКИ например STOP.
И еще влияет ли на точность delay_ms(150) в начале и в конце счета.
Добавлено: Чт мар 19, 2009 22:16:23
Юрий Климчук
Новая версия моей программы, минимальный вариант но треба совершенства. Кто поможет, как устанавливать время срабатывания и обойтись без delay_ms(250) т. е. выставлять время срабатывания соленойда для надежного срабатывания секундомера.
Наверное можно использовать другой таймер, этот же занят?
Я прав или?
Добавлено: Пт мар 20, 2009 20:21:14
Digital
А вот с этим куском из первой версии программы разобрались почему так?
Код: Выделить всё
TCCR1B&=0b11111000; // останавливаем таймер
//TCCR1B|=0b11111000; // останавливаем таймер (НЕ РАБОТАЕТ) в чем отличие ????
Добавлено: Пт мар 20, 2009 21:27:40
Юрий Климчук
Наполовину, & -это И, а |-это исключающее ИЛИ, где то читал но не записал, вспоминаю вроде так. А вот как они работают в данном коде не понял.
Добавлено: Пт мар 20, 2009 22:00:27
Digital
Юрий Климчук писал(а):Наполовину, & -это И, а |-это исключающее ИЛИ, где то читал но не записал, вспоминаю вроде так. А вот как они работают в данном коде не понял.
Сотрите из своей памяти эти сведения.
В общем обязательно надо понять, "ху ис ху", прежде чем дальше продолжать изучать программирование МК. Попробую помочь. Минутку-с...
Добавлено: Пт мар 20, 2009 22:53:13
Digital
Ну, во первых, мы говорим о правилах записи на языке Си.
Есть в нём такие операции – поразрядные называются.
& - поразрядное логическое И
| - поразрядное логическое ИЛИ
Кстати поразрядное логическое исключающее ИЛИ имеет вот такое обозначение: ^
Берём код:
Код: Выделить всё
TCCR1B&=0b11111000; // останавливаем таймер
//TCCR1B|=0b11111000; // останавливаем таймер (НЕ РАБОТАЕТ) в чем отличие ????
Напишем строки для ясности так:
TCCR1B&=0b11111
000;
TCCR1B|=0b11111
000;
Вот те три, выделенные жирным, разряда регистра TCCR1B (который управляет тактовой частотой и режимами работы таймера 1) – отвечают за установку тактовой частоты таймера. Смотрите таблицу 40 на стр.98 ДШ (даташита) на ATMega8. Т.е., когда эти разряды в нулях, то таймер
остановлен.
Вот вам посоветовали запуск таймера сделать так:
Да, так таймер 1 начнёт работать, согласно ДШ, на частоте в 1024 раза ниже тактовой частоты самого МК (микроконтроллера). Но… «ещё более правильней» сделать вот так:
Теперь «сама соль». Вот так: TCCR1B|=0b11111000; - не остановить таймер, потому что, если в тех трёх разрядах было что-то, отличное от нулей, то, выполняя
поразрядное логическое ИЛИ ничего и не изменится! Надо применять логическое умножение (& - поразрядное логическое И).
Почему именно
поразрядное, да? Ну совсем не обязательно конечно. И так как вам советовали:
будет работать. Кстати можно было и так записать «TCCR1B = 0b00000000;».
Разница прямой записи с поразрядными операциями лишь в том, что меняться будут
лишь те разряды (биты), которые по логике операции должны меняться на противоположные!
Т.е.:
Вариант 1)
Было TCCR1B=0b11111 101;
Поступила команда TCCR1B=0; => в TCCR1B записалось 0b
00000 000.
Вариант 2)
Было TCCR1B=0b11111 101;
Поступила команда TCCR1B&=0b11111 000; => в TCCR1B стало 0b
11111 000. Т.е. остальные разряды
остались не тронутыми.
Видите разницу? Так, кстати, с помощью поразрядных (битовых ещё называют) операций можно и
по-отдельности выводами портов рулить.
Добавлено: Пт мар 20, 2009 22:56:09
Digital
Вариант с исключающим поразрядным ИЛИ:
Если TCCR1B = 0b00000 101; //старт таймер 1
TCCR1B^=0b00000 101; // останавливаем таймер 1
Но это так, для примера. Таймер в этом случае будет каждый раз старт/стоп выполнять по той команде.
Добавлено: Сб мар 21, 2009 08:33:40
asteroid7
Немного добавлю.
& - лог. "И" - во многих других языках или ассемблере встречается как
AND, или ещё называют маской (наложить маску, маскировать и т.д.), используется для сброса нужных бит в "0" не трогая другие биты.
| - лог. "ИЛИ" - -//-
OR, используется как установка нужных бит в "1" не трогая другие биты.
Немного поправлю.
Digital писал(а):...
Но… «ещё более правильней» сделать вот так:
...
Не корректно это. Таймер, желательно, запускать и останавливать из одного места программы. Это не порты, которые могут настраиваться и управляться из разных мест. Для портов логические операции необходимы.
В данном случае, откуда известно что регистр таймера TCCR1B в нуле?
По рекомендации атмела, перед любым изменением настроек таймера его желательно останавливать кодом 0x00. Потом, конечно, можно лог. "ИЛИ" запустит. А смысл? Лишняя ассемблерная команда.
Таймерами лучше управлять прямой записью.
Добавлено: Сб мар 21, 2009 09:41:41
Digital
asteroid7 писал(а):В данном случае, откуда известно что регистр таймера TCCR1B в нуле?
Это было допущение. Спасибо за уточнение. Ну хоть надеюсь смысл битовых операций человеку раскрыл подробно, будет с чего начать осмысленное применение команд!?
Давайте ещё уточним, что и
& и
| - могут использоваться для маскИрования!?
Добавлено: Сб мар 21, 2009 09:44:36
Digital
asteroid7 писал(а):Немного добавлю.
& - лог. "И"
| - лог. "ИЛИ"
У меня в памяти

, применительно к языку С, вот что записано (в асме также или нет - не знаю, пока не интересовался):
&& - логическое И;
|| - логическое ИЛИ.
Т.е.
&, |, ^ - это поразрядные операции.
&&, || - логические операции.
Добавлено: Вс мар 22, 2009 00:25:35
IfoR
Ну да.
&& и || Это логические операции. Они применяются для всего числа в целом, при этом если оно равно 0, то это лог. 0, а если больше 0, то это лог. 1
Пример:
0b11111101 && 0b11111000 = 1
0b11111101 && 0b00000000 = 0
0b00000000 && 0b00000000 = 0
0b11111101 || 0b11111000 = 1
0b11111101 || 0b00000000 = 1
0b00000000 || 0b00000000 = 0
&, |, ^ - это побитывые операции. Они применяются для каждого бита в числе.
Пример:
0b11111101 & 0b11111010 = 0b11111000
0b11111101 | 0b11111000 = 0b11111101
0b11111100 ^ 0b11111010 = 0b00000010
Применение:
Оператор & можно использовать для установки лог. 0 на определённых битах, при этом в тех местах где надо установить лог. 0 надо установить лог. 0, а во всех других лог. 1.
Принцип: Когда применяется операция И к исходному биту и 0, то какой бы бит небыл бы в исх. состоянии 0 или 1 он всегда меняется на 0:
1 И 0 = 0
0 И 0 = 0
А если к исх. биту применяется 1 то какой бы небыл исх. бит он остаётся в прежнем состоянии:
1 И 1 = 1
0 И 1 = 0
Пример:
Переменная X=0b00110100
Нужно устоновит 1,3,6 биты в лог. 0. Ставим:
X&=0b11011010;
Теперь X=0b00010000
Оператор | можно использовать для установки лог. 1 на определённых битах, при этом в тех местах где надо установить лог. 1 надо установить лог. 1, а во всех других лог. 0.
Принцип: Когда применяется операция ИЛИ к исходному биту и 0, то какой бы бит небыл бы в исх. состоянии 0 или 1 он остаётся в прежнем состоянии:
1 ИЛИ 0 = 1
0 ИЛИ 0 = 0
А если к исх. биту применяется 1 то какой бы небыл исх. бит он всегда меняется на лог. 1:
1 ИЛИ 1 = 1
0 ИЛИ 1 = 1
Пример:
Переменная X=0b00110100
Нужно устоновит 1,3,6 биты в лог. 1. Ставим:
X&=0b00100101;
Теперь X=0b00110101
Ну а оператор ^ можно использовать для сравнения, например, а можно ещё инвертировать значения в определённых битах
при этом в тех местах где надо инвертировать бит надо установить лог. 1, а во всех других лог. 0.
Принцип: Когда применяется операция Иск. ИЛИ к исходному биту и 0, то какой бы бит небыл бы в исх. состоянии 0 или 1 он остаётся в прежнем состоянии:
1 Иск. ИЛИ 0 = 1
0 Иск. ИЛИ 0 = 0
А если к исх. биту применяется 1 то он инвертируется:
1 Иск. ИЛИ 1 = 0
0 Иск. ИЛИ 1 = 1
Пример:
Переменная X=0b00110100
Нужно инвертировать 1,3,6 биты. Ставим:
X&=0b00100101;
Теперь X=0b00010001
Вот.

Добавлено: Вс мар 22, 2009 13:05:27
Digital
IfoR писал(а):Переменная X=0b00110100
Нужно инвертировать 1,3,6 биты. Ставим:
X&=0b00100101;
Теперь X=0b00010001
Последний пример. Может быть так вы имели ввиду: X
^=0b00100101; ?
А для первого примера:
IfoR писал(а):Пример:
Переменная X=0b00110100
Нужно устоновит 1,3,6 биты в лог. 1. Ставим:
X&=0b00100101;
Теперь X=0b00110101
вот так?
X
|=0b00100101;
Добавлено: Вс мар 22, 2009 21:15:41
Юрий Климчук
Я очень извиняюсь, что создал такой переполох (спор) своими вопросами, но как говорится в споре рождается истина, я очень рад, что столько информации вылилось для изучения, большое ВСЕМ спасибо и скорей всего от других тоже. Я немного отойду от темы, что бы осмыслить всю информацию которую мне дали, очень надеюсь, что тема закроется не скоро. Я как раз тот, который вопросы задаёт, которые другие стесняются задать. По профессии я военный метролог и проектов с микроконтроллерами у меня будет много, уж больно дорого то, что предлагает промышленность, буду бороться с ней своими разработками, если конечно я освою все это.
Немного предыстории. Как то раз, я зашел в наш местный ГОСТАНДАРТ, и увидел у них установку для поверки секундомеров «УПМС-1», цена её тогда было 350 тыс. в моей лаборатории её нет, и врят ли будет в скором времени. Сфоткал все режимы которые мне продемонстрировали хвастаясь, но я затаил свою мысль, что мы создадим не хуже и своими силами и теперь мне не даёт это покоя, вот так я попал на этот форум со своей темой.
Ну все пока.
Измеряй все доступное измерению и делай доступным все недоступное ему.
Г.Галилей
Добавлено: Вс мар 22, 2009 21:20:24
Digital
Юрий Климчук писал(а):я очень рад, что столько информации вылилось для изучения
Разбирайтесь, для того этот ресурс и существует.
Добавлено: Пн мар 23, 2009 09:20:21
asteroid7
Digital писал(а):asteroid7 писал(а):Немного добавлю.
& - лог. "И"
| - лог. "ИЛИ"
У меня в памяти

, применительно к языку С, вот что записано (в асме также или нет - не знаю, пока не интересовался):
&& - логическое И;
|| - логическое ИЛИ.
Т.е.
&, |, ^ - это поразрядные операции.
&&, || - логические операции.
Да. Вы правы. В Си именно так и называются. Я старался к нему не привязываться.
Самое интересное, то что в Си называется логическими операциями во многих других языках программирования называют булевыми (Boolean). А поразрядное в Си - логическими (Logical) операциями, ещё приписывая в скобочках слово поразрядное (Bitwise).
Добавлено: Пн мар 23, 2009 09:24:45
asteroid7
Digital писал(а):...
Давайте ещё уточним, что и & и | - могут использоваться для маскИрования!?
Только &.
Добавлено: Пн мар 23, 2009 19:01:42
Digital
Digital писал(а):Давайте ещё уточним, что и & и | - могут использоваться для маскИрования!?
asteroid7 писал(а):Только &.
Ну не знаю

.
Что такое маскИрование? Это ведь, другими словами,
изменение, а не только обнуление отдельных битов в байте, без изменения других, по маске. А какой операцией мы добьёмся успеха, по & или | не всё равно? Откуда такое ограничение?
Т.е., к примеру:
Было:
0b0000 1000 // Если PORTn=0x08;
Надо установить биты 0 и 1 в лог. "1" (бит 3, допустим, трогать не надо):
0b0000 0011 // Маска (будем делать по ИЛИ).
Стало:
0b0000 1011 // Стало PORTn=0x0B;
Бит 3 остался не тронутым. Разве это не маскИрование?
Маской по & из 0b0000 1000 разве 0b0000 1011 сделаешь?
П.С. Тут наверное
asteroid7 имел ввиду
частный случай - сбросить в ноль только нужные биты: если так, то да, надо будет применить маскирование по операции
&, т.к. по | такого не получишь.
Т.е.:
Есть байт 0110 0101;
Надо сбросить все биты в ноль, кроме пятого.
Применяем маску 0010 0000 с операцией
&.
Получаем вот такой байт: 0010 0000.
Т.е. разница в том, что мы хотим сделать с помощью битовой маски:
сбросить или же
установить значение.
Добавлено: Пн мар 23, 2009 19:05:43
Digital
Юрий Климчук писал(а):Я очень извиняюсь, что создал такой переполох (спор) своими вопросами...
Да какой там спор. Просто каждый пишет то, в чём сам уверен, ну а ошибаться или не знать чего-то или не так понять может каждый. Век живи, век учись.
По девайсу размышления:
1. Ведь самодельный стенд тоже должен кто-то поверить сначала?
2. Точность такого стенда должна превосходить точность поверяемого устройства на порядок и более. Какая точность у механического секундомера? Т.е. до какого знака надо будет определять время. На картинках точность до 0,0001 сек.
3. Как учесть время нажатия и останова, т.к. началом отсчёта следует считать наверное начало движения стрелки секундомера!?
а) Если по движению, то акустический метод, отпадает наверное, т.к. само нажатие забьёт тикание секундомера!?
б) Если оптическим методом, то самое простое, что приходит в голову - это отражение видимого луча от стрелки. Пропадание сигнала => стрелка начала движение. Но будет ли работать? А остановку как ловить?
Кстати по кнопкам и таймерам на этом форуме много информации есть. Можете тоже использовать в качестве учебного материала.