Attiny 2313 и терморезистор

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Attiny 2313 и терморезистор

Сообщение Spad »

Скажу сразу, что я только начинаю изучать микроконтроллеры. Пытаюсь прогаммировать на avr. Проблема такая: мне надо считывать показания с терморезистора. Если точнее, то с автомобильного датчика температуры (который на стрелку идет). Покапавшись несколько часов в интернете, переводил даташит переводчиком так как в английском я не особо силен, результат нулевой. Вопрос такой: как датчик будет подключаться к контроллеру? Что надо прописать в пограмме чтобы не видеть на входе 1 или 0, а видеть показания какие-нить? Если можно, то по подробнее. прям для чайников )))
Заранее благодарен!
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Сообщение DrWatson »

Вот примерная реализация в железе "измерения" сопротивления терморезистора с использованием аналогового компаратора и таймера Т1.
Принцип такой: бит 0 порта В изначально устанавливаем в 0, т.е. конденсатор С1 будет замкнут на общий. Таймер Т1 настроен на захват по переключению компаратора из 0 в 1 и пока остановлен. так как на плюсовом входе напряжение 0, а на минусовом - напряжение заданное делителем R1,R2 >0, выход компаратора выдает 0.
переводим бит 0 порта В в Z-состояние (программируем его как вход) и запускаем таймер Т1. Теперь конденсатор С1 начинает заряжаться через терморезистор и скорость его зарядки будет зависеть от сопротивления терморезистора TR (чем меньше сопротивление, тем быстрее будет заряжаться конденсатор). По мере зарядки конденсатора, на его верхнем выводе будет напряжение расти и соответственно на плюсовом входе компаратора тоже. А таймер тем временем тикает. Когда напряжение на конденсаторе достигнет (и будет расти дальше) напряжения на минусовом входе компаратора (заданного делителем R1,R2), выход компаратора переключится в 1 и произойдет "захват" значения счетчика Т1 (TCNT1) - его значение в этот момент будет скопировано в регистр ICR1. Вот это значение будет соответствовать определенному сопротивлению терморезистора: меньше сопротивление - быстрее заряжается конденсатор - меньше значение в регистре ICR1, и наоборот: больше сопротивление - медленнее заряжается конденсатор - больше значение в ICR1.
Останавливаем Т1, обнуляем TCNT1, считываем значение из ICR1, переводим бит 0 порта В в режим выхода и выставляем в него 0 - чтобы разрядить конденсатор для следующего измерения.
резисторы R1, R2 следует подобрать такими (например 20к и 10к), чтобы их отношение R1/R2 было равно примерно равно 2 (это даст на минусовом входе компаратора 1/3 напряжения питания, до которого будет заряжаться конденсатор до захвата таймера, если позволить ему заряжаться до большего напряжения, то нелинейность зависимости захваченного значения от сопротивления терморезистора будет увеличиваться). А конденсатор следует выбирать исходя из сопротивления терморезистора при нормальных условиях в зависимости от частоты, которой тактируется Т1 (или частоту Т1 выбирать исходя из емкости конденсатора и спротивления терморезистора), главное, чтобы емкость С1 не была слишком большой, иначе ток разряда через бит 0 порта В может его (порт) повредить.
Компаратор настраиваем так (Си):

Код: Выделить всё

ACSR=0x04; /* в этом регистре устанавливаем бит ACIC, который подключает выход компаратора к схеме захвата таймера */
DIDR|=0x03; /* устанавливаем в единицу биты AIN1D, AIN0D в регистре DIDR, т.е. отключаем цифровые входы от этих выводов МК */
Таймер настраиваем так (на Си):

Код: Выделить всё

TCCR1A=0x00; // обычный режим счета
TCCR1B=0xC0; //режим захвата с "защитой от дребезга", таймер остановлен
TCCR1C=0x00;
TIMSK=0x00; /* (если будем обрабатывать захват в прерывании, то пишем 0x08, но не забываем написать обработчик прерывания) */
Порт В натраиваем так (Си):

Код: Выделить всё

DDRB&=0xFD; // бит 1 - вход
DDRB|=1; // бит 0 - выход
PORTB&=0xFC; // бит 1 без подтяжки, бит 0 - на выходе 0

Для запуска измерения пишем (в Си):

Код: Выделить всё

TCNT1H=0; // обнуляем значение счетчика таймера
TCNT1L=0; // старший и младший байты (он 16-разрядный)
DDRB&=0xFE; // бит 0 порта В делаем входом
TCCR1B=0xC1; /* Запускаем таймер с предделителем 1, для других предделителей: 0xC2 - 8; 0xC3 - 64; 0xC4 - 256; 0xC5 - 1024 */
while(TIFR&0x88); /* Ждем захвата, когда бит ICF1 регистра TIFR установится в 1 или переполнения таймера (флаг TOV1 установится в 1 в случае если емкость С1 оказалась слишком большой или терморезистор "отвалился", тогда захват не произойдет никогда) */
TCCR1B=0xC0; // Останавливаем таймер
TIFR&=0xF7; // обнуляем флаг ICF1
DDRB|=0x01; // разряжаем конденсатор
if(TIFR&0x80) // произошло переполнение таймера
{
  TIFR&=0x7F; // обнуляем флаг TOV1
   /* Здесь обрабатываем ситуацию, когда измерение не удалось (терморезистор "отвалился") */
}

в случае успеха в регистре ICR1 ( а точнее в ICR1H и ICR1L) будет измеренное значение (не в омах или килоомах, конечно, а в неких условных единицах, соответствующих текущему значению сопротивления терморезистора)
Вложения
termores.gif
(7.52 КБ) 842 скачивания
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Здравствуйте. Может пригодится метод измерения из этой веточки, позволяющий избавиться от нелинейной зависимости напряжения на конденсаторе при заряде (разряде) через резистор.

http://www.radiokot.ru/forum/viewtopic. ... highlight=
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Сообщение DrWatson »

это вариант измерения сопротивления резистора, а, как известно, зависимость сопротивления от температуры нелинейна, поэтому этот вариант для измерения температуры будет требовать чуть больше вычислений, плюс дополнительный замер "сопротивления" эталона, чем предложенный мной, однако точность, полагаю будет выше. А для автомобильного датчика температуры оно надо? У стрелочного инструментальная погрешность, если не ошибаюсь, градусов 5.
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Сообщение GP1 »

ИМХО проще такое сварганить на чем-нибудь, что имеет встроенный АЦП, тини13 - например, очень люблю этот процик :tea:
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

Всем спасибо. Принцип понятен. Надо подробнее со всем разобраться. Я не прощаюсь ;)
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

Не получаеться. Вобще никак ((( У меня выход компаратора не переключатся в 1 вобще никак. Я просто сначала написал весь код, у меня не работало. Потом начал искать проблему. Решил проверить, что у меня происходит с компаратором. Сделал так, что если выход компаратора переключатся в 1, то загорается светодиод, если не пееключается, то диод не горит. Диод не горит

Это моя первая прошивка. Только начинаю изучать. Так что извините за глупые вопросы.

Вот че я понаписал:

Код: Выделить всё

     Reset:     
          ldi Temp,0x04
          out ACSR,Temp         ;в этом регистре устанавливаем бит ACIC, который подключает выход компаратора к схеме захвата таймера

          ldi Temp,0x03
          out DIDR,Temp         ;отключаем цифровые входы от этих выводов МК
         
         
          ;********* Настройка Таймера *********

          ldi Temp,0x00
          out TCCR1A,Temp       ;обычный режим счета

          ldi Temp,0xC0
          out TCCR1B,Temp       ;режим захвата с "защитой от дребезга", таймер остановлен

          ldi Temp,0x00
          out TCCR1C,Temp;

          ldi Temp,0x00   ;запретить прерывания
          out TIMSK,Temp
         
          ldi Temp,0xFD   ;настройка портов
          out DDRB,Temp         ;бит 1 - вход бит 0 - выход
         
          ldi Temp,0xFC
          out PORTB, Temp
         
          ldi Temp, 0b11111111  ;
          out DDRD,Temp         ;вывод
         
          ldi Temp,RamEnd       ;установка указателя стека
          out SPL,Temp
         
          ldi Temp1,0           ;инициализация индикатора
         
          sei                   ;разрешить прерывания



         ldi Temp,0             ;обнуление таймера
         out TCNT1H,Temp
         out TCNT1L,Temp

         ldi Temp,0xFE
         out DDRB,Temp          ;бит 0 порта В делаем входом
         
         ldi Temp,0xC1
         out TCCR1B,Temp        ;Запускаем таймер с предделителем 1

         ldi Temp,TIFR
         cpi Temp,0b00001000
         breq out
         rjmp Reset

out:    ldi Temp,0b00000001
        out PortD,Temp

        rjmp reset


Чую куска какого-то не хватает
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Сообщение DrWatson »

Вот здесь что имеем?

Код: Выделить всё

ldi Temp,TIFR 
         cpi Temp,0b00001000
         breq out
         rjmp Reset

Во-первых надо проверять один интересующий нас бит, а не сравнивать весь регистр с числом, во-вторых проверка дала "не равно" и куда переходим? на Reset и проводим всю процедуру инициализации с начала. А надо бы крутиться - проверять дальше. Попробуй примерно так:

Код: Выделить всё

loop1:   ld Temp,TIFR    ; Загружаем в Temp значение из TIFR
         sbrs Temp, 3    ; если в Temp бит3 единица, перескакиваем rjmp
         rjmp loop1       ; иначе крутимся в цикле дальше
         ld Temp,0b00000001
         out PortD,Temp ; Зажигаем светодиод
loop2:   ld Temp,TIFR ; здесь ждем в цикле когда бит 3 станет нулем
         sbrc Temp, 3
         rjmp loop2
         ld Temp,0
         out PortD,Temp ; гасим светодиод
         rjmp loop1     ; и снова по кругу

Вообще в данном случае нам надо в PortD менять один бит, а не весь порт, потому надо бы заменить ld Temp, 0b00000001 и out PortD, Temp конструкцией типа:

Код: Выделить всё

     in Temp, PortD
     sbr Temp, 0b0000001 ; уст-ем в единицу нулевой бит
     out PortD, Temp
     .....
     in Temp, PortD
     cbr Temp, 0b00000001 ; сбрасываем в ноль нулевой бит
     out PortD, Temp

и еще: когда идет пересылка регистр-регистр, регистр-порт, используется команда ld, а не ldi. Команда ldi записывает в регистр константу, т.е. ldi Temp, TIFR загрузит тебе в Temp не содержимое этого регистра, а его адрес.
Прерывания ты не используешь, значит команда sei не нужна (закомментируй пока).
В асме АВРок я толком не ковырялся, поэтому возможно не все ляпы заметил и код может быть привел не очень удачный, но пока попробуй такой, может кто из спецов по асму потом присоединится, поправит - будем вместе язык учить :)
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Сообщение GP1 »

1. настоятельно рекомендую перейти на тини13
2. правилами хорошего тона программирования на асме предусмотрено первой командой после reset запрещать прерывания, затем инициализировать стек, и уже потом все остальное
грузить 0 в регистр командой ldi..., ну есть же спец. оператор clr
для установки/сброса одной линии порта есть команды sbi/cbi
(это так - для общего развития)
3. про переход вам указали, но даже если исправить переход, то единожды сработав у тебя так и будет висеть единица во флаге TIFR, при таком методе ее надо сбрасывать в 0 программно.

зы: что за датчик/авто
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

DrWatson, компилятор ругается на команду ld. Может быть я не тот компилятор использую? Я сделал все как написано в обучалке на этом сайте. Такой же программатор, те же программы (avreal, tavrasm).

GP1, на тини13 портов маловато. Я задумал не просто измерение температуры, а в зависимости от температуры будет на определенное положение выставляться заслонка подсоса. Заслонку двигать будет моторедуктор от печки 2110 (там тоже будет сопротивление мерить).
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

Сообщение Meteor »

1) Присоединяюсь к GP1.
Но раз надо альтернативу то переходите на мегу 8, 16, 8535 и ног достаточно и АЦП 10 бит да еще и с мультиплексором на 8 каналов, один из которых можно использовать для термокоррекци. А "изголяться" с аналоговым компаратором - себе дороже. Опыт конечно приобретете, но запаритесь по страшному.
2) Покажите фрагмент "животного". Команда ld-штатная, так что скорее всего Вы сами ее нештатно используете.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

на 2313 я хоть что-то делал, а мегу я вобще в руках ни разу не держал. Я сейчас тут уже всех достал, вы представляете че с мегой будет...

Вот фагмент. Он же есть выше

Код: Выделить всё

loop1:   ld Temp,TIFR    ; Загружаем в Temp значение из TIFR
         sbrs Temp, 3    ; если в Temp бит3 единица, перескакиваем rjmp
         rjmp loop1       ; иначе крутимся в цикле дальше
         ld Temp,0b00000001
         out PortD,Temp ; Зажигаем светодиод
loop2:   ld Temp,TIFR ; здесь ждем в цикле когда бит 3 станет нулем
         sbrc Temp, 3
         rjmp loop2
         ld Temp,0
         out PortD,Temp ; гасим светодиод
         rjmp loop1     ; и снова по кругу
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Сообщение DrWatson »

Мой косяк :) надо in Temp, TIFR
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

Сообщение Meteor »

Spad писал(а):на 2313 я хоть что-то делал, а мегу я вобще в руках ни разу не держал. Я сейчас тут уже всех достал, вы представляете че с мегой будет...

То же что и сейчас - ничего страшного
А за каким... Вы загружаете константу командой ld?
Ведь прекрасно справляется с этим ldi. А ld- читает с регистра
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Сообщение GP1 »

Spad писал(а):GP1, на тини13 портов маловато. Я задумал не просто измерение температуры, а в зависимости от температуры будет на определенное положение выставляться заслонка подсоса. Заслонку двигать будет моторедуктор от печки 2110 (там тоже будет сопротивление мерить).


у тини13 достаточно ног чтобы управлять движком, мерять 2 резистора и можно еще вывод температуры в цифре организовать :wink:
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

Сейчас заработало. Диод загорается. Но это ладно. Я уже думаю, может действительно взять другой контроллер. Посмотрел тини13. Там 1 или 2 ноги нужны для замера сопротивления? Если 2, то по любому не хватает ног.
2 ноги будут заслонку двигать
1 нога будет газ несколько раз нажимать в холодную погоду (ниже 2-3 градусов) чем ниже температура, тем больше раз надо нажать.
1 нога для тахометра.
Еще надо на датчик температуры ноги и на моторедуктор котоый подсос будет двигать, чтобы контроллер видел в какую сторону надо двигать и в каком положении заслонка.

Например: температуа -5, нажать 3 раза на педаль, вытянуть подсос на 100%, (сигнализация заводит, в настройках надо будет задержку поставить побольше), обороты 2500-2700, убираем подсос до того пока обороты на упадут до 2200. Дальше поверяем температуру, чем больше температура, тем меньше обоотов.
Вот вся моя задумка ))


И еще вопрос. Как сравнивать бит? Команды sbrs\sbrc не подходят. Они не пропускаю дальше, пока бит не установится или наоборот не пропадет. А мне надо что-то типа cpi
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

Сообщение Meteor »

Как это не подходят sbrs и sbrc?? :shock: Вот например
sbrc temp, 0x08
rjmp loop1
rcall function1
......
.......
loop1:
sbrs temp, 0x10
rjmp loop2
rcall function2
...
после сравнения бита в первом случае либо перейдет на метку loop1 либо если бит =0 вызовет функцию 1. со вторым тоже самое но переход на функцию 2 будет по 1 в разряде порта
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Сообщение GP1 »

Spad писал(а):Сейчас заработало. Диод загорается. Но это ладно. Я уже думаю, может действительно взять другой контроллер. Посмотрел тини13. Там 1 или 2 ноги нужны для замера сопротивления? Если 2, то по любому не хватает ног.
2 ноги будут заслонку двигать
1 нога будет газ несколько раз нажимать в холодную погоду (ниже 2-3 градусов) чем ниже температура, тем больше раз надо нажать.
1 нога для тахометра.
Еще надо на датчик температуры ноги и на моторедуктор котоый подсос будет двигать, чтобы контроллер видел в какую сторону надо двигать и в каком положении заслонка.

Например: температуа -5, нажать 3 раза на педаль, вытянуть подсос на 100%, (сигнализация заводит, в настройках надо будет задержку поставить побольше), обороты 2500-2700, убираем подсос до того пока обороты на упадут до 2200. Дальше поверяем температуру, чем больше температура, тем меньше обоотов.
Вот вся моя задумка ))


никогда не слышал о двойном использовании ног у мк? :shock:
по твоей задумке скорее не хватит памяти, чем ног :) можно взять тини с большей памятью.
1. замер температуры на борту - нога вход АЦП
2. если надо делаем 3 качка - эта же нога выход на привод "нажималки" , все, больше этот выход до следующей процедуры запуска нам не понадобится, переводим его обратно на вход АЦП

Итого:
температура/дрыгалка дроселя - 1 нога
положение воздушной заслонки - 1 нога
вход тахометра - 1 нога
управление заслонкой - 2 ноги

О! у меняу даже лишняя нога осталась :)))
т.е. даже без совмещения функций ног вполне хватает.
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Spad
Родился
Сообщения: 13
Зарегистрирован: Сб дек 05, 2009 00:13:48
Откуда: Дзержинск

Сообщение Spad »

Ну я же говорю, что ничего не сображаю ))) Насчет двух ног, я думал, что для измерения придется использовать две ноги. Как объяснил DrWatson.

Читал на каком-то форуме. Там примено тоже самое сделали на 2313, но там сигнализация стояла без автозапуска. Т.е там контроллер проверял поднят ли ручник, нейтральное положение рычага кпп, даже выжимал сцепление, регулировал подсос, крутил стартером, так же регулировал обороты и двигал заслонку в зависимости от темпеатуры. Я хочу сказать, что заморочек там больше, а памяти хватило.
Ну если вы считаете, что памяти не хватит, то как тогда узнать какой контроллер использовать?

Meteor, спасибо. Я делал немного по другому. Попробую так.
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Сообщение GP1 »

по-любому прежде чем покупать мк нужно накидать софтину и погонять ее в симуляторе, т.е. если не хватит памати перейдешь на другой мк с большей памятью.
Чем дальше, тем больше становлюсь занудой...
Изображение
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»