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

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

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

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

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

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

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

Закрытая тема
Опции темы
Непрочитано 01.08.2010, 18:59   #11
_guardianangel
Почётный гражданин KAZUS.RU
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 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   #12
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   #13
_guardianangel
Почётный гражданин KAZUS.RU
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 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   #14
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 ‹ 0x19cnt++;

        
//[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) / 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_ZADT_MAX)
    {
    
T_ZAD T_MAX;
    }

    
//  Проверка нижней границы T_zad‹T_min?
    
if (T_ZADT_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(00);
lcd_puts(lcd_buffer);

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

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

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

void ADC_IN()
{
    
//Организация цикла опроса АЦП
    
while (COUNTER8)
    {
        
//Выбор датчика
        
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_defT_ZAD)
    {
    
//Вызов подпрограммы: Out_ON
    
Out_ON();
    }

    
//Выключение нагревателей
    
if (TEMP_defT_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(10);
    
lcd_puts(lcd_buffer);
    
delay_ms(200);
    }
}

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

void Out_OFF()
{
//Output_ON
DDRC DDRC | (1‹‹COUNTER);
PORTC = (PORTC & (‹‹ 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   #15
_guardianangel
Почётный гражданин KAZUS.RU
 
Регистрация: 01.04.2009
Адрес: Рязань
Сообщений: 1,140
Сказал спасибо: 21
Сказали Спасибо 635 раз(а) в 344 сообщении(ях)
_guardianangel на пути к лучшему
По умолчанию Re: ATmega16 Устройство управления тепличными нагревателями

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

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

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

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

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

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

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

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

Закладки

Опции темы

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

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

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


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


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot