простые и интересные  РАДИОСХЕМЫ сделанные своими руками

» Гость

Мы рады вас видеть. Пожалуйста зарегистрируйтесь или авторизуйтесь!



» ДАТАШИТЫ
Например: TDA1562

» СХЕМЫ


Отметить прочитанными   -   Поиск   -   Правила   -   Новые сообщения

Страница 2 из 5«12345»
Модератор форума: Электродыч, Витинари, Sam 
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Помогите с направлением (программирование микросхем)
Помогите с направлением (программирование микросхем)
Сб, 09.01.2016, 02:16 | Сообщение # 11        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
Всем привет!!! не нашёл более подходящей темы, если что сильно не пинайте :)
Задача следующая: пытаюсь писать программу в КодевижнАВР. Необходимо подключить несколько датчиков DS18B20 к Atmega8 и вывести показания на LCD экран.
Вот кусок кода:

// Determine the number of DS1820 devices
// connected to the 1 Wire bus
ds18b20_devices = w1_search(0xf0,ds18b20_rom_codes); //Запуск функции поиска 1wire устройств
// и запись их количества в переменную ds18b20_devices.

ds18b20_init( &ds18b20_rom_codes[0][0], -55, 125, DS18B20_9BIT_RES );
ds18b20_init( &ds18b20_rom_codes[1][0], -55, 125, DS18B20_9BIT_RES );
ds18b20_init( &ds18b20_rom_codes[2][0], -55, 125, DS18B20_9BIT_RES );
ds18b20_init( &ds18b20_rom_codes[3][0], -55, 125, DS18B20_9BIT_RES );

lcd_init(16);

ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x81;

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

while (1)
{
sprintf( lcd_buf,"Y %.0f\xdf ", ds18b20_temperature(&ds18b20_rom_codes[0][0]) );
lcd_gotoxy(0,0);
lcd_puts( lcd_buf );
sprintf( lcd_buf,"C %2d\xdf ", ds18b20_temperature(&ds18b20_rom_codes[1][0]) );
lcd_gotoxy(0,1);
lcd_puts( lcd_buf );
sprintf( lcd_buf,"D %.0f\xdf", ds18b20_temperature(&ds18b20_rom_codes[2][0]) );
lcd_gotoxy(6,0);
lcd_puts( lcd_buf );
sprintf( lcd_buf,"O %2d\xdf ", ds18b20_temperature(&ds18b20_rom_codes[3][0]) );
lcd_gotoxy(6,1);
lcd_puts( lcd_buf );

sprintf(lcd_buf,"%2d\xdf",x); // выводим заданную температуру
lcd_gotoxy(12,1);
lcd_puts(lcd_buf);

u=read_adc(6)/51; /* вызываем функцию для измерения напряжения и передаем ей
номер ножки, на которой нужно измерить напряжение */
lcd_gotoxy(11,0); // перевод курсор в положение x=0 y=0
sprintf(lcd_buf,"%2dv",u); // формируем строку для вывода
lcd_puts(lcd_buf);


};

Проблема заключается в том, что всё работает нормально если в настройках проекта (s)printf Features указано "float",

но при таких настройках программа занимает очень много памяти. А так как мне показания температуры не нужны с большой точностью (хватит то градуса), то по идее для экономии памяти можно в настройках поставить "int", но вся беда в том, что в таком случае температура на отображается, т.е. выводит 0.
Сб, 09.01.2016, 02:25 | Сообщение # 12        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
вот что у меня получается:

Добавлено (09.01.2016, 02:25)
---------------------------------------------
спецификацию преобразования специально оставил %.0f и %2d чтобы было видно разницу...
Вопрос что мне необходимо сделать чтобы данные отображались корректно?

Сб, 09.01.2016, 02:28 | Сообщение # 13        
Витинари
аватар
  Постов: 2479  Offline Модератор 
Тёмыч, надо, видимо, рыться в либе на 18b20, там float установлен как тип данных для выводимого результата. Было бы на пиках, скинул бы измененную библиотеку на только целые градусы.
Сб, 09.01.2016, 02:36 | Сообщение # 14        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
Вот что показывает если код тот же, но в настройках "float":

Добавлено (09.01.2016, 02:33)
---------------------------------------------
Вот собственно либа:
#include <delay.h>
#include <ds18b20.h>

struct __ds18b20_scratch_pad_struct __ds18b20_scratch_pad;

// temp. conversion time [ms] depending on the resolution
static flash int conv_delay[4]={100,200,400,800};
// valid temp. bit mask depending on the resolution
static flash unsigned bit_mask[4]={0xFFF8,0xFFFC,0xFFFE,0xFFFF};

unsigned char ds18b20_select(unsigned char *addr)
{
unsigned char i;
if (w1_init()==0) return 0;
if (addr)
{
w1_write(0x55);
i=0;
do
w1_write(*(addr++));
while (++i<8);
}
else w1_write(0xcc);
return 1;
}

unsigned char ds18b20_read_spd(unsigned char *addr)
{
unsigned char i;
unsigned char *p;
if (ds18b20_select(addr)==0) return 0;
w1_write(0xbe);
i=0;
p=(char *) &__ds18b20_scratch_pad;
do
*(p++)=w1_read();
while (++i<9);
return !w1_dow_crc8(&__ds18b20_scratch_pad,9);
}

float ds18b20_temperature(unsigned char *addr)
{
unsigned char resolution;
if (ds18b20_read_spd(addr)==0) return 00;
resolution=(__ds18b20_scratch_pad.conf_register>>5) & 3;
if (ds18b20_select(addr)==0) return 00;
w1_write(0x44);
delay_ms(conv_delay[resolution]);
if (ds18b20_read_spd(addr)==0) return 00;
w1_init();
return (*((int *) &__ds18b20_scratch_pad.temp_lsb) & ((int) bit_mask[resolution]))*0.0625;
}

unsigned char ds18b20_init(unsigned char *addr,signed char temp_low,signed char temp_high,
unsigned char resolution)
{
if (ds18b20_select(addr)==0) return 0;
resolution=(resolution<<5) | 0x1f;
w1_write(0x4e);
w1_write(temp_high);
w1_write(temp_low);
w1_write(resolution);
if (ds18b20_read_spd(addr)==0) return 0;
if ((__ds18b20_scratch_pad.temp_low!=temp_low) ||
(__ds18b20_scratch_pad.temp_high!=temp_high) ||
(__ds18b20_scratch_pad.conf_register!=resolution)) return 0;
if (ds18b20_select(addr)==0) return 0;
w1_write(0x48);
delay_ms(15);
return w1_init();
}

Добавлено (09.01.2016, 02:34)
---------------------------------------------
Красным выделил float, пытался его заменить на int, компилятор ругается...

Добавлено (09.01.2016, 02:36)
---------------------------------------------
Я ещё совсем чайник в этих делах, если не трудно ткните носом что мне сделать.

Сб, 09.01.2016, 10:03 | Сообщение # 15        
Витинари
аватар
  Постов: 2479  Offline Модератор 
Тёмыч, дай-ка код из файла "ds18b20.h". По ходу, эти данные с плавающей точкой где-то там определены.
Сб, 09.01.2016, 10:50 | Сообщение # 16        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
Витинари, вот он "ds18b20.h":

/*
CodeVisionAVR C Compiler
© 1998-2009 Pavel Haiduc, HP InfoTech S.R.L.

Prototypes for Dallas Semiconductor
DS18B20 1 Wire bus temperature sensor
functions

BEFORE #include -ING THIS FILE YOU
MUST DECLARE THE I/O ADDRESS OF THE
DATA REGISTER OF THE PORT AT WHICH
THE 1 WIRE BUS IS CONNECTED AND
THE DATA BIT USED

EXAMPLE FOR PORTB:

#asm
.equ __w1_port=0x18
.equ __w1_bit=3
#endasm
#include <ds18b20.h>
*/

#ifndef _DS18B20_INCLUDED_
#define _DS18B20_INCLUDED_

#include <1wire.h>

#define DS18B20_9BIT_RES 0 // 9 bit thermometer resolution
#define DS18B20_10BIT_RES 1 // 10 bit thermometer resolution
#define DS18B20_11BIT_RES 2 // 11 bit thermometer resolution
#define DS18B20_12BIT_RES 3 // 12 bit thermometer resolution

#define DS18B20_FAMILY_CODE 0x28
#define DS18B20_SEARCH_ROM_CMD 0xf0
#define DS18B20_ALARM_SEARCH_CMD 0xec

#pragma used+
extern struct __ds18b20_scratch_pad_struct
{
unsigned char temp_lsb,temp_msb;
signed char temp_high,temp_low;
unsigned char conf_register,
res1,
res2,
res3,
crc;
} __ds18b20_scratch_pad;

unsigned char ds18b20_select(unsigned char *addr);
unsigned char ds18b20_read_spd(unsigned char *addr);
float ds18b20_temperature(unsigned char *addr); // наверное эта строчка виновата, так?
unsigned char ds18b20_init(unsigned char *addr,signed char temp_low,signed char temp_high,
unsigned char resolution);
#pragma used-

#pragma library ds18b20.lib

#endif

Добавлено (09.01.2016, 10:49)
---------------------------------------------
Витинари, спасибо за помощь!!! заменил float в лайбе и хидер файлах на int и всё заработало!!!
Сам бы не допёр без твоей помощи. С меня + в репу!

Добавлено (09.01.2016, 10:50)
---------------------------------------------
размер проги похудел на треть или даже чуть больше...



Отредактировал Тёмыч - Сб, 09.01.2016, 10:40
Сб, 09.01.2016, 10:56 | Сообщение # 17        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
Вот как получилось :
Сб, 09.01.2016, 12:23 | Сообщение # 18        
Витинари
аватар
  Постов: 2479  Offline Модератор 
Тёмыч, о, я даже написать не успел biggrin
Размер прошивки уменьшился потому, что тип int в codevisionavr имеет размер в 16 бит (и может принимать значения от -32768 до 32767), а float - 32 бит (от ±1.175e-38 до ±3.402e38).
Сб, 09.01.2016, 14:06 | Сообщение # 19        
Тёмыч
аватар
  Постов: 1158  Offline Друзья 
Витинари, да, в курсе, что у них размер разный, единственное что не допёр сразу, так это то, что и в хидер файле надо было тип поменять. А вот думаю ещё если заменить на "char", у него же размер ещё меньше от -127 до +127 по моему, "градусная мера" должна влезть :)
Сб, 09.01.2016, 14:13 | Сообщение # 20        
nickolay130978
аватар
  Постов: 1784  Offline Друзья 
Емае , здесь программистов куча оказывается smile А можете сделать простейший счетчик оборотов в одну сторону ?? Нужно четыре знака на семисегментниках , управление герконом - геркон клацнул - на табло единица и так далее, и что бы сброс обязательно был.
Форум радиолюбителей » СХЕМЫ » МИКРОСХЕМЫ » Помогите с направлением (программирование микросхем)
Страница 2 из 5«12345»
Поиск:
Кто есть кто на форуме радиолюбителей: Администратор Модераторы Друзья Пользователи
Группа вконтакте Канал ютуб Группа в фэйсбук Мобильная версия © 2010-2016, "Радиосхемы". Все права защищены. Почта