реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> DS18B20, 7 сегментный индикатор и Atmega8
trivet
сообщение Feb 2 2011, 16:12
Сообщение #1





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



Объясните пожалуйста, я новичек и если что извиняйте за тупой вопрос.
У меня датчик техразрядный индикатор(использую 2 из разрадов). Написал прогу в CodeVisionAVR, все работает. Но прикол в том что иногда(часто но никакой закономерности) заместо значений выводится "88".
CODE

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

// 1 Wire Bus interface functions

#include <1wire.h>

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

//#asm //сообщаем куда подключён экран
// .equ __lcd_port=0x18
//#endasm
//#include <lcd.h>

#define A PORTB.6
#define B PORTB.2
#define C PORTB.0
#define D PORTD.6
#define E PORTD.5
#define F PORTB.7
#define G PORTB.1
#define H PORTD.7

#define D1 PORTB.5
#define D2 PORTB.4
#define D3 PORTB.3
#define D4 PORTC.1

#define MAX_DS18b20 8
unsigned char ds18b20_devices;
unsigned char ds18b20_rom_codes[MAX_DS18b20][9];

float temper;
int temper_int,temper_fl,min=0,temp[2],i;

flash int digits[11][8] = {{0,0,1,1,1,1,1,1}, //0
{0,0,0,0,0,1,1,0}, //1
{0,1,0,1,1,0,1,1}, //2
{0,1,0,0,1,1,1,1}, //3
{0,1,1,0,0,1,1,0}, //4
{0,1,1,0,1,1,0,1}, //5
{0,1,1,1,1,1,0,1}, //6
{0,0,0,0,0,1,1,1}, //7
{0,1,1,1,1,1,1,1}, //8
{0,1,1,0,1,1,1,1}, //9
{0,0,0,0,0,0,0,0}}; //пусто

interrupt [TIM1_OVF] void timer2_ovf_isr(void)
{
switch(i)
{
case 0:D3=1;
D1=0;
break;
case 1:D1=1;
D2=0;
break;
case 2:D2=1;
D3=0;
break;
};
if(i>0)
{
A=digits[temp[i-1]][7];
B=digits[temp[i-1]][6];
C=digits[temp[i-1]][5];
D=digits[temp[i-1]][4];
E=digits[temp[i-1]][3];
F=digits[temp[i-1]][2];
G=digits[temp[i-1]][1];
}
else
{
A=digits[10][7];
B=digits[10][6];
C=digits[10][5];
D=digits[10][4];
E=digits[10][3];
F=digits[10][2];
G=digits[10][1];
}

i++;
if(i==3) i=0;
TCNT1H=0xEC;
TCNT1L=0x77;
}

void temperature(void) // функция по работе с термо-датчиком
{
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
temper_int=temper; // отбор целой части от температуры
if(temper<0) // при отрицательной температуре
{
temper_fl=(temper-temper_int-0.0625)*10; // дробная часть
temper_int=-((temper_int*10)+temper_fl); // температура*10
min=1; // минус
}
else // при положительной
{
temper_fl=(temper-temper_int)*10; // дробная часть
temper_int=(temper_int*10)+temper_fl;// температура*10
min=0; // плюс
}
}

void main(void)
{
PORTB=0x00;
DDRB=0xFF;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0xFF;

TCCR0=0x02;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0xEC;
TCNT1L=0x77;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x04;
UCSRB=0x00;
ACSR=0x80;
SFIOR=0x00;
SREG|=(1<<7);
ADCSRA=0x00;
SPCR=0x00;
TWCR=0x00;

w1_init();
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
ds18b20_init(0,-35,35,DS18B20_12BIT_RES);

while (1)
{
temperature();
temp[0]=temper_int/100;
temp[1]=(temper_int-temp[0]*100)/10;
}
}


Вот проект CodeVisionAVR и Proteus

Сообщение отредактировал IgorKossak - Feb 2 2011, 18:06
Причина редактирования: Читайте в правилах об оформлении кода

Эскизы прикрепленных изображений
Прикрепленное изображение
 

Прикрепленные файлы
Прикрепленный файл  proga.rar ( 150.05 килобайт ) Кол-во скачиваний: 31
 
Go to the top of the page
 
+Quote Post
Stepan_L
сообщение Feb 3 2011, 05:56
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 26-08-08
Из: Ереван
Пользователь №: 39 828



причем тут "lcd.h"
посмотри в "examples\DS18B20"
"88"это по моему пр.от таймера мешает DS.Во время чтение температуры (ds18b20_temperature)надо блокировать timer.


--------------------
ARM_enia
Go to the top of the page
 
+Quote Post
trivet
сообщение Feb 3 2011, 07:55
Сообщение #3





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



lcd.h здесь непричем, я его сейчас не использую.
а как таймер может помешать? Я пробовал делать проверку если приходит непонятное значение от датчика или вообще если приходят восьмерки на вывод их не выводить. Но все равно это происходит. Такое впечатление что чтото выводит на порты используемые для вывода непонятно что.
И если это таймер ко как его именно в это время отключить?

Сообщение отредактировал trivet - Feb 3 2011, 07:57
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 3 2011, 08:30
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(trivet @ Feb 3 2011, 10:55) *
И если это таймер ко как его именно в это время отключить?
Чтобы проверить, что обмену с DS18B20 мешает таймер, попробуйте перед вызовом функции ds18b20_temperature(...) запретить прерывания (сбросить флаг I в SREG), а после её работы разрешить вновь.
Go to the top of the page
 
+Quote Post
GDI
сообщение Feb 3 2011, 08:37
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата(Stepan_L @ Feb 3 2011, 08:56) *
Во время чтение температуры (ds18b20_temperature)надо блокировать timer.
Тут надо определить что главнее индикация или чтение температуры, по моему индикация главнее, к тому же температура читается неоправданно часто. При 12бит разрешении что устанавливается для датчика температуры, он преобразование температуры делает 750мс. Температуру надо читать не чаще этого времени, я в свое время читал температуру раз в секунду, правда библиотеку от CodeVision-а пришлось заменить самопальной и там уже был полный контроль над процессом считывания температуры, в нужных местах стояли запреты прерываний, потому никакие другие прерывания, а их в системе было много, не мешали.



--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
trivet
сообщение Feb 3 2011, 08:48
Сообщение #6





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



У меня таймер для вывода на индикатор чтоб он не тух во время опроса датчика. я начал возится с таймером только из-за этого. А если я буду запрещать прерывание во время опроса датчика я вернусь к морганию. Я пробовал считывать реже тот же эффект.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 3 2011, 08:53
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Попробуйте переименовать переменную i во что-нибудь похитрее, например, current_digit.
И ещё (это не связано с ошибкой, но на всякий случай) - перед сменой знакоместа сначала гасите все сегменты.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Feb 3 2011, 09:00
Сообщение #8


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(GDI @ Feb 3 2011, 11:37) *
...в нужных местах стояли запреты прерываний, потому никакие другие прерывания, ... не мешали.


если присмотреться к протоколу 1Wire повнимательней, то критичные участки только между стробом на считывание и самим считыванием. посему _всё_ смело выноситься в прерывание и отлично работает с прерываниями от других устройств, полностью асинхронно. тактовая правда должна быть завышена. как пример: работал на 14 и 16 МГц - протаскивает на ура.


удачи вам
(круглый)
Go to the top of the page
 
+Quote Post
trivet
сообщение Feb 3 2011, 09:17
Сообщение #9





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



Я пробовал проверять если приходит непонятное значение или вообще восьмерки на вывод их не выводить а оставлять предыдущее значение. Тот же эффект
Go to the top of the page
 
+Quote Post
GDI
сообщение Feb 3 2011, 09:26
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Так может у вас тупо контроллер сбрасывается от собаки или от переполнения стека? И еще, датчик в первый раз после включения всегда отдает температуру 85, если мне память не изменяет, проверьте в даташите, может у Вас именно это значение выводится? Если это так, тогда, есть вариант что у Вас плохой контакт питания на датчике. И еще уточню - 88 выводится в железе или в Протеусе, или и там, и там?


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
trivet
сообщение Feb 3 2011, 10:35
Сообщение #11





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



"88" выводится и в железе и в протеусе. пробовал вообще не выводить восьмерки, но результат тот же!
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 3 2011, 10:44
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(trivet @ Feb 3 2011, 13:35) *
"88" выводится и в железе и в протеусе. пробовал вообще не выводить восьмерки, но результат тот же!

О чем вообще можно говорить, если Вы до сих пор не пользовались Debug/Configure diagnostics в протеусе, битый час парите мозг окружающим, вместо того, чтобы проверить, понимайт даллас все посланные ему команды или нет, срабатывает собака или нет, есть переполнение стека или нет, итд итп
Go to the top of the page
 
+Quote Post
GDI
сообщение Feb 3 2011, 13:14
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Да, к программе слишком много вопросов:
1. Почему переменная i не имеет начального значения?
2. Зачем она int, да еще и со знаком?
3. Зачем float temper, тут вообще не нужно вычислений с плавучкой, они просто не нужны.
4. Почему массив digits интовый? вполне можно сделать чар, а может даже и BOOL.
5. С какой частотой работает таймер?
6. Зачем так часто опрашивать температуру?
7. почему в свиче в прерывании меняются только 2 линии порта из 3х?
8. Если сделать пустой цикл while(1), т.е. не опрашивать температуру вообще, что будет выводиться на индикатор?


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
trivet
сообщение Feb 3 2011, 13:56
Сообщение #14





Группа: Новичок
Сообщений: 7
Регистрация: 12-05-05
Пользователь №: 4 963



Спасибо всем. Все заработало после того как я решил не подстраиваться под чужую схему а на макетке собрал свою где все сегменты индикатора висят на одном порту. И все теперь работает. Там наверно где то во время моего разложение на биты клинило.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01481 секунд с 7
ELECTRONIX ©2004-2016