Atmega8 + DS18b20 + Led = 8888 , помогите(((

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Drozdov
Родился
Сообщения: 5
Зарегистрирован: Вс июн 12, 2011 21:19:04

Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Drozdov »

Всем доброе время суток, уже с неделю борюсь с данной проблемой. Атмега8 с датчиком ds18b20 и результат преобразований выводим на четыре 7сегментных индикатора. В конечном итоге устройство будет управлять реле через транзистор, но все никак не удается получить показания температуры. Вопрос жизни и смерти... если есть у кого идеи - напишите плз в аську 2087116, почту rekrios@hotmail.com или в скайпе rekrios, ну и конечно же я буду здесь читать ваши ответы.

Текст программы:

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

/*****************************************************

Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

// 1 Wire Bus functions
#asm
   .equ __w1_port=0x15 ;PORTC
   .equ __w1_bit=0
#endasm
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>
char lcd[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
int disp_1=0,disp_2,mode_k=0;    //объявляем переменные дли индикаторов

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x03;
// Place your code here


switch(mode_k)
 {
 case 0:
 mode_k=1;
 PORTB.0=0;
 PORTB.6=0;
 PORTB.7=0;
 PORTB.4=0;  
 
// PORTD =lcd[4];
// PORTB.0=1;
disp_2=disp_1/1000;
PORTD =lcd[disp_2]; 
PORTB.0=1;     

 break;
 case 1:   
 PORTB.0=0;
 PORTB.6=0;
 PORTB.7=0;
PORTB.4=0; 
 mode_k=2;
 
     disp_2=disp_1%1000;
    disp_2=disp_2/100;   
  

 PORTD =lcd[disp_2]; 
 PORTB.4=1;
 
 break;
 
 case 2:
 PORTB.0=0;
 PORTB.6=0;
 PORTB.7=0;
PORTB.4=0; 
 mode_k=3;  
    
 
 
    disp_2=disp_1%100; 
    disp_2=disp_2/10;
PORTD =lcd[disp_2]; 
PORTB.7=1;
 
  break; 
   case 3:
 PORTB.0=0;
 PORTB.6=0;
 PORTB.7=0;
PORTB.4=0; 
  mode_k=0;    
  
  //PORTD =lcd[1];  
  //PORTB.6=1;  
  disp_2=disp_1%10;
 PORTD =lcd[disp_2]; 
 PORTB.6=1;
   break;  
   }




}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=Out 
// State7=0 State6=0 State5=T State4=0 State3=T State2=T State1=T State0=0 
PORTB=0x00;
DDRB=0xD1;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=0 State0=T 
PORTC=0x00;
DDRC=0x02;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
TCCR0=0x01;
TCNT0=0x03;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// 1 Wire Bus initialization
#asm("cli")
w1_init();
delay_ms(500);


// Global enable interrupts
#asm("sei")

while (1)
      {    
      #asm("cli")
      // Place your code here
      disp_1=ds18b20_temperature(0);
      #asm("sei")
    
      };
}
результат этого действа - 8888 на индикаторах, пробовал уже разные варианты кода, разные прерывания, использование cli sei в разных местах но все же не получается, сейчас вот переписал все по-новой и выложил сюда чтобы понять, в чем же трабл...


Индикаторы с общим Анодом, котоды к PD0...6, аноды на PB0,4,6,7
Датчик на PC0

и сразу вопрос, 1-wire должен стоять на in или out ?
Реклама
Аватара пользователя
Coviraylhik
Мучитель микросхем
Сообщения: 420
Зарегистрирован: Чт июн 03, 2010 23:06:12

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Coviraylhik »

Drozdov писал(а):..........результат этого действа - 8888 на индикаторах, ............
Самое простое , но бывает................. вместо индикаторов ОА надо ставить ОК.
Некакого перимирия, Некаких мирных шагов навстречу и периговоров.
Реклама
Drozdov
Родился
Сообщения: 5
Зарегистрирован: Вс июн 12, 2011 21:19:04

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Drozdov »

Создал простую программку без прерываний для проверки...

основные части из нее:

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

#asm
   .equ __w1_port=0x15 ;PORTC
   .equ __w1_bit=0
#endasm
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>
#include <delay.h>

// Declare your global variables here
char lcd[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

...

PORTB=0x00;
DDRB=0xF1;


PORTC=0x00;
DDRC=0x7E; // пробовал для 1wire ставить как вход так и выход, правда ставил без pullup-а вход.


PORTD=0x00;
DDRD=0xFF;

w1_init();
//ds18b20_init(0,0,50,DS18B20_9BIT_RES))
while (1)
{
      // Place your code here
      //temp=ds18b20_temperature(0);
      
      if(ds18b20_init(0,0,50,DS18B20_9BIT_RES))
      {
      PORTD=lcd[1];
      PORTB.4=1;
      }    
      else
       {
      PORTD=lcd[0];
      PORTB.4=1;
      }
      delay_ms(2000);
      PORTB.4=0;
       if(w1_init())
      {
      PORTD=lcd[1];
      PORTB.6=1;
      }    
      else
       {
      PORTD=lcd[0];
      PORTB.6=1;
      }         
      delay_ms(2000);
      PORTB.6=0;
      
      
     
}       // while
результатом должна появится 1 если хотя бы где-то проскочет положительный эффект, так ведь? на обоих индикаторах 0 ((( видимо проблемы с датчиком ?
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение O-LED »

для начала забей на датчик и 1-варе шину. просто выведи на индикатор - "1234"
KIT
Реклама
Эиком - электронные компоненты и радиодетали
Drozdov
Родился
Сообщения: 5
Зарегистрирован: Вс июн 12, 2011 21:19:04

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Drozdov »

1234 выводится без проблем в прерывании...

сейчас вот разбираюсь с датчиком без прерываний с двумя поочередно светящимися индикаторами, результата нету((( точнее он есть, но не в мою пользу
Реклама
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение metan »

Здравствуйте!
Рассмотрим следующую экзотическую конструкцию:

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

while (1)
      {    
      #asm("cli")
      // Place your code here
      disp_1=ds18b20_temperature(0);
      #asm("sei")    
      };
Лично мне не совсем понятно, какая небесная сила позволит нормально работать прерыванию по таймеру, если прерывания разрешены только несколько процессорных тактов?
Разрешаем прерывания, и тут же их запрещаем..
Насколько я в курсе, cli и sei в цикле нужно убить, т.к. в функциях библиотеки ds18b20 они встроены и обрамляют только необходимый кусочек кода.
Это раз.
Во вторых, первое считывание может дать мусор.
Ну и на десерт, непрерывный опрос датчиков может привести к их разогреву.

Рекомендация - ознакомиться с трудами уважаемого автора Danko,
например http://radiokot.ru/circuit/digital/home/61/
или http://radiokot.ru/forum/viewtopic.php?f=20&t=21235
Прекрасные материалы для изучения.
Сам использовал их для автомобильных часов, заработало с 1/2 пинка.

Удачи.
Реклама
Drozdov
Родился
Сообщения: 5
Зарегистрирован: Вс июн 12, 2011 21:19:04

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Drozdov »

metan писал(а):Здравствуйте!
Рассмотрим следующую экзотическую конструкцию:

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

while (1)
      {    
      #asm("cli")
      // Place your code here
      disp_1=ds18b20_temperature(0);
      #asm("sei")    
      };
Лично мне не совсем понятно, какая небесная сила позволит нормально работать прерыванию по таймеру, если прерывания разрешены только несколько процессорных тактов?
Разрешаем прерывания, и тут же их запрещаем..
Насколько я в курсе, cli и sei в цикле нужно убить, т.к. в функциях библиотеки ds18b20 они встроены и обрамляют только необходимый кусочек кода.
Это раз.
Во вторых, первое считывание может дать мусор.
Ну и на десерт, непрерывный опрос датчиков может привести к их разогреву.

Рекомендация - ознакомиться с трудами уважаемого автора Danko,
например http://radiokot.ru/circuit/digital/home/61/
или http://radiokot.ru/forum/viewtopic.php?f=20&t=21235
Прекрасные материалы для изучения.
Сам использовал их для автомобильных часов, заработало с 1/2 пинка.

Удачи.
тем не менее показания на индикаторы в прерывании выводятся нормально, а вот с датчиков ничего не снимается

----
на ответ про общий анод или общий катод, если просто выводить цифры, то все ОК
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение ChipKiller »

......а вот с датчиков ничего не снимается
... разумеется, так и должно быть

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

disp_1=ds18b20_temperature(0);
из библиотеки CV AVR нормально работает только при запрещенных прерываниях. На форуме эта тема затерта до дыр......
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение O-LED »

ChipKiller я правил библиотеку по работе с дс18б20 и запускал вообще без запрета прерываний внутри библиотеки. при этом в устройстве была динамическая индикация по прерыванию. так вот количество неверных чтений было не больше 50%. так что собака зарыта гдето еще.
Drozdov так что на индикаторе выводится? 8888?
KIT
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение ChipKiller »

O-LED писал(а):... я правил библиотеку по работе с дс18б20 и запускал вообще без запрета прерываний
я не правил - своя пишется за 20 минут и остается побольше места во Flash
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение O-LED »

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

А вообще странный синдром. Если просто число выводится корректно, то даже при некорректном чтении датчика, на индикаторы выводилось бы 85, или еще какая чушь(в зависимости от библиотеки), а у человека просто тупо горят все сегменты...... :dont_know: что больше похоже на неправильное подключение индикаторов, ключей и т.д.
KIT
Аватара пользователя
Danko
Сверлит текстолит когтями
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай
Контактная информация:

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Danko »

И опять 25.

И еще один программист который не открывает и не читает хидеры к библиотекам.

Drozdov, значение какого типа возвращает ds18b20_temperature() ?
и какого типа типа у вас переменная disp_1 ?

Наберетесь опыта вот тогда и играйтесь с автоматическим приведением типов, а пока берите в руки книгу и читайте.
как должен быть на строен порт МК к которому подключена шина 1-wire ?
Не хочу отвечать на вопрос вопросом, но если шина двунаправленная и МК, то принимает информацию через этот порт, то передает, ну и как нужно настраивать порт ?
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Drozdov
Родился
Сообщения: 5
Зарегистрирован: Вс июн 12, 2011 21:19:04

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение Drozdov »

Drozdov, значение какого типа возвращает ds18b20_temperature() ?
и какого типа типа у вас переменная disp_1 ?


float выводит, disp_1 как инт, во время другого тестирования я делал преобразования из флоата в инт, не помогло, но попробую еще раз...

Наберетесь опыта вот тогда и играйтесь с автоматическим приведением типов, а пока берите в руки книгу и читайте.
Теория без практики мертва)

Не хочу отвечать на вопрос вопросом, но если шина двунаправленная и МК, то принимает информацию через этот порт, то передает, ну и как нужно настраивать порт ?

спасибо за заметку, уже понял это ) в библиотеке прописано, когда на вход, а когда на выход)

А вообще странный синдром. Если просто число выводится корректно, то даже при некорректном чтении датчика, на индикаторы выводилось бы 85, или еще какая чушь(в зависимости от библиотеки), а у человека просто тупо горят все сегменты...... что больше похоже на неправильное подключение индикаторов, ключей и т.д.

если б неправиьно были подключены индикаторы, тест на 1234 и на простой count-инг не проходил бы?
перепроверю все еще раз, а то когда начинаешь бороться с конкретной проблемой - иногда теряется виденье всей картины

Drozdov так что на индикаторе выводится? 8888?
да...
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: Atmega8 + DS18b20 + Led = 8888 , помогите(((

Сообщение O-LED »

Drozdov так что на индикаторе выводится? 8888?
да...
и точки может все светятся??? :shock:
бред какойто......
т.е. если написать

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

disp_1=1234;
то выводится "1234" , а если написать

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

disp_1=ds18b20_temperature(0);
на индикаторе "8888" ??? Так быть не должно даже если вы перепутсете все что возможно, и типы всех переменных, и нерабочую библиотеку....... Попробуйте ради прикола так -

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

disp_1=ds18b20_temperature(0) + 1;
и если не выведется 8889 тогда :dont_know:
KIT
Закрыто

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