Страница 1 из 4

Преобразование числа в строку и обратно (DS18B20 + 7 сегм.)

Добавлено: Сб май 30, 2009 16:57:00
mr_smit
Значит так: ATMega8, DS18B20, двойной 7-ми сегм. индикатор.

Что надо: показывать целую часть температуры.

Один индикатор повесил на порт В, второй на порт D. Хочу измерить температуру ds18b20_temperature(0). Получим число (например 20 т.е 20 градусов). Число перевести в строку. Взять первое значение (2) перевести обратно в число и отобразить на 7 сегм. индик. Потом взять второе число (0) и т.д.
Никак не могу разобраться. Перерыл уже все примеры на Си - ни один не работает.

Что делаю (CVAVR):

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


...........

int temp;
char temp_str;

char Indicator_1 [10] = {      // массив для отображения на индикаторе

0b01111110,    // 0
0b00001100,    // 1
0b10110110,    // 2
0b10011110,    // 3
0b11001100,    // 4
0b11011010,    // 5
0b11111010,    // 6
0b00001110,    // 7
0b11111110,    // 8
0b11011110,    // 9
};

char Indicator_2 [10] = {      // массив для отображения на индикаторе

0b01111110,    // 0
0b00001100,    // 1
0b10110110,    // 2
0b10011110,    // 3
0b11001100,    // 4
0b11011010,    // 5
0b11111010,    // 6
0b00001110,    // 7
0b11111110,    // 8
0b11011110,    // 9
};

...

w1_init();

ds18b20_init(0,-30,120,0);

.........

while (1)
      {
      temp=ds18b20_temperature(0);

      //itoa(temp, temp_str);
      itoa(temp,temp_str,10);
      
      //PORTB=Indicator_1 [2];
      //PORTD=Indicator_2 [5];
      
      };
Пробовал так
char *temp_str = new char[17]; - не знает что такое new

Посмотрел библиотеку DS18B20 - там у функции ds18b20_temperature тип float. Посмотрел справку CVAVR - там есть ftoa - что с ней только не делал, безполезно.

Что ещё сделать не знаю. Поэтому обращаюсь к мудрейшим. :cry:

Добавлено: Сб май 30, 2009 18:00:36
Pippeytz
Вот, можеш посомтреть , только здесь 4х разрядный индикатор , поудаляеш индикацию на другие два разряда если разберешся

Никаких преобразований тут делать не нужно, за тебя все ето здеално в библиотеках , просто нужна перменная типа int
куда ты сохраниш результат
temp=ds18b20_temperature(0);
после етой команды все будет в temp уже в реальном виде
float- обычное число с палвяющей запятой

Добавлено: Сб май 30, 2009 18:21:51
mr_smit
Pippeytz писал(а): нужна перменная типа int куда ты сохраниш результат
temp=ds18b20_temperature(0);
после етой команды все будет в temp уже в реальном виде
float- обычное число с палвяющей запятой
Это я понимаю. Не понимаю как вывести результат на индикатор. Сейчас посмотрю твой пример.

P.S. А ds18b20_temperature(0) в каком виде возвращает значение?

Добавлено: Вс май 31, 2009 20:59:23
mr_smit
Хочу вывести 2-х значное число на 2-х значный индикатор. Есть KingBright DA04-11SRWA. Но для начала хочу попробовать в Proteus. Индикатор с общим анодом.

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

flash char digits [] = {      // массив для отображения на индикаторе
0b10000001,    // 0
0b11110011,    // 1
0b01001001,    // 2
0b01100001,    // 3
0b00110011,    // 4
0b00100101,    // 5
0b00000101,    // 6
0b11110001,    // 7
0b00000001,    // 8
0b00100001,    // 9
};
char digit_out[2], cur_dig=0;     //переменные для работы с LED
unsigned int indicator=23;        //переменная для вывода
void cifri_v_massiv (void) {           // функция для перекодировки
  digit_out[0]=indicator%10;           // Делим на 10 остаток в масив, 1-разряд  (справа налево)
  digit_out[1]=indicator/10;           // 2 разряд                      
} 
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  cifri_v_massiv ();
  switch (cur_dig){
  case 0:{PORTC.2=1; PORTC.1=0; break;};  //подаём питание на разряд 0 (справа налево)
  case 1:{PORTC.1=1; PORTC.2=0; break;};  //подаём питание на разряд 1 (справа налево)
  }
  PORTD=digits[digit_out[cur_dig]];    
  cur_dig++;                                           
  if(cur_dig==2) {cur_dig=0;}                 
}
Получается какая то абракабабра. Целый день сегодня бьюсь. Никак не выходит.

Изображение

Всё в архиве:

Добавлено: Вс май 31, 2009 21:40:01
mr_smit
Почему то если меняю частоту TCCR0=0x05 на TCCR0=0x03 и т.д. "абракабабра" тоже меняется. Иногда вовсе пропадает. Я совсем запутался...

Добавлено: Вс май 31, 2009 21:45:08
Pippeytz
Попробуй таймер завести так TCCR0=0x02; TCNT0=0x00;
И еще вот так поробуй...

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



#include <mega8>
#include <stdlib>


flash char digits [] = {      // массив для отображения на индикаторе

0b10000001,    // 0
0b11110011,    // 1
0b01001001,    // 2
0b01100001,    // 3
0b00110011,    // 4
0b00100101,    // 5
0b00000101,    // 6
0b11110001,    // 7
0b00000001,    // 8
0b00100001,    // 9
};

char digit_out[2], cur_dig=0;   
unsigned int indicator=0;        

void cifri_v_massiv (void) {           
  digit_out[0]=indicator%10;         
  digit_out[1]=indicator/10;                            
} 


interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
    PORTC=0x00;
    PORTD=digits[digit_out[cur_dig]];
  switch (cur_dig){
  case 0:{PORTC.2=1;  break;};  
  case 1:{PORTC.1=1;  break;};  
  }
  
  cur_dig++;                                           
  if(cur_dig==2) {cur_dig=0;}                 
}

void main(void)
{

PORTC=0x00;
DDRC=0x00;


PORTD=0xFF;
DDRD=0xFF;

             
TCCR0=0x02;
TCNT0=0x00;
TIMSK=0x41;


#asm("sei")

while (1)
      {  
        indicator=12;
        cifri_v_massiv ();
     
      };
}


[code/]

Добавлено: Пн июн 01, 2009 08:22:44
Fallk
Êàê ÿ ïîíÿë çàäà÷à áàíàëüíàÿ - èìåþùååñÿ ñëîæíîå ÷èñëî íóæíî ðàçáèòü íà ñîñòàâëÿþùèå?
Íàïðèìåð ÷èñëî 247 ðàçëîæèòü íà ÷èñëà 2, 4 è 7 ÷òîáû êàæäîå èç íèõ çàïèñàòü â ñîîòâåòñòâóþùåì 7-ìè ñåãìåíòíîì èíäèêàòîðå?

Добавлено: Пн июн 01, 2009 13:35:33
Alex Medvedev
Я замучался в свое время с этим.
Исходник прилагается. Все работает но вот тока индикаторов не два а четыре..
Изображение

Добавлено: Пн июн 01, 2009 19:04:33
mr_smit
Fallk - да.

Сделал так, заработало.

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

interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  indicator=23;
  cifri_v_massiv ();

  PORTC=0x00;     //   < -- добавил

  if (cur_dig==0) {PORTC.2=1; PORTC.1=0;}
  else {PORTC.1=1; PORTC.2=0;}
  PORTD=digits[digit_out[cur_dig]];
  cur_dig++;                                           
  if(cur_dig==2) {cur_dig=0;}                 
}
Частота 1 МГц (от внутреннего RC). Главное интересно, если поставить TCCR0=0x01, то получим:
Изображение

А если поставить TCCR0=0x02, то:
Изображение

Почему?

Добавлено: Пн июн 01, 2009 21:06:23
dosikus
Советую посмотреть граф индикации.
А то нарветесь на неприятные приколы типа этого :
http://www.kaligraf.narod.ru/nedodellki.html

Добавлено: Вт июн 02, 2009 07:39:51
Fallk
[quote="mr_smit"]Fallk - äà.

Îðãàíèçîâûâàåì 2 öèêëà äëÿ 3õ çíà÷íîãî ÷èñëà è íà÷èíàåì îòíèìàòü ñíà÷àëà 100, ïîòîì 10 è ñ÷èòàÿ êîëëè÷åñòâî îïåðàöèé.  ðåçóëüòàòå áóäåò ïîëó÷àòüñÿ îòâåò, åñëè îí áóäåò ìåíüøå íóëÿ, çíà÷èò îñòàòîê ìåíüøå 100, ïåðåõîäèì ñ îñòàòêîì â öèêë ãäå îòíèìàåòñÿ 10.  íåì òàê æå ñ÷èòàåòñÿ êîëëè÷åñòâî îïåðàöèé è ïîëó÷åííûé îòâåò ìåíüøå 10 áóäåò òðåòèì ÷èñëîì.  èòîãå ïîëó÷àåòñÿ 367=3*100+6*10+7
Ïîëó÷åííûå ÷èñëà 3,6,7 çàïèñûâàåì â îòäåëüíûå ðåãèñòðû ïàìÿòè. Èòîãî èìååì 3 ÿ÷åéêè ïàìÿòè ñ òðåìÿ ïðîñòûìè ÷èñëàìè.
Ïî êðàéíåé ìåðå ÿ òàê äåëàþ íà àñåìáëåðå äëÿ PICa

Добавлено: Вт июн 02, 2009 09:25:45
ARV
ну сколько можно эту жвачку жевать?! :evil: каждый, кто берет в руки МК и 7-сегментые индикаторы тут же начинает задавать вопрос о выводе на него чисел!!! неужели поиском нельзя попользоваться?! просто тошнит от этого!!!

человек, который хоть что-то смыслит в программировании, просто не может не знать основ арифметики!!! зачатки систем счисления так же нынче изучают в школе на информатике... неужели нельзя чуть-чуть подумать?! на крайний случай, просто 5-10 минут порыться в форуме - ну куча советов!!!

в конце концов, это просто надоедает :evil:

Добавлено: Вт июн 02, 2009 17:46:05
mr_smit
ARV писал(а):ну сколько можно эту жвачку жевать?! :evil: каждый, кто берет в руки МК и 7-сегментые индикаторы тут же начинает задавать вопрос о выводе на него чисел!!! неужели поиском нельзя попользоваться?! просто тошнит от этого!!!

человек, который хоть что-то смыслит в программировании, просто не может не знать основ арифметики!!! зачатки систем счисления так же нынче изучают в школе на информатике... неужели нельзя чуть-чуть подумать?! на крайний случай, просто 5-10 минут порыться в форуме - ну куча советов!!!

в конце концов, это просто надоедает :evil:
Ага, везде только и слышишь: "Ищите, ищите, 100 раз обсуждалось". Толком никто ничего не говорит, даже если знает.

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

Чуть выше вопрос задал: Почему сектор "е" на индикаторе при изменении частоты засвечивается? Он же даже не участвует в отображении цифры "3".

Добавлено: Вт июн 02, 2009 17:48:51
ibiza11
а я с ARV согласен. зачем поднимать еще одну новую тему, если этот вопрос уже обсуждался, даже тема была такая(!!!!) если кому то лень посидеть немного с поиском...

Добавлено: Вт июн 02, 2009 18:04:45
mr_smit

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

temp=ds18b20_temperature(0);
что в temp будет? В каком виде? Ну там 21,5 или 215 или 21,500

потому что:

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

while (1)
      {
      //temp=ds18b20_temperature(0);
      indicator=25.6;
      cifri_v_massiv ();
      };
}
На индикатор выводится 25. А если так:

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

while (1)
      {
      temp=ds18b20_temperature(0);
      indicator=temp;
      cifri_v_massiv ();
      };
}
На индикатор выводится 1. Хотя температура выставлена 27 (Proteus).

Добавлено: Вт июн 02, 2009 19:08:21
dosikus
mr_smit писал(а): Чуть выше вопрос задал: Почему сектор "е" на индикаторе при изменении частоты засвечивается? Он же даже не участвует в отображении цифры "3".
Я же тебе ответил ссылкой... :)))

Добавлено: Вт июн 02, 2009 19:20:55
mr_smit
dosikus писал(а):
mr_smit писал(а): Чуть выше вопрос задал: Почему сектор "е" на индикаторе при изменении частоты засвечивается? Он же даже не участвует в отображении цифры "3".
Я же тебе ответил ссылкой... :)))
Причина в том, что при переключении разрядов в программе динамической индикации(переключение идёт слева направо) транзистор разряда, выводимого на индикацию не успевал закрываться. Часть времени(несколько микросекунд) цифра следующего разряда отображалась в разряде предыдущем.
Транзисторов здесь нет. Загораются строго определенные числа. То есть 3, 3, 3, 3, 3 .... почему "е" засвечивается всё равно не понимаю.

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

indicator=25.6;
и TCCR0=0x01; - на индикаторе вообще 88. Я так понимаю что просто слишком быстро смена происходит. Ладно, будем считать что разобрались. С температурой что?

Добавлено: Вт июн 02, 2009 20:01:39
dosikus
Не мне это положительно нравится ...
Ты читаешь не больше двух слов на странице ? Или так спешишь что них.. не видишь ?
Причем здесь транзисторы ?! Засветка и без транзисторов обеспечена тебе...

Добавлено: Вт июн 02, 2009 20:44:59
ARV
мне лень все читать...
1. перед тем, как вывести НОВЫЙ символ на НОВЫЙ разряд индикатора, надо ПОГАСИТЬ текущий индикатор. я всегда гашу ВСЕ индикаторы (вывожу 1 на общие катоды или 0 на андоы).
2. почитайте статью- возможно, вопросы пропадут... а ясность появится...

Добавлено: Ср июн 03, 2009 06:38:59
mr_smit
Всё разобрался. Спасибо.

Про температуру ещё скажите что нибудь. В каком виде возвращает?