Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

Делимся опытом Наступив на грабли - сообщи другим! Обмен опытом разработки и ремонта электронных устройств.

 
Опции темы

ATmega16 Устройство управления тепличными нагревателями

Непрочитано 01.08.2010, 18:59  
_guardianangel
Почётный гражданин KAZUS.RUN
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

1. Как я понял у Вас стоит задача разработать терморегулятор для теплицы. Если следовать логике Вашего алгоритма выходит что контроллер считывает температуру, сравнивает с порогом и включает/выключает нагреватель. Представте ситуацию контроллер считал температуру и она на 0.5 градуса ниже порога, он включил нагреватель и тут к прибору подошли Вы и начали листать температуру по датчикам и задавать новый порог, а нагреватель работает греет. Вас отвлекли или Вы вспоминаете нужную температуру, а нагрев идет. Цикл прерван. Здесь необходимо разделить регулировку и задачу температуры. Далее у Вас ключевое включение нагрузки, т.е. температура понизилась нагреватель включился - представте температура упала на 0.1 градуса нагреватель включился, через секунду новый замер - температура выше порога - выключился и т.д. - как результат быстрый износ пускателя и обгорание контактов. Что бы избежать этого обычно задают 2 порога температуры с разницей в 1 - 2 градуса и учитывают предыдущее измерение. Выглядит это так - 2 порога 1 порог = 24 С 2 порог = 25 С, текущая температура = 18 С. Контроллер сравнивает текущую температуру с 1 порогом, она ниже - нагрев, сохраняет замер, второй замер температура = 19 С, берет разницу между 2 и 1 замером - разница положительна - идет нагрев =› сравнение с 2 порогом - температура меньше 2 порога - нагрев и т.д....... 25 замер температура 25.1 С предыдущая = 24.9 С разница положительна, сравниваем с 2 порогом - выше - отключить нагреватель ..... 30 замер температура = 24.6 предыдущий замер = 24.8 - разница отрицательна - охлаждение =› сравнение с 1 порогом.... 40 замер температура = 23.9 предыдущий замер = 24.1 разница отрицательная - охлаждение - сравнение с 1 порогом - меньше - включить нагреватель и т.д. Более подробно можете прочесть в книге "Аналоговые интерфейсы микроконтроллеров" Стюарт Болл Р. по моему видел в разделе книги ( у меня она в бумаге).

Теперь по поводу шедевра.
Код:
		ADCSRA = 0x8B;   //0b10001011 - ADC Enable; ADC Interrupt Enable; ADC Prescaler-8; 
		#asm("sei")
Эти строки кода разрешают прерывание по окончанию цикла преобразования АЦП, расположенного по адресу 0х01С. Тоесть как только закончиться преобразование и будет сброшен флаг ADSC в счетчик команд будет записано 0x01C и выполнение программы пойдет именно с этого адреса, т.к. у Вас обработчик данного прерывания не написан то одному Аллаху известно что произойдет, но скорее всего ребут системы т.к обычно компилятор помечает не используемые прерывания как ошибочные и пренудительно записывает в счетчик команд нулевой адрес, что по сути ребут. Вам же дабы избежать подобных проблем надо либо отказаться от прерывания и выбросить сей код, либо написать обработчик прерываний и переделать пол программы.

По поводу ожидания АЦП. Ждать фиксированные 25 тактов не надо, проще отслеживать состояние флага ADSC в регистре ADCSRA. Что кста у Вас и сделано.
_guardianangel вне форума  
Сказали "Спасибо" _guardianangel
grizko (01.08.2010)
Непрочитано 01.08.2010, 19:20  
grizko
Частый гость
 
Регистрация: 15.01.2010
Сообщений: 16
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
grizko на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Возможно я ошибаюсь, но в этом коде далее прописанно:
результат АЦП разделить на 31 (40-10+1) таким образом 33 единицы АЦП равняются 1-му градусу цельсия. А дальше по программе (допустим Т_задан = 22 градуса), если текущая температура датчика n = 23 градуса, то на порт РСn подать 1 (отключить), если 21 градус то на РСn подать 0, если 22 градуса то состояние порта не менять.
Мне кажется это нормальное решение, регулирование в пределах одного градуса. (десятичные значения градуса игнорируются, АЦП/31).

Цитата:
Вам же дабы избежать подобных проблем надо либо отказаться от прерывания и выбросить сей код, либо написать обработчик прерываний и переделать пол программы.
Выбросить строчку вообще? Или изменить значение ADCSRA?
grizko вне форума  
Непрочитано 01.08.2010, 19:30  
_guardianangel
Почётный гражданин KAZUS.RUN
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Сообщение от grizko Посмотреть сообщение
Возможно я ошибаюсь, но в этом коде далее прописанно:
результат АЦП разделить на 31 (40-10+1) таким образом 33 единицы АЦП равняются 1-му градусу цельсия. А дальше по программе (допустим Т_задан = 22 градуса), если текущая температура датчика n = 23 градуса, то на порт РСn подать 1 (отключить), если 21 градус то на РСn подать 0, если 22 градуса то состояние порта не менять.
Мне кажется это нормальное решение, регулирование в пределах одного градуса. (десятичные значения градуса игнорируются, АЦП/31).
Согласен. Можно и так.


Сообщение от grizko Посмотреть сообщение
Выбросить строчку вообще? Или изменить значение ADCSRA?
Выбросить строчку #asm ("sei")
Изменить значение ADCSRA
_guardianangel вне форума  
Сказали "Спасибо" _guardianangel
grizko (01.08.2010)
Непрочитано 01.08.2010, 19:31  
grizko
Частый гость
 
Регистрация: 15.01.2010
Сообщений: 16
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
grizko на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Я всё таки приведу код программы полностью, наверно так будет удобнее.
PHP код:
/**************************************************  ***
Программа управления тепличными нагревателями, в диапазоне температур от 10 до 40 градусов цельсия.
Управляет 8-ю нагревателями по сигналам датчиков, а также отображает температуру выбранного датчика.


Chip type               : ATmega16
Program type            : Application
AVR Core Clock frequency: 1.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
**************************************************  ***/

#include ‹mega16.h›
#include ‹stdio.h›
#include ‹delay.h›
#include ‹io.h›
#asm
   .equ __lcd_port=0x18 ;PORTB
#endasm
#include ‹lcd.h›

//Подпрограммы
void Zad_temp();
void Chek_Botton();
void Check_bounds();
void Check_OK();
void ADC_IN();
void Temp_Ind();
void Out_ON();
void Out_OFF();


//Объявление переменных
volatile short ADC_VALUE;
volatile char D6_OK;
volatile char T_MIN;
volatile char COUNTER;
volatile char D4_UP;
volatile char T_MAX;
volatile char D5_DOWN;
volatile char SENSOR_SEL;
volatile char SENSOR;
volatile char TEMP_def;
volatile char T_ZAD;

//LCD
char lcd_buffer[33];

//Определение функций АЦП
static void __ADC_SampleADC();
static short __ADC_ReadAsInt();


/*************************************
//ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned int iRetVal;
// Read the AD conversion result
iRetVal=ADCW;
// Place your code here

}
**************************************/

//Реализация АЦП
void __ADC_SampleADC()
{
        volatile char cnt;
        //[U]char dda;[/U]
        
        //[U]dda = DDRA;[/U]

        //[U]//Включить выбранный АЦП[/U]
        //[U]DDRA &= ~(1 ‹‹ COUNTER);[/U]
        
        ADCSRA = 0x83;   //0b10000011 - ADC Enable; [U]ADC Interrupt Enable;[/U] ADC Prescaler-8; 
        //[U]#asm("sei")[/U]
        ADMUX = 0x20 | COUNTER;  //0b00100xxx - ADC Left Adjust Result

        

        //начать преобразование
        ADCSRA |= 0x40;
        while(ADCSRA & 0x40);

        //время АЦП 25 тактов
        cnt = 0;
        while (cnt ‹ 0x19) cnt++;

        //[U]DDRA = dda;[/U]
}
static short __ADC_ReadAsInt()
{
        int iRetVal;
        __ADC_SampleADC();
        iRetVal = (ADCL ›› 6);
        iRetVal |= (ADCH ‹‹ 2);
        return (iRetVal);
}

void Zad_temp()
{
    T_MIN = 10;                             //  T_min = 10 нижняя граница диапазона
    T_MAX = 40;                             //  T_max = 40 верхняя граница диапазона
    T_ZAD = (T_MAX - T_MIN) / 2 + T_MIN;    //  Середина диапазона для начальной настройки:
}

void Chek_Botton()
{
    //Вход D4
    DDRD = DDRD & 0x10;
    D4_UP = (PIND.4 == 0);

    //Вход D5
    DDRD = DDRD & 0x20;
    D5_DOWN = (PIND.5 == 0);

    //Вход D6
    DDRD = DDRD & 0x40;
    D6_OK = (PIND == 0);


    //Опрос пина D4_UP? Увеличение заданной температуры
    if (D4_UP == 0)
    {
        //Устранение дребезга. Delay: 200 ms
        delay_ms(200);
        //Нажата "+"?
        if (D4_UP == 0)
        {
         T_ZAD = T_ZAD + 1;
        }
    }

    //Опрос пина D5_DOWN? Понижение заданной температуры
    if (D5_DOWN == 0)
    {
        //Устранение дребезга. Delay: 200 ms
        delay_ms(200);
        //Нажата "-"?
        if (D5_DOWN == 0)
        {
         T_ZAD = T_ZAD - 1;
        }
    }
}

void Check_bounds()
{
    //  Проверка верхней границы T_zad›T_max?
    if (T_ZAD›T_MAX)
    {
    T_ZAD = T_MAX;
    }

    //  Проверка нижней границы T_zad‹T_min?
    if (T_ZAD‹T_MIN)
    {
    T_ZAD = T_MIN;
    }
}

void Check_OK()
{
//Очистка дисплея
lcd_clear();
B__Check_OK:
    //Цикл проверки "OK" 
     if (D6_OK == 0) 
    {
            //Устранение дребезга. Delay: 200 ms
            delay_ms(200);
            //Нажата D6_OK?
            if (D6_OK == 0)
            {
            //Переход на метку
            goto A__Check_OK;
            }
    }
else  
    {
    //Вызов подпрограммы: Chek_Botton
    Chek_Botton();
    //Вызов подпрограммы: Check_bounds
    Check_bounds();    
    };

//Вывод на дисплей заданной температуры
sprintf(lcd_buffer," Set temp %u grd",T_ZAD);
lcd_init(16);
lcd_gotoxy(0, 0);
lcd_puts(lcd_buffer);

//Переход на метку
goto B__Check_OK;   

//Выход из цикла
A__Check_OK:

//Очистка дисплея
lcd_clear();
}

void ADC_IN()
{
    //Организация цикла опроса АЦП
    while (COUNTER‹8)
    {
        //Выбор датчика
        DDRD = DDRD & 0x07;
        SENSOR_SEL = PIND & 0x07;
        
        //Вызов функции: __ADC_ReadAsInt()
        __ADC_ReadAsInt();
        ADC_VALUE = __ADC_ReadAsInt();

        //Temp_Ind
        //Вызов подпрограммы: Temp_Ind
        Temp_Ind();

        //АЦП Counter
        if (COUNTER==7)
        
        { 
         //Сброс счетчика
         COUNTER = 0;
        }
         
        else
        {
         //Инкремент счетчика
         COUNTER = COUNTER + 1;
        }
    }
}

void Temp_Ind()
{
    //Преобразование данных АЦП в градусы
    TEMP_def = ADC_VALUE / 33 + T_MIN;
    
    //Включение нагревателей
    if (TEMP_def‹T_ZAD)
    {
    //Вызов подпрограммы: Out_ON
    Out_ON();
    }

    //Выключение нагревателей
    if (TEMP_def›T_ZAD)
    {
    //Вызов подпрограммы: Out_OFF
    Out_OFF();
    }
   
    //Индикация температуры выбранного датчика
    if (COUNTER==SENSOR_SEL)
    {
    SENSOR = SENSOR_SEL + 1;
    delay_ms(50);
    sprintf(lcd_buffer," Temp sensor %u  %u grd",SENSOR,TEMP_def);
    lcd_init(16);
    lcd_gotoxy(1, 0);
    lcd_puts(lcd_buffer);
    delay_ms(200);
    }
}

void Out_ON()
{
//Output_ON
DDRC = DDRC | (1‹‹COUNTER);
PORTC = PORTC & ~(1 ‹‹ COUNTER);
}

void Out_OFF()
{
//Output_ON
DDRC = DDRC | (1‹‹COUNTER);
PORTC = (PORTC & (1 ‹‹ COUNTER));
}

void main(void)
{
    //Инициализация
    MCUCSR=0x00;
    #asm("wdr")
    
    //Вызов подпрограммы: Zad_temp
    Zad_temp();

    //Вызов подпрограммы: Check_OK
    Check_OK();

    // Установка сетчика. Counter = 0
    COUNTER = 0;

    //Вызов подпрограммы: ADC_IN
    ADC_IN();
} 

Последний раз редактировалось grizko; 02.08.2010 в 17:57.
grizko вне форума  
Непрочитано 01.08.2010, 19:34  
_guardianangel
Почётный гражданин KAZUS.RUN
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Было бы не плохо указать каким компилятором пользуетесь.
_guardianangel вне форума  
Непрочитано 01.08.2010, 19:47  
grizko
Частый гость
 
Регистрация: 15.01.2010
Сообщений: 16
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
grizko на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Сообщение от _guardianangel Посмотреть сообщение
Было бы не плохо указать каким компилятором пользуетесь.
Компилятор CodeVisionAVR V2.04.4a но туда я напихал разного кода. В частности изначально код был сгенерирован "Flowcode V4 for AVR", в нём я писал алгоритм (да и хотел сэкономить в написании текста программы). Кстати в "Flowcode V4 for AVR" он работал, но он там несколько специфичен, если есть возможность просмотреть файлы Flowcode V4 for AVR могу выложить проект. Но я хотел бы разобраться на С, на Ассемблере многовато писанины, хотя на асме мне кажется понятнее.
grizko вне форума  
Непрочитано 01.08.2010, 19:51  
grizko
Частый гость
 
Регистрация: 15.01.2010
Сообщений: 16
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
grizko на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Сообщение от _guardianangel Посмотреть сообщение
Выбросить строчку #asm ("sei")
Мне кажется данная строчка разрешает прерывания глобально, в данном случае и для АЦП. Или я опять что-то недопонял?
grizko вне форума  
Непрочитано 01.08.2010, 23:07  
_guardianangel
Почётный гражданин KAZUS.RUN
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

У Вас разрешено только одно прерывание - от АЦП и то, как мы разобрались, без обработчика. Ежели Вы не используете прерывания то лучше их запретить глобально, а точнее просто не разрешать - по дефолту они запрещены.
_guardianangel вне форума  
Непрочитано 02.08.2010, 06:41  
grizko
Частый гость
 
Регистрация: 15.01.2010
Сообщений: 16
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
grizko на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Сообщение от _guardianangel Посмотреть сообщение
У Вас разрешено только одно прерывание - от АЦП и то, как мы разобрались, без обработчика. Ежели Вы не используете прерывания то лучше их запретить глобально, а точнее просто не разрешать - по дефолту они запрещены.
А в этом случае АЦП будет выполнятся? Если запретить прерывания глобально?

А как будет лучше (правильней), отказаться от прерываний или написать обработчик?

Последний раз редактировалось grizko; 02.08.2010 в 06:44.
grizko вне форума  
Непрочитано 03.08.2010, 14:05  
_guardianangel
Почётный гражданин KAZUS.RUN
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,138
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

Сообщение от grizko Посмотреть сообщение
А в этом случае АЦП будет выполнятся? Если запретить прерывания глобально?
Будет.

Сообщение от grizko Посмотреть сообщение
А как будет лучше (правильней), отказаться от прерываний или написать обработчик?
А эт Вам уже решать. От это будет зависить как Вы реализуете алгоритм. Реализация возможна как с использованием прерываний так и без них.
_guardianangel вне форума  
Сказали "Спасибо" _guardianangel
grizko (03.08.2010)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 02:31.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.