Страница 3 из 4
Добавлено: Пн июн 15, 2009 20:58:04
Goodefine
Еще раз о функции decbin_ds...
Можете ее сделать и так:
Код: Выделить всё
void decbin_ds (unsigned int const* x, unsigned char* buffer)
{
buffer[1]=*x%10;
buffer[0]=*x/10;
}
Т.е. как у вас было, через деление. Но в этом случае она длится около 135мкс, против 80мкс в моем варианте...
Обработчик прерывания у меня длится около 8.25мкс, против вашего с 14.1мкс, и вызывается примерно в 4-е раза реже...
Добавлено: Пн июн 15, 2009 20:59:55
dosikus
mr_smit писал(а):
В каком вашем исходнике??? вы ничего не выкладывали.
Ну так пора к ARV на сайт наведатся , подчерпнешь массу полезного...
Добавлено: Пн июн 15, 2009 21:01:00
ARV
mr_smit писал(а):В каком вашем исходнике??? вы ничего не выкладывали.
читайте внимательнее. если хотите, конечно...
Добавлено: Пн июн 15, 2009 21:01:48
Igor_67
Вот вы, уважаемый
mr_smith, прежде чем обижаться, лучше бы внимательно посты почитали, а еще лучше - заново всю тему! Вам же явно указали ссылку на статью ( там и исходник):
http://radiokot.ru/forum/viewtopic.php?p=231499#231499.
Просто внимательнее читайте и будет вам счастье!
Добавлено: Пн июн 15, 2009 21:11:20
Goodefine
Igor_67 писал(а):
..явно указали ссылку на статью ( там и исходник):
Да далеко и ходить не надо - на пару постов выше его собственный исправленный проект лежит! Но в ответ тишина....
Добавлено: Пн июн 15, 2009 21:17:10
mr_smit
Мужики, я конечно понимаю что вы все хотите показать какие вы умные, но я тоже не дурак. Тут дело не в принципах реализации. Goodefine, зашил в свою мегу твою прошивку. Смотри сам.
На 16 секунде в первом ролике. На 17 и на 36 секунде во втором.
Добавлено: Пн июн 15, 2009 21:33:12
Goodefine
mr_smit писал(а):
...но я тоже не дурак...
Вроде обратного никто не отрицал...
mr_smit писал(а):
Тут дело не в принципах реализации. Goodefine, зашил в свою мегу твою прошивку. Смотри сам.
Ясен пень, в чем тут дело - в неправильном значении температуры, возвращаемой с датчика. Тут либо датчик виноват, либо встроенная библиотека CAVR. Лечится элементарно. Главный цикл:
Код: Выделить всё
for (;;)//---------------------MAIN_LOOP----------------------------------
{
#asm("wdr") //для Протеуса
//получаем температуру
temp=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
//преобразуем значение температуры в строку и ложим в буфер buffer
if((temp>=0)&&(temp<100))decbin_ds(&temp, buffer);
//пауза
delay_ms(100);
} //end MAIN_LOOP----------------------------------------------------
Немного костыли, но должно помочь...
Добавлено: Пн июн 15, 2009 21:43:06
Igor_67
delay_ms(100)
А задержки не маловато?
Добавлено: Пн июн 15, 2009 21:48:39
mr_smit
Добавлено: Пн июн 15, 2009 21:48:55
Goodefine
Еще грабли могут быть с тем, что датчик читается слишком часто, попробуй его привязать к прерыванию таймера - чтобы оно не мешало. Например:
Код: Выделить всё
/*****************************************************
CodeWizardAVR V2.03.4 Standard
Project : DEMO_TERMOMETRE
Date : 14.06.2009
Author : Goodefine
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8>
#include <delay>
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=0
#endasm
#include <1wire> //библиотека для работы с 1Wire
#include <ds18b20> //библиотека для работы с датчиком температуры
#define MAX_DS18B20 8
unsigned char ds18b20_devices;
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];
//-------------------------------------------------------------------------
#define PIN_DIGIT_1 PINC.1
#define PIN_DIGIT_2 PINC.2
#define OUT_DIGIT_1 PORTC.1
#define OUT_DIGIT_2 PORTC.2
#define TIME_DS_READ 30 /*подбираем, так для опроса два раза в сек.*/
#define BUF_SIZE 2
unsigned char buffer[BUF_SIZE]; //буфер для разложения числа
unsigned int temp; //температура
unsigned char fl_ds_read; //флаг разрешения чтения датчика
//-------------------------------------------------------------------------
flash char digits[]={// массив для отображения на индикаторе
0b10000001,0b11110011,0b01001001,0b01100001,0b00110011,0b00100101,
0b00000101,0b11110001,0b00000001,0b00100001};
//-------------------------Функция преобразования числа в строку------------//
void decbin_ds (unsigned int const* x, unsigned char* buffer)
{ //функция не использует операцию деления
unsigned char i;
//PORTC.0=0;
for (i=0; i<BUF_SIZE>=10; i-=10) {buffer[0]++;}
for (i=*x-10*buffer[0]; i>=1; i-=1) {buffer[1]++;}
// PORTC.0=1;
}
//====================//
//-------------------- 0 overflow interrupt service routine------------//
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
//динамическая индикация, выводит поочередно числа из buffer
static unsigned char counter_ds_read;
(counter_ds_read==TIME_DS_READ)? (fl_ds_read=1,counter_ds_read=0):(counter_ds_read++);
(PIN_DIGIT_1)? (OUT_DIGIT_1=0,PORTD=digits[buffer[1]],OUT_DIGIT_2=1):
(OUT_DIGIT_2=0,PORTD=digits[buffer[0]],OUT_DIGIT_1=1);
}
//====================//
void main(void)
{
PORTB=0x00;
DDRB=0xFF;
PORTC=0xFF;
DDRC=0xFF;
PORTD=0x00;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
TCCR0=0x04;
TCNT0=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;
w1_init();
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
ds18b20_init(&ds18b20_rom_codes[0][0],-55,125,DS18B20_9BIT_RES);
// Global enable interrupts
#asm("sei")
for (;;)//---------------------MAIN_LOOP----------------------------------
{
#asm("wdr") //для Протеуса
//получаем температуру (два раза в секунду)
if(fl_ds_read){
temp=ds18b20_temperature(&ds18b20_rom_codes[0][0]);fl_ds_read=0;
//преобразуем значение температуры в строку и ложим в буфер buffer
decbin_ds(&temp, buffer);
//или так, если не поможет (в верху строчку закомментировать)
//if((temp>=0)&&(temp<100))decbin_ds(&temp, buffer);
}
} //end MAIN_LOOP----------------------------------------------------
}
Если не поможет, то сделайте проверку и не парьтесь...
Мля, да что ж за глюк такой с отображением в посте decbin_ds

Добавлено: Пн июн 15, 2009 21:53:53
Goodefine
Igor_67 писал(а):delay_ms(100)
А задержки не маловато?
Вот и я подумал, что мало - сделал вообще без нее, засинхронизировав заодно чтение датчика и прерывание. Но опрос датчика длится около 144мс, потому при динамической индикации, прерывание будет по любому влазить в опрос примерно 10 раз...
Добавлено: Пн июн 15, 2009 21:56:28
Igor_67
Опрос датчика должен производиться как минимум 1 раз в 750мс (по ДШ на DS-ку)
Добавлено: Пн июн 15, 2009 21:58:53
Goodefine
Тогда сделать:
И будет раз в секунду..
Добавлено: Пн июн 15, 2009 21:59:20
mr_smit
Goodefine писал(а):...попробуй его привязать к прерыванию таймера - чтобы оно не мешало...
Лепота...
Igor_67 писал(а):Опрос датчика должен производиться как минимум 1 раз в 750мс (по ДШ на DS-ку)
При 12-ти битном разрешении. А мы выставляем 9:
Код: Выделить всё
ds18b20_init(&ds18b20_rom_codes[0][0],-55,125,DS18B20_9BIT_RES);
Там время гораздо меньше.
Добавлено: Пн июн 15, 2009 22:01:27
Igor_67
Ну какчество видео, конечно, отвратительное!
Добавлено: Пн июн 15, 2009 22:05:28
mr_smit
Ну уж извините, телефон. Можно конечно и вэб камерой снять, но не думаю что гораздо лучше получится. Прошу прощенья.
Добавлено: Пн июн 15, 2009 22:08:50
Goodefine
mr_smit писал(а):
Лепота...
Что-то странное у тебя с датчиком. В симуляторе все работает.. Поставь проверку (в первом варианте)
Код: Выделить всё
if((temp>=0)&&(temp<100))decbin_ds(&temp, buffer);
И(или) delay увеличь...
Добавлено: Пн июн 15, 2009 22:19:48
Goodefine
Попробуй эту прошивку (переименовать в хекс)
Добавлено: Пн июн 15, 2009 22:28:27
mr_smit
Вроде нормально, только цифры дрожат. Делитель думаю надо поменьше. Что сделал?
Добавлено: Пн июн 15, 2009 22:32:18
mr_smit
ОПА!!! Только что глюк был.