Она не хочет читать температуру с ds1820. Вот код программы:
Код:
/***************************************************** Chip type : ATmega16 Program type : Application Clock frequency : 8,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/ #include <mega16.h> #include <delay.h>
void hc164_wr(unsigned char dig1, unsigned char dig2){ //подпрограмма вывода данных в регистр
unsigned char a;
for(a=0; a<8; a++){ //цикл для вывода 8 бит данных из массива
PORTD.1=buf[dig1] & 1<<a; //выводим в линию DATA1 текущий бит PORTD.0=buf[dig2] & 1<<a; //выводим в линию DATA2 текущий бит PORTD.2=0; //опускаем линию CLK в лог.0 PORTD.2=1; //поднимаем линию CLK в лог.1 } }
while (1) { if(t>=500){tem(); t=0;} // Читаем температуру раз в секунду }; }
Все время светится 85 или что-то непонятное, в протеусе все работает нормально. Без 74HC164, тоже работало нормально. Если вызов функции чтения температуры из цикла перенести в таймер, то чтение происходит нормально, но индикация пропадает
Зарегистрирован: Пт мар 18, 2011 12:41:09 Сообщений: 25
Рейтинг сообщения:0
Чего то я не понял, в библиотечке ds1820.h функция ds1820_temperature_10() сама преобразование запускает в термометре или это нужно делать принудительно? Если сама, то надо порыскать на тему того, как она это делает - в случае когда у вас постоянно выводится +85С, судя по всему, температура считывается(но, все таки в этом тоже стоит убедится - оторвать градусник и посмотреть что будет. Если ничего не изменится то.. дело было не в бобине:) ), но конвертирование температуры никто почему то не запускает и градусник выдает постоянно исходное значение температуры, которое в нем всегда находится при включении.
Кстати на счет оторвать градусник... зря вы в своей программе проверяете его наличие только при включении. А что будет если он отвалится? Лучше кажый раз смотреть есть ли что на линии... а еще лучше найти datasheet на датчик - там все прекрасно описано, есть и блок -схема оптимального алгоритма обмена данными и последовательность комманд, и куча другой полезной информации...
Блин.... чего то я торможу. Вы в курсе что такое протокол 1-wire? Если нет, то советую прочесть - http://radiokot.ru/articles/13/ Отличное руководство, сам когда писал программку на асме им пользовался. Так вот, для 1-wire огромное значение имеет задержка даже на 30-40мкс. Вот выставили вы шину в 0, приготовились читать значение на шине, а тут БАЦ и всунулось прерывание. Вот и конец всей посылке.
А вот на счет таймера я как то не понял - TCCR1B=0x0B; Зачем Waveform Generation Mode включать? При настройке регистров лучше все писать в виде TCCR1B =(1 << CS11) | (1 << CS10); компилятор один хрен все к виду TCCR1B=0x0B переделает, но читабельность возрастает на порядок.
Зарегистрирован: Пн мар 15, 2010 18:00:02 Сообщений: 15 Откуда: Свердловская область. ГО Сухой Лог
Рейтинг сообщения:0
Здравствуйте, КАШАК. Я как-то делал термометр, но на Atmega48, тогда ещё не использовал сдвиговый регистр, а развесил всё прямо на МК (есть моделька для Протеуса). Код получился довольно компактный, для работы с датчиком нашёл какую-то библиотеку, она была великовата и я её поправил. Если вам нужно, могу скинуть свой проектик (на Си) (коменты имеются) + модель для Протеуса. Тестил в реале - работает безотказно.
Насчет проверки наличия датчиков: это только часть программы, потом добавится проверка и чтение с двух датчиков Но пока она и с одного читать не хочет... Только никак не могу понять, почему эта программа работала с обычной динамической индикацией, а с 74HC164 не хочет? Ведь "тики" таймера и прерывания остались прежними...
_________________ Опыт растет прямо пропорционально выведенному из строя оборудованию...
Только никак не могу понять, почему эта программа работала с обычной динамической индикацией, а с 74HC164 не хочет? Ведь "тики" таймера и прерывания остались прежними...
... для начала "подчистите" код - например
Код:
switch (cur_dig){ case 0: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b00010001; break; case 1: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b00100010; break; case 2: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b01000100; break; case 3: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b10001000; break; }
можно записать
Код:
switch (cur_dig){ PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); case 0: PORTC=0b00010001; break; case 1: PORTC=0b00100010; break; case 2: PORTC=0b01000100; break; case 3: PORTC=0b10001000; }
... а чтобы найти ошибку - поставьте BreakPoint в функцию вывода
Последний раз редактировалось ChipKiller Вс мар 27, 2011 16:31:09, всего редактировалось 1 раз.
Только никак не могу понять, почему эта программа работала с обычной динамической индикацией, а с 74HC164 не хочет? Ведь "тики" таймера и прерывания остались прежними...
... для начала "подчистите" код - например
Код:
switch (cur_dig){ case 0: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b00010001; break; case 1: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b00100010; break; case 2: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b01000100; break; case 3: PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b10001000; break; }
можно записать
Код:
switch (cur_dig){ PORTC=0; hc164_wr(digit_out[cur_dig], digit_out[cur_dig+4]); PORTC=0b00010001; break; case 0: PORTC=0b00010001; break; case 1: PORTC=0b00100010; break; case 2: PORTC=0b01000100; break; case 3: PORTC=0b10001000; }
... а чтобы найти ошибку - поставьте BreakPoint в функцию вывода
Если так написать, то программа не работает, выводится только первая цифра на кждом из двух индикаторов...
_________________ Опыт растет прямо пропорционально выведенному из строя оборудованию...
вот пример из "закромов", как с помощью всего 4-х выводов управлять 6-ти разрядным семисегментным индикатором
Если только для общего развития, а практическая ценность схемы равна нулю. Ведь ток дешифратора 74HC155 по ДШ всего 4 мА. Делим на количество разрядов: 4/6=0,7 мА средний ток на разряд. Если горит 8 и "зпт", то делим еще на 8: 0,7/8=0,09 мА средний ток на сегмент. Конечно в безлунную ночь можно будет что-то прочитать, а днем ни-ни, даже с черной накидкой.
Если только для общего развития, а практическая ценность схемы равна нулю.
... нулю равны Ваши знания в применении Протеуса. Данная схема успешно работает. Добавление транзисторов для управления разрядами индикатора ни как не отразится на отлаженном коде программы. Если желание собрать набор глюков, то можно "возмущаться" и в отсутствии конденсаторов в схеме.
Добавление транзисторов для управления разрядами индикатора ни как не отразится на отлаженном коде программы.
А ректификационной колонны и ветряного генератора? Вы уж как-то намекайте, я же не могу знать, о чем думает Ваша левая пятка. Транзистор вроде как бы инвертирует, надеюсь это в Ваши знания входит?
>>Если вызов функции чтения температуры из цикла перенести в таймер, то чтение происходит нормально, но индикация пропадает
Как и выше сказали, на время обращения к датчику необходимо блокировать прерывания. При входе в таймер все прерывания блокируются автоматически, поэтому происходит успешное считывание. Надо сделать так: #asm("cli") temp=ds1820_temperature_10(0); #asm("sei")
При таком подходе индикация будет пропадать на 750мс - время преобразования температуры. Чтобы избавится от этого недостатка вам придется расковырять встроенную в CVAVR библиотеку и функцию измерения разбить на части(маленькие функции): 1)отключение прерываний, запуск измерения, включение прерываний 2)подождать 750мс 3)откл. прерываний, считвание показаний, вкл. прерываний
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения