 |
|
|
|
| Автор |
Сообщение |
tellurian Частый гость (>5)

Зарегистрирован: 15.11.2006 Сообщения: 15
|
Добавлено: 24 Ноя 2006, 11:28 Заголовок сообщения: |
|
|
Я немножко с таймером не понял . Вот как можно установить таймер ровно на 1 секунду?
|
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 24 Ноя 2006, 13:52 Заголовок сообщения: |
|
|
1. Прерывание возникает при переходе TCNT с 0xFF в 0x00
2. Каждый такт к TCNT прибавдяется единица
3. Тактируем от внутреннего генератора
4. При использовании внутреннего генератора можно использовать предделитель
тактовая частота (F) равна 1МГц ... ставим делитель 10000 ... получаем частоту на таймер 100 Гц ... в TCNT0 (счетчик 1 байт) запишем число 0xFF - 100 = 155 ... значит через 100 тактов счетчик переполнится (переход 0xFF -> 0) и возникнет прерывание по переполнению... так-как частота 100 Гц, значит времени пройдет 1Сек. Если это число (155) закидывать в счетчик в самом начале обработки прерывания, то таймер будет тикать с периодом 1сек (1гц).
Если используем прерывание по совпадению, то в регистр совпадения нужно писать само число, а не 0xFF-число (думаю ясно почему) и в TCNT записывать 0 (есть вариант настройки таймера так, что он сам при прерывании по совпадению будет инициализировать счетчик)
Это общий принип.
Осталось учесть:
- значения делителей строго описаны (1 8 64 256 1024)
- мог ошибится +\- единица ... посмотреть толком когда плюсование происходит и киогда переполнение вызникает
- если программу пишем на С, то при возникновении прерывания выполняется некоторый код... и только потом мы записываем число в таймер... следовательно число надо писать больше расчитанного вые, ибо уже время прошло некоторое.
_________________ AndryG |
|
| Вернуться к началу |
|
 |
tellurian Частый гость (>5)

Зарегистрирован: 15.11.2006 Сообщения: 15
|
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 01 Дек 2006, 9:35 Заголовок сообщения: |
|
|
C возвращением.
1. Дабы таймер работал с нужной выдержкой... нужно его инициализировать в самом начале кода прерывания... ибо получается как: сперва 50 тактов работы в прерывании - пототм инициализация таймера... в другой раз при других условиях 80 тактов и только потом инициализация. Так-как таймер инициализируем одним числом, то задержки будут разные. В нашем случаем на такую разницу наплевать, но в иных задачах можно и глюк получить.
2. Посмотрите на код. У Вас повторяются вложенные условия, в которых Вы выполняете ПОЧТИ одинаковые действия... инициализация одним и тем же числом (0) и разные проверки (3 или 4). И там и сям переключаете светодиод. Когда одна строка повторяется - полбеды, а если такие куски большие будут? Можно ставить функции. Но функции - это лишний корд на вызов функции Давайте немного перекрутим алгоритм:
| Код: |
unsigned char tmp1=0; //размер до переделки 130, после - 117
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //описываем прерывание
{
tmp1++;
TCNT1 = 0xFCBD; //ПЕРВЫМ ДЕЛОМ!!! устанавливаем таймер на 0,25 сек.
if (tmp1>3) //оно же ">=4"
{
PORTB = PORTB ^ 1;
if (PINB&0x02) // "Если кнопка отпущена"
tmp1 = 1; // 0,75 Гц
else
tmp1 = 0; // 1,00 Гц
} // tmp1>3
}//tim1_ovf
|
Если счетчик больше 3 (=4) - переключим светодиод и дальше посмотрим. чем инициализировать: Если нажата кнопка - 0, отжата - 1 ... инициализировав int1 единицей мы получим меньше выдержку.
3. Обращайте внимание на размер данных. Это Вам не PC с сотнями метров памяти Вам совершенно не нужен тип INT(16 бит). Первое... у нас возможны значения 0..4 и нам вполне хватит UNSIGNED CHAR (8 бит). Второе... Вы заставляете восьмиразрядное АЛУ работать c несвойственным ему размером данных - это лишний код. Таким образом мы разбрасываемся и памятью программ (на код) и данных (лишний байт данных)
Обратив внимание на такие мелочи получилось сократить код на 10%.
___
P.S.
Ну и совсем мелочь ... вместо int1+=1 можно поставить int1++ . Работать будет полюбому и код тот же, но читать легче... не нужно втыкать "сколько же там увеличение" .. просто "+1".
_________________ AndryG |
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 01 Дек 2006, 13:26 Заголовок сообщения: |
|
|
Поехали дальше.
Скучно такие задачки решать ... давай какую-нить полезность делать .. на ее примере и разберемся с программированием.
Ну там часики или хрень какую... только не с дорогущими комплектующими ... я тогда и себе в железе соберу - будет легче работать с ней... хотя можно и в симуляторе (proteus) прогнать кучу железок .. но, как по мне, не интересно это - канифоль не воняет, ничего не горит
Вот что надумали. (посты по обговариванию примера удалены для читабельности)
Семисегментный индикатор пара кнопок.
Эволюция прибора:
включаем переферию - учимся работать со всем...
делаем классические часики
добавляем ночной режим (индикатор слабо горит)
будильник
учимся не забывать время при пропадании напруги сети
добавляем температурометр
подключаем нагреватель - температуру будем стабилизировать (учим ПИД-регулирование )
подключаем светодиод и будильником включаем телек... да погромче!
добавляем COM-порт и включаем/управляем компом ... например возле часиков еще и температурка будет "за бортом"
впихиваем в контроллер искуственный интеллект, подключаем часики через COM-порт к компу, запукаем любой терминал ... будет с кем поговорить при плохом настроении
Приветствуются дополнения к развитию "часов". Или свое устройство с подобным развитием.
_____
P.S.
Здесь еще один пример показательной разработки устройствa
_________________ AndryG
Последний раз редактировалось: AndryG (10 Янв 2007, 13:57), всего редактировалось 3 раз(а) |
|
| Вернуться к началу |
|
 |
Alexx Знатный посетитель (>20)


Зарегистрирован: 25.09.2006 Сообщения: 49 Откуда: Украина, Киев
|
Добавлено: 01 Дек 2006, 14:59 Заголовок сообщения: |
|
|
| AndryG писал(а): | на 2313 только часы и получатся .. а куда же навороты?
ЛЮДИ!!! Еще кто есть?! посоветуйте! |
Предлагаю остановиться на 32-й меге.
Эдакий универсальный камень для большинства мелких и средних проектов.
И цена не кусается, и статус EOL не скоро присвоят, и на борту много чего вкусненького, да и в ДИП-е найти можно его, что для "самопая" немаловажно.
|
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 04 Дек 2006, 13:08 Заголовок сообщения: |
|
|
В общем мы посоветовались и я решил
Предлагаю продолжать взлет к вершинам программирования на платформе NS182.2 от МастерКит.
Краткое описание платформы:
AT90S2313,
4-х разрядный семисегментный индикатор c общим катодом,
как расширитель порта 8-разрядный сдвиговый регистр 74HC164,
часы реального времени PCF8583,
температурометр DS18B20.
Дальняя цель - удовлетворить потребность этого человека
Информационное обеспечение :
Проект Proteus c указанным железом окромя термодатчика - нет модели... у кого есть - может поделитесь? (Это RAR-архив!!! - измените расширение после закачки)... там же описание 74HC164
инструкция оригинального устройства
исходники оригинального устройства
схема принципиальная устройства
модель PCF8583 для Proteus
После разбирательства с этой платформой возьмемся, как и советовал Alexx, за Mega32. (надо придумать будет тоже крутое нечто)
Дальше предлагаю работу строить так: в этой ветке учимся работать с переферией отдельно, потом объединять и добавлять функционал в схему.
Обсуждение создания новой прошивки а-ля ns182 предлагаю перенести в новую ветку - так-как там вопросы будут, которые другим могут быть совсем не интересны.
_____
P.S.
У меня Proteus 6.9SP5 при большом коде контроллера глючит. Подменил библиотеку AVR.DLL на более старую (с 6.7SP3) - всё пошло. По ссылке лежит RAR-архив!
_________________ AndryG
Последний раз редактировалось: AndryG (03 Май 2007, 10:35), всего редактировалось 9 раз(а) |
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 04 Дек 2006, 16:49 Заголовок сообщения: |
|
|
Ну и задачка на основе сего железа.
"Вывести на индикатор число 0412"
Написать знакогенератор для его индикатора
Разобратся с динамической индикацией.
Разобраться с сдвиговым регистром - засылка в него потоков информации.
Коротко принципы работы:
Сдвиговый регистр.
74HC164 8-разрядный сдвиговый регистр с последовательной загрузкой и параллельной выгрузкой... другими словами ... подавая биты последовательно на вход DATA получаем их же на выходах Q0-7
При положительном фронте на входе CLK (0->1) данные выходов Q0-7 сдвигаются влево, а в Q0 "переходит" DATA.
Таким образом для задвигания бита в регистр нам нужно:
1. установить CLK в 0
2. установить необходимый уровень на DATA
3. установить CLK в 1
И напоследок. Всё это действительно, если на входе R установлена единица, иначе все выходы переходят в ноль - производится очистка регистра.
Маленькое дополнение. При вводе нового байта нам вовсе не нужно очищать регистр - новый байт просто "вытолкнет" предыдущий и о нем можно забыть.
В нашем устройстве сдвиговый регистр дает экономию выводов микроконтроллера - с помощью двух выводов (DATA и CLK) мы управляем восемью выводами индикатора.
Динамическая индикация в Сети много о этом написано - посему очень кратко. (если найдете красивоописание - киньте ссылку в ветку)
Семисегментный индикатор с общим катодом содержит семь светодиодов(A-G) у который катоды объеденены в один вывод. Для зажигания циферки нам нужно подать напругу на определенные аноды(+) (на какие именно - указывает нам знакогенератор)и общий катод(-).
Если используется несколько разрядов, то у них объединяют соответствующие аноды диодов. (все A вместе, В вместе и т.д.) ... так мы получаем подобие матрицы (одноименные аноды образуют горизонтали и общие катоды каждого индикатора - вертикали.)
Теперь, дабы красиво горели ВСЕ индикаторы мы делаем следующее:
1 тушим индикатор (на все катоды даем +)
2 выставляем цифру 1-го разряда (на нужные аноды (A-G) подаем +)
3 зажигаем 1-й разряд общий катод первого индикатора садим на минус
4 выдерживаем немного времени
5 тушим индикатор
6 дальше с пункта два, но уже с следующим разрядом.
Таким образом мы поочередно зажигаем нужные цифры на индикаторах. Если делать это быстро, то такой перебор будет смотреться без миганий (все вспомнили кинематограф)
_________________ AndryG
Последний раз редактировалось: AndryG (19 Янв 2007, 15:09), всего редактировалось 1 раз |
|
| Вернуться к началу |
|
 |
day177 Знатный посетитель (>20)


Зарегистрирован: 25.12.2006 Сообщения: 51 Откуда: Тула
|
Добавлено: 25 Дек 2006, 12:24 Заголовок сообщения: |
|
|
| Код: | #include <90s2313.h>
#include <delay.h>
void main(void) {
DDRB = 0x01; //определяем направление
PORTB = 0x00; //загорается светодиод
while (1)
{
PORTB ^= 0x01; // переключили светодиод
delay_ms(50); // задержка (для реала нужно больше ставить)
}; //while
} //main |
Господа, объясните пожалуйста словесно эту программку. Особенно интересует что делает строчка PORTB ^= 0x01. После паузы куда переходит программа: в DDRB = 0x01;... или опять в PORTB ^= 0x01...?
Не бейте пожалуста - просто никак не могу понять смысл исключающего ИЛИ.
Все ведь с чего-то начинали
Кстати - как подключен светодиод: катодом на землю, а анодом через резюк PB0?
|
|
| Вернуться к началу |
|
 |
AndryG Модератор
Зарегистрирован: 24.07.2006 Сообщения: 411 Откуда: Helios-3
|
Добавлено: 25 Дек 2006, 12:50 Заголовок сообщения: |
|
|
"Исключающее ИЛИ" можно перефразировать "разные значения".
| Код: |
Таблица истинности:
A B R
1. 0 0 0
2. 0 1 1 -- !!!
3. 1 0 1
4. 1 1 0 -- !!!
|
Обратите внимание на выделенные строки.
PORTB ^= 0x01 -- аналогичная запись PORTB = PORTB ^ 0x01
Если PORTB.0 (вес бита 1) равен 1, то он станет 0 (4 строка в табл. истинности) и наоборот - если PORTB.0 = 0, то будет 1 (2 строка в табл.)
Остальные биты PORTB значения не изменят... смотрите таблицу.
Таким образом в строке PORTB ^= 0x01 число 0х01 указывает "какие биты нужно инвентировать"
Дальше. Смотрим на код ... у нас бесконечный цикл while(1) и его тело заключено в фигурные скобки. Значит строки
DDRB = 0x01; //определяем направление
PORTB = 0x00; //загорается светодиод
выполнятся один раз и строки
PORTB ^= 0x01; // переключили светодиод
delay_ms(50); // задержка (для реала нужно больше ставить)
будут выполнятся бесконечно.
В нашем случае не суть важно как подключить светодиод - моргать будет в любом случаем, но в комментарии есть подсказка
PORTB = 0x00; //загорается светодиод
на вывод подаем ноль и светодиод загорается, значит второй вывод светодиода должен быть подключен на + питания (через огр. резистор)
_________________ AndryG
Последний раз редактировалось: AndryG (26 Дек 2006, 8:16), всего редактировалось 1 раз |
|
| Вернуться к началу |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете добавлять вложения в этом форуме Вы можете просматривать вложения в этом форуме
|
|