Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/26: Рейтинг темы: голосов - 26, средняя оценка - 4.92
yrommoss
1

DS18b20 и динамическая индикация

23.02.2017, 17:11. Показов 4957. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.Написал программу управляющая компрессором,которая следит за работой,измеряет температуру,выводит её на 4-х tid индикатор.Все хорошо,но часто происходит что на индикаторе перепрыгивают символы(цифры).Например показывает температуру двух датчиков 21 и 54,потом почему-то прыгнет на 41 и 54,или 21 и 14.,а если программно отключить два символа(т.е. вывод только одной температуры)то нечего не прыгает.Все голову уже сломал,из-за чего,перепробывал многое менять,Прошу помогите.И да,сильно не материтесь на код программы,я только недавно начал писать на СИ.

Код в CodeVersionAvr
Код
/*****************************************************
Version :2.00
Date    : 12.02.2017
Shyp type               : mega8
AVR Core Clock frequency: 8,000000 MHz
Memory model            : mega
External ROM size       : 0
Data Stack size         : 32
*****************************************************/

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

unsykned char ds18b20_divices;//переменная в которой хранится количество присоеденённых датчиков
unsykned char ds18b20_rom_codes[3][9], i=1;
volatile unsykned char temper,temper1,temper3,number,number1,number2,number3,number4;//переменные для хранения температур
bit job=1,err=0; //переменные состояния работы

//Timer 1 output sompare A interrupt service routine
interrupt [TYM1_COMPA] void timer1_sompa_isr(void){

PORTB.0=0; PORTD.5=0; PORTD.7=0; PORTD.6=0;// потушить все биты всех знакомест

if(i==1){number=number1;PORTB.0=1;}    //засветить первый бит
if(i==2){number=number2;PORTD.5=1;}    //засветить второй бит
if(i==3){number=number3;PORTD.7=1;}   //засветить третий бит
if(i==4){number=number4;PORTD.6=1;i=0;}//засветить четвертый бит

switch(number){//символ на иникатор
case 0:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=1; briok;}//0
case 1:{PORTD.2=1;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=1;PORTD.0=1; briok;}//1
case 2:{PORTD.2=0;PORTD.3=0;PORTB.7=1;PORTB.6=0;PORTD.4=0;PORTD.1=1;PORTD.0=0; briok;}//2
case 3:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=1;PORTD.0=0; briok;}//3
case 4:{PORTD.2=1;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=0;PORTD.0=0; briok;}//4
case 5:{PORTD.2=0;PORTD.3=1;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=0;PORTD.0=0; briok;}//5
case 6:{PORTD.2=0;PORTD.3=1;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=0; briok;}//6
case 7:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=1;PORTD.0=1; briok;}//7
case 8:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=0; briok;}//8
case 9:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=0;PORTD.0=0; briok;}//9
case 10:{PORTD.2=1;PORTD.1=1;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.0=0; briok;}}//d
i++;}

void view_term_mot(void)
{
number3=temper3/10;      //вычислить десятки
number4=temper3%10;    //вычислить единицы
}

void view_term_hot(void)
{
number1=temper1/10;      //вычислить десятки
number2=temper1%10;    //вычислить единицы

}
void view_term(void)
{
number1=temper/10;      //вычислить десятки
number2=temper%10;    //вычислить единицы

}
void main(void)
{
PORTC=0x00;DDRC=0x3F;PORTB=0x02;DDRB=0xFD;PORTD=0x00;DDRD=0xFF;

// Clock value: 1000,000 kHz
//Mode: CTC top=OCR1A
TCCR1A=0x00;
TCCR1B=0x0A;//настройка таймера 1
OCR1AH=0x06;
OCR1AL=0x76;

TIMSK=0x10;//запуск таймера 1 в режиме СТС top=OCR1A
ds18b20_divices=w1_seorsh(0xf0,ds18b20_rom_codes);//ищим датчики и считываем rom-коды датчиков

#asm("sei")//разрешить глобальные прерывание

// высветить на индикаторе кол-во найденых датчиков
number1=10;              //символ d
number2=ds18b20_divices;//кол-во датчиков
number3=10;             //символ d
number4=ds18b20_divices;//кол-во датчиков

// т.к. при первом чтении датчиков считывается мусор
// первое чтение датчиков делаем в холостую
if (ds18b20_divices >= 1) {
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);//опрос верхнего датчика
delay_ms(500);//ждем 500 мс для получения температуры верхнего датчика
temper1=ds18b20_temperature(&ds18b20_rom_codes[1][0]);//опрос нижнего датчика
delay_ms(500);//ждем 500 мс для получения температуры нижнего датчика
temper3=ds18b20_temperature(&ds18b20_rom_codes[2][0]);//опрос датчика двтгателя
delay_ms(500);}//ждем 500 мс для получения температуры датчика двигателя
while (ds18b20_divices>0){    //если датчиков больше 1 то бесконечный цикл

temper3=ds18b20_temperature(&ds18b20_rom_codes[2][0]);//опрос датчика двигателя
view_term_mot();

if(err==0){         //если разрешенно включение подогревателя то
if (temper1<=20){     //если температура нижнего датчика меньше 20
temper1=ds18b20_temperature(&ds18b20_rom_codes[1][0]);//опрос нижнего датчика
delay_ms(200); //ждем 500 мс для получения температуры нижнего датчика
view_term_hot();//выводим температуру
PORTC.4=1;    //Включение подогревателя
PORTC.2=0;    //Остановка двигателя на всякий случай
PORTC.3=0;}}      //Отключение помпы на всякий случай

if (temper1>=20){   //если температура нижнего датчика больше или равно 20
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);//опрос верхнего датчика
delay_ms(200);//ждем 500 мс для получения температуры верхнего датчика
view_term(); //выводим температуру верхнего датчика на индикатор
if (PINB.1==0){       //если датчик давления выключен
if (job==1){        //если состояние работы "вкл"
PORTC.4=0;        //Выключение подогревателя
PORTC.3=1;      //Включение помпы
PORTC.0=1;     //Включение клапана сброса давления
delay_ms(3000); //подождем 3 сек для сброса давления в нигистрале
PORTC.2=1;    //Запуск двигателя
delay_ms(3000); //подождем 3 сек для полного запуска двигателя
PORTC.0=0;    //Отключение клапана сброса давления
PORTC.1=1;  //Сигнал на включение второму компрессору
err=1;      //запрет на включение подогревателя
job=0;}}}      //установить состояние работы "выкл"

if (PINB.1==1){ //если датчик давления включен
if (job==0){  //если состояние работы "выкл"
PORTC.2=0;    //Остановка двигателя
PORTC.1=0;  //Сигнал на отключение второму компрессору
PORTC.0=1;     //Включение клапана сброса давления
delay_ms(3000); //подождем 3 сек для сброса давления в нигистрале
PORTC.0=0;    //Отключение клапана сброса давления
job=1;}  //установить состояние работы "вкл"
if (temper<=30){   //если температура верхнего датчика меньше или равно 30
PORTC.3=0;}}      //Отключение помпы

if (temper3>=60){   //если температура двигателя больше или равно 60
PORTC.2=0;}    //Остановка двигателя
if (temper3<=45){   //если температура двигателя упала до 45
job=1;}}}  //установить состояние работы "вкл"
[194.42 Кб]
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.02.2017, 17:11
Ответы с готовыми решениями:

Четыре датчика DS18B20 и динамическая индикация
Здравствуйте! Есть следующая задача. Рожается контроллер нагревателя, который содержит в своем...

Динамическая индикация
Здравствуйте! Хочу сделать динамическую индикацию на Atmega8 код примера взял отсюда : Динамическая...

Динамическая индикация
AT90USB162. Нужно чтобы два средних разряда 4-разрядного индикатора мигали. Прерывания по идее пока...

Динамическая индикация ATMega8535
Необходимо реализовать динамическую индикацию на 7 сегментном индикаторе. Даны начальные условия...

14
0 / 0 / 0
Регистрация: 06.05.2011
Сообщений: 49
23.02.2017, 18:37 2
Прерывание может возникнуть при перерассчёте. Например,

Код
number1=temper1/10;      //вычислить десятки
// плямс! прерывание.
number2=temper1%10;    //вычислить единицы
0
yrommoss
24.02.2017, 12:46 3
Попробывал запретить прерывание при пересчете командой #asm("cli") а после опять разрешить #asm("sio").Нечего не изменилось,так и прыгают цифры.Вот еще что заметил когда в протеусе по шагово смотришь,то когда доходит до опроса датчика то возникает прерывание и температура сразу прыгнет а потом еще и цифры прыгнут.
Получается вот так,
Код
 temper3=ds18b20_temperature(&ds18b20_rom_codes[2][0]);//опрос датчика двигателя
//прерывание
delay_ms(100);//ждем 100 мс для получения температуры датчика двигателя
Что еще можно сделать я не знаю.
0 / 0 / 0
Регистрация: 04.11.2012
Сообщений: 81
24.02.2017, 13:09 4
А где собственно 1W? Прерывания запрещаете на время общения с датчиками?
0
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
24.02.2017, 16:24 5
Не нужно ждать! DS18B20 нужно поллить. Как готово, он отпустит линию. И можно будет забрать данные.
0
yrommoss
24.02.2017, 19:37 6
Прерывание запрещаю когда идет разбивка числа на разряды. Пробывал запрещать прерывание перед опросом датчика,но тогда индикация начинает мигать и бегать.

Цитата Сообщение от Iddy_Im
Не нужно ждать! DS18B20 нужно поллить. Как готово, он отпустит линию. И можно будет забрать данные.
не понял что вы имеете ввиду?
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
24.02.2017, 20:00 7
В кодевижене своя библиотека 1-wire, не надо там ничего поллить.
ТС, отладьте сначала индикацию, без датчиков. Просто выводите в 4 разряда число 1234. Потом добавьте разбивку числа на разряды, опять же, без опроса датчиков, просто присваивая значение температуры вручную. Это поможет локализовать проблему.
По поводу схемы: совсем никак сегменты на один порт нельзя повесить? Это сильно упростило бы вывод на индикатор.
0
yrommoss
24.02.2017, 20:07 8
Раньше сегменты весели на одном порту,а разряды на другом.Но когда в протеусе началась свестопляска с цифрами,то решил сделать отладочную плату.И подгонял порты к сегментам,вот и получилось что все на разных.

А что значит поллить?
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
24.02.2017, 20:10 9
Поллить - это периодически опрашивать пин, к которому подключен датчик, вместо тупой задержки время преобразования температуры (750мс при макс. разрешении, по даташиту). В течении всего времени преобразования датчик будет удерживать линию в "нуле".
0
yrommoss
24.02.2017, 20:13 10
большое спасибо за ответ,буду пробывать сначало без датчиков,завтра отпишусь.
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
24.02.2017, 20:16 11
Протеус отлично обрабатывает и несколько DS18B20 и динам. индикацию. (ну при условии, что у вас не Sitirom 1200 :) ) Так что смело можно отлаживать ваш проект в нем.
0
yrommoss
24.02.2017, 20:22 12
да я в нем и отлаживаю,но когда делаешь чуть быстрее прерывание то пишет что CPU 100% и не может правильно симулировать.Комп у меня 4 ядерный,по 2,9 каждое ядро,4 Гб оперативки.Вот и решил что на живую уже точно все будет видно.
Вот сейчас попробывал убрал датчики,а вручную забил разные цифры,за 5 мин.,ни одного сбоя.Значит дело в опросе датчиков.
0 / 0 / 0
Регистрация: 03.01.2016
Сообщений: 126
24.02.2017, 22:45 13
CRC проверяйте в ответе датчика
0
yrommoss
25.02.2017, 10:20 14
Цитата Сообщение от Kypsy
CRC проверяйте в ответе датчика
для меня это очень сложно
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
25.02.2017, 11:08 15
Цитата Сообщение от Финский
В кодевижене своя библиотека 1-wire, не надо там ничего поллить.
Не знаю, что там в "кодевижене", но сколько я ни встречал "прожектов" с 1-wire, везде через задницу все было: либо ногодрыгом, либо с задержками. Сделать на КА, видимо, никому в голову не приходило.
На STM8 1-wire делается на таймере с прерываниями (т.к. там нет DMA), на STM32 — два варианта: либо таймер с DMA, либо USORT с DMA (кто-то даже SPI с DMA предлагал, но я такой реализации не делал); как на отмелях не знаю, никогда не вникал в их периферию. Но, думаю, и на этом шлаке можно что-то сделать по-человечески, а не завешивая вусмерть камень, пока термометр измерения проводит.
0
25.02.2017, 11:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.02.2017, 11:08
Помогаю со студенческими работами здесь

Динамическая индикация с транзисторами atmega16
Здравствуйте! возникла такая проблема: Схема состоит из мк atmega16, 4-разрядного сегментника с...

Динамическая индикация. Проблема с портом С (ATmega16)
Парни, ай нид хелп! Собрал схемку на atmega16 в tqfp корпусе, на порт С кинул сегменты от...

ATmega8515. CVAVR. Не работает динамическая индикация
Изучаю динамическую индикация и таймеры. Предполагалось, вывести динамическую индикацию на два...

Как работает динамическая индикация + AVR
Не могу понять как работают схемы динамической индикации описанные здесь:...

Динамическая индикация на примере управления светодиодной матрицей 4x
нашел данную статью - http://microsin.net/programming/avr/led-matrix-dynamic-indication.html очень...

Динамическая индикация на два независимых индикатора на atmega8
Здравствуйте. Так как только учусь программировать с миру по нитки собрал программу. На два...

[Atmega128] Динамическая индикация на многоразрядном семисегментном индикаторе
Всем привет. Программирую на МК Atmega128. По заданию встрял на динамической индикации для 7-ми...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru