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

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

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

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

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

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

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

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

Как я понял, обработчик прерывания - это строчки в начале кода (закомментированные). И их возможно использовать как обработчик?
Вот это:
PHP код:
/************************************* 
//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 


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

Изменил несколько код, повыкидывал лишнее, подправил кое где. Запускается в Протеусе, ..но несколько "но".
1.
В начале, во время установки температуры LCD моргает редко и очень короткими вспышками, что-либо разглядеть проблематично.

2.
Результат АЦП отображается на дисплее как +40 градусов, независимо от положения потенциометоров, имитирующих датчики температуры.

3.
При отображении температуры выбранного датчика, первая строчка LCD отображается нормально, вторая медленно мигает ???

А в остальном всё работает как задумывалось. Пока ничего в голову путнего не пришло как исправить эти баги.

Ниже приведён исправленный код:
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 T_MIN;
volatile char COUNTER;
volatile char T_MAX;
volatile char SENSOR_SEL;
volatile char SENSOR;
volatile char TEMP_def;
volatile char T_ZAD;

//LCD
char lcd_buffer[33];

//ADC interrupt service routine; Обработчик прерывания АЦП
interrupt [ADC_INTvoid adc_isr(void)
{
ADC_VALUE=ADCW;
}

//Реализация АЦП
void __ADC_SampleADC()
{
        
ADCSRA 0x8B;    //0b10001011 - ADC Enable; ADC Interrupt Enable; ADC Prescaler-8; 
        #asm("sei")
        
ADMUX COUNTER;  //0b00000xxx - ADLAR, выравнивание вправо 

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

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

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

    
//Опрос пина D5_"-"; Понижение заданной температуры
    
if (PIND.5 == 0)
    {
        
//Устранение дребезга. Delay: 200 ms
        
delay_ms(200);
        
//Нажата "-"?
        
if (PIND.5 == 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()
{
B__Check_OK:
    
//Цикл проверки "OK" 
     
if (PIND.6 == 0
    {
            
//Устранение дребезга. Delay: 200 ms
            
delay_ms(200);
            
//Нажата D6_OK?
            
if (PIND.6 == 0)
            {
            
//Переход на метку
            
goto A__Check_OK;
            }
    }
    else  
    {
    
//Вызов подпрограммы: Chek_Botton
    
Chek_Botton();
    
//Вызов подпрограммы: Check_bounds
    
Check_bounds();    
    };

//Вывод на дисплей заданной температуры
//Очистка дисплея
lcd_clear();
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_SampleADC()
        
__ADC_SampleADC();

        
//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 1;
    
    
//Включение нагревателей
    
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; 04.08.2010 в 19:45.
grizko вне форума  
 

Закладки
Опции темы

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

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

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


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


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