Перейти к содержанию

Atmega8 2 ШИМ и прерывание по таймеру для чтения DS18B20


Рекомендуемые сообщения

Всем доброго времени суток. Я реальный нуб в ATMEGA. Могу более-менее понять чужой код и из кусков сделать целое. Вопрос такой: реально ли на ATMEGA8 сделать 2 ШИМ (таймер 1 и2) и внутреннее прерывание (по таймеру 0) для чтения данных с DS18B20 на 8Мгц чтобы еще осталось на опрос кнопок и небольшую логику? Я выложу пример кода. По отдельность: ШИМ, прерывания, логика, запись в ЕПРОМ работает. Собираю все вместе - не работает. Пробовал в Протеусе, тоже глючит, да и протеус тормозит. Может кто чего подскажет.

//#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include "ds18x20.h"
#include "onewire.h"


#define MAXSENSORS 1

unsigned int tempint = 0; // переменная для целого значения температуры
unsigned int subzero = 0; // переменная отрицательных значений температуры
unsigned int clock = 0; //задержка для опроса датчика температуры
unsigned int termo_error = 0; //флаг ошибки термодатчика
unsigned char regim, R1_SHIBER, R1_VENT, R2_SHIBER, R2_VENT, R3_SHIBER, R3_VENT; //переменные режимов работы
volatile char press = 0, pr = 0, pr1 = 0, set = 0; //дополнительные переменные для кнопок

#define SHIBER_PB	1 //шибер подачи топлива
#define SHIBER_PWM	OCR1A
#define VENT_PB	2 //вентилятор подачи воздуха
#define VENT_PWM	OCR1B

#define LED1_ON PORTD |= _BV(PD3) // светодиод режим 1
#define LED1_OFF PORTD &= ~_BV(PD3)
#define LED2_ON PORTD |= _BV(PD4) // светодиод режим 2
#define LED2_OFF PORTD &= ~_BV(PD4)
#define LED3_ON PORTD |= _BV(PD6) // светодиод режим 3
#define LED3_OFF PORTD &= ~_BV(PD6)
#define LED4_ON PORTD |= _BV(PD7) // светодиод 4 программирование
#define LED4_OFF PORTD &= ~_BV(PD7)

#define BUT_M PIND & (1 << PD1)  // кнопка MENU
#define BUT_U PIND & (1 << PD2)  // кнопка UP
#define BUT_D PIND & (1 << PD0)  // кнопка DOWN

unsigned char eep1 EEMEM; // режим работы
unsigned char eep2 EEMEM; // режим 1 ШИМ вентилятор
unsigned char eep3 EEMEM; //режим 1 ШИМ шибер
unsigned char eep4 EEMEM; // режим 2 ШИМ вентилятор
unsigned char eep5 EEMEM; //  режим 2 ШИМ шибер
unsigned char eep6 EEMEM; // режим 3 ШИМ вентилятор
unsigned char eep7 EEMEM; // режим 3 ШИМ шибер
unsigned char eep8 EEMEM; // флаг первого запуска


uint8_t Temperature, szero; //-255
uint8_t nSensors, j;
uint8_t cel_frac_bits;
uint8_t gSensorIDs[MAXSENSORS][OW_ROMCODE_SIZE];

uint8_t search_sensors(void) // поиск DS18B20
{
	uint8_t i;
	uint8_t id[OW_ROMCODE_SIZE];
	uint8_t diff, nSensors;

	nSensors = 0;

	for( diff = OW_SEARCH_FIRST;
		diff != OW_LAST_DEVICE && nSensors < MAXSENSORS ; )
	{
		DS18X20_find_sensor( &diff, &id[0] );

		if( diff == OW_PRESENCE_ERR ) {
			Temperature = 255;
			szero = 1;
			break;
		}
		if( diff == OW_DATA_ERR ) {
			Temperature = 255;
			szero = 1;
			break;
		}
		for (i=0; i<OW_ROMCODE_SIZE; i++)
			gSensorIDs[nSensors][i]=id[i];

		nSensors++;
	}

	return nSensors;
}


void get_temp(int sensor){ // получаем температуру с датчиков


		DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL);
		DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL);

		j = gSensorIDs[0][sensor]; // family-code for conversion-routine

		if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255
			Temperature = 255;
			szero = 1;
		}
			if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255
			Temperature = 255;
			szero = 1;
		}

		tempint=(int)Temperature;
		subzero=(int)szero;
}


void pin_init(void) { //инициализация портов ШИМ
    DDRB |= (1<<SHIBER_PB) | (1<<VENT_PB);
    PORTB &= ~((1<<SHIBER_PB) | (1<<VENT_PB));
}


void timer0_init(void) { //инициализация таймера для термодатчика 
TCCR0 |= (1<<CS00); 
TIMSK |= ( 1 << TOIE0); 
TCNT0 = 0xFF; 
}

void timer1_init(void) { //инициализация таймера ШИМ шибера
   TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
    TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
    TCNT1 = 0x00;
    ICR1 = 0xFF;
    OCR1A = 0x00;
    OCR1B = 0x00;
}

void timer2_init(void) { //инициализация таймера ШИМ вентилятора
    TCCR2 |= (1 << COM21) | (1 << WGM21) | (1 << WGM20) | (1 << CS20);
    TCNT2 = 0x00;
    OCR2 = 0x00;
}

ISR(TIMER0_OVF_vect){ //прерывание таймера 0 для термодатчика

if (clock != 4294967295){_delay_us(50);clock++;}else{get_temp(0);clock=0;}

}

	 
//***************** обработка нажатия кнопок **********************
void buttons(){ 

	if(~BUT_U){if(set == 0)pr++; // кнопка UP
		
		if(pr == 10){ // долгое нажатие
			
		}
		
	_delay_ms(100);

	}else{
		if(pr >= 1 && pr < 10){ // короткое нажатие
		regim++;
		if (regim>3){regim=0;}
		eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom
		set = 0;
		pr = 0;
		}
		pr = 0;
	}


	if(~BUT_D){if(set == 0)pr1++; // кнопка DOWN

	if(pr1 == 10){ // длинное нажатие
	
		}
	_delay_ms(100);

	}else{

	if(pr1 >= 1 && pr1 < 10){ // короткое нажатие.
			//set = 20;
			regim--;
		if (regim<0){regim=3;}
		eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom	
		_delay_ms(100);
			set = 0;
			pr1 = 0;
		}
		pr1 = 0;
	}




	if(~BUT_M){ // кнопка MENU
	
		press++;  

		if(press == 1 && set != 0){set++;} // переход по настройкам
		if(press >= 100 && set == 0){set = 1; _delay_ms(200);} // ход в настройки
		
		if(set == 1) eeprom_write_byte(&eep2, R1_VENT);
		if(set == 2) eeprom_write_byte(&eep3, R1_SHIBER);
		if(set == 3) eeprom_write_byte(&eep4, R2_VENT);
		if(set == 4) eeprom_write_byte(&eep5, R2_SHIBER);	
		if(set == 5) eeprom_write_byte(&eep6, R3_VENT);
		if(set == 6) eeprom_write_byte(&eep7, R3_SHIBER);

		
		if(set > 6){ _delay_ms(100); set = 0; press = 0;} // если включена настройка даты,
	

	}else{
		if(set == 0 && press >= 1){ // если не вошли в настройки
		regim++;
		if (regim>3){regim=0;}
		eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom
		}

		press = 0;
	}
}
//*****************режим настроек********************

void settings(){ 
//визуальное подтверждение настроек
if(press >= 1 && set == 1) {
LED1_ON;
LED2_OFF;
LED3_OFF;
LED4_ON;
SHIBER_PWM = R1_VENT;} //ШИМ шибер 0-255
if(press >= 1 && set == 2) {
LED1_ON;
LED2_OFF;
LED3_OFF;
LED4_ON;
VENT_PWM = R1_SHIBER;} //ШИМ вентилятор 0-255
if(press >= 1 && set == 3) {
LED1_OFF;
LED2_ON;
LED3_OFF;
LED4_ON;
SHIBER_PWM = R2_VENT;} //ШИМ шибер 0-255
if(press >= 1 && set == 4) {
LED1_OFF;
LED2_ON;
LED3_OFF;
LED4_ON;
VENT_PWM = R2_SHIBER;} //ШИМ вентилятор 0-255
if(press >= 1 && set == 5) {
LED1_OFF;
LED2_OFF;
LED3_ON;
LED4_ON;
SHIBER_PWM = R3_VENT;} //ШИМ шибер 0-255
if(press >= 1 && set == 6) {
LED1_OFF;
LED2_OFF;
LED3_ON;
LED4_ON;
VENT_PWM = R3_SHIBER;} //ШИМ вентилятор 0-255


switch(set) // включена настройка
	{
	case 1: // настройка R1_VENT
		if(~BUT_U){R1_VENT++; if(R1_VENT > 254) R1_VENT = 0; _delay_ms(100);}
		if(~BUT_D){R1_VENT--; if((~BUT_D) && R1_VENT == 0) R1_VENT = 254; _delay_ms(100);}
	break;

	case 2: // настройка R1_SHIBER
		if(~BUT_U){R1_SHIBER++; if(R1_SHIBER > 254) R1_SHIBER = 0; _delay_ms(100);}
		if(~BUT_D){R1_SHIBER--; if((~BUT_D) && R1_SHIBER == 0) R1_SHIBER = 254; _delay_ms(100);}
	break;

	case 3: // настройка R2_VENT
	if(~BUT_U){R2_VENT++; if(R2_VENT > 254) R2_VENT = 0; _delay_ms(100);}
		if(~BUT_D){R2_VENT--; if((~BUT_D) && R2_VENT == 0) R2_VENT = 254; _delay_ms(100);}
	break;

	case 4: // настройка R2_SHIBER
		if(~BUT_U){R2_SHIBER++; if(R2_SHIBER > 254) R2_SHIBER = 0; _delay_ms(100);}
		if(~BUT_D){R2_SHIBER--; if((~BUT_D) && R2_SHIBER == 0) R2_SHIBER = 254; _delay_ms(100);}
	break;

	case 5: // настройка R3_VENT
	if(~BUT_U){R3_VENT++; if(R3_VENT > 254) R3_VENT = 0; _delay_ms(100);}
		if(~BUT_D){R3_VENT--; if((~BUT_D) && R3_VENT == 0) R3_VENT = 254; _delay_ms(100);}
	break;

	case 6: // настройка R3_SHIBER
		if(~BUT_U){R3_SHIBER++; if(R3_SHIBER > 254) R3_SHIBER = 0; _delay_ms(100);}
		if(~BUT_D){R3_SHIBER--; if((~BUT_D) && R3_SHIBER == 0) R3_SHIBER = 254; _delay_ms(100);}
	break;	
	}
}



int main(){

	/*******************************настройка переферии******************************/	
	cli();
 	ow_set_bus(&PIND, &PORTD, &DDRD, PD5); // иництализация протокола 1-wire
	nSensors = search_sensors(); // поиск датчиков DS18B20
	DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); //включаем преобразование температуры
	pin_init();
	//timer0_init();
 	timer1_init();
 	timer2_init();
	_delay_ms(5);
	if(eeprom_read_byte(&eep8) != 1){ // читаем eeprom, если там мусор (первый запуск), пишем свои данные
		eeprom_write_byte(&eep1, 0); // режим работы
		eeprom_write_byte(&eep2, 150); // режим 1 ШИМ вентилятор
		eeprom_write_byte(&eep3, 100); //режим 1 ШИМ шибер
		eeprom_write_byte(&eep4, 200); //режим 2 ШИМ вентилятор
		eeprom_write_byte(&eep5, 150);  //режим 2 ШИМ шибер
		eeprom_write_byte(&eep6, 230); //режим 3 ШИМ вентилятор
		eeprom_write_byte(&eep7, 200); //режим 3 ШИМ шибер
		eeprom_write_byte(&eep8, 1); // флаг первого запуска
	
	}
	//читаем настройки из памяти
	regim = eeprom_read_byte(&eep1); // читаем режим работы из eeprom
	R1_VENT = eeprom_read_byte(&eep2); // читаем режим 1 ШИМ вентилятор из eeprom
	R1_SHIBER = eeprom_read_byte(&eep3); //читаем режим 1 ШИМ шибер
	R2_VENT = eeprom_read_byte(&eep4); //читаем режим 2 ШИМ вентилятор
	R1_SHIBER = eeprom_read_byte(&eep5); //читаем режим 2 ШИМ шибер
	R3_VENT = eeprom_read_byte(&eep6); //читаем режим 3 ШИМ вентилятор
	R1_SHIBER = eeprom_read_byte(&eep7); 	//читаем режим 3 ШИМ шибер
	sei();
	_delay_ms(5);
/**********************************инициализация ШИМ*************************************/

	while(1){

//if (tempint=255) {LED1_ON;LED2_OFF;LED3_ON;termo_error=1;} else {termo_error=0;}//выводим код ошибки датчика темппературы 

buttons();//обработик нажатия кнопок

if (termo_error == 0){//блокировка по термодатчику
if(set == 0) { //нормальный режим работы
	if (regim == 0){ //режим работы 0
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	LED4_OFF;
	SHIBER_PWM = 0; //ШИМ шибер 0-255
	VENT_PWM = 0; //ШИМ вентилятор 0-255
	}

	if (regim == 1){ //режим работы 1
	LED1_ON;
	LED2_OFF;
	LED3_OFF;
	LED4_OFF;
	VENT_PWM = R1_VENT; //ШИМ вентилятор 0-255
		if (tempint >=40) { //блокировка по температуре
		SHIBER_PWM = 0; //ШИМ шибер 0-255
		}else{
		SHIBER_PWM = R1_SHIBER; //ШИМ шибер 0-255
		}
	}

	if (regim == 2){ //режим работы 2
	LED1_OFF;
	LED2_ON;
	LED3_OFF;
	LED4_OFF;
	VENT_PWM = R2_VENT; //ШИМ вентилятор 0-255
		if (tempint >=60) { //блокировка по температуре
		SHIBER_PWM = 0; //ШИМ шибер 0-255
		}else{
		SHIBER_PWM = R2_SHIBER; //ШИМ шибер 0-255
		}
	}

	if (regim == 3){ //режим работы 3
	LED1_OFF;
	LED2_OFF;
	LED3_ON;
	LED4_OFF;
	VENT_PWM = R3_VENT; //ШИМ вентилятор 0-255
		if (tempint >=80) { //блокировка по температуре
		SHIBER_PWM = 0; //ШИМ шибер 0-255
		}else{
		SHIBER_PWM = R3_SHIBER; //ШИМ шибер 0-255
		}
	}
}
}else{
SHIBER_PWM=0;
VENT_PWM=0;
}
	if(set != 0) settings();//вход в настройки
} 

	//return 0;
}


 

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Я бы в такой конструкции применил бы аналоговый датчик температуры - LM135 и фильтрацию результатов по "окну" с ним гораздо меньше проблем. Обращение с DS18B20 требует точного измерения времени импульса, а возникающие прерывания в процессе измерения всё портят, поэтому у вас имеются глюки. Попробуйте на время считывания/записи данных с датчика запрещать прерывания.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

В 23 Август 2017 г. в 19:15, balistik сказал:

unsigned int clock = 0; //задержка для опроса датчика температуры

 

В 23 Август 2017 г. в 19:15, balistik сказал:

ISR(TIMER0_OVF_vect){ //прерывание таймера 0 для термодатчика

if (clock != 4294967295){_delay_us(50);clock++;}else{get_temp(0);clock=0;} }

что это за бред написан?

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Внутри обработчика прерывания таймера не следует опрашивать датчик. Опрос, как было сказано ранее, процедура длительная и чувствительная к задержкам. Длительные процедуры логично выполнять в основном цикле. Поэтому в обработчике прерывания таймера следует устанавливать какой-то флаг, а в главном цикле этот флаг опрашивать и, если он установлен, работать с датчиком и сбрасывать флаг.

Разумеется, процедура опроса датчика должна запрещать прерывания в критичные моменты - это не долго длится...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

12 минуты назад, ARV сказал:

Внутри обработчика прерывания таймера не следует опрашивать датчик.

его как раз и следует опрашивать в прерывании по одному байту , только уж точно не библиотеками

Ссылка на комментарий
Поделиться на другие сайты

Спасибо. Отказался от цифрового датчика. Перешел на аналоговый LM. Все вроде работает. Протеус тормозит. Приходится комментировать часть кода, потом отлаживать оставшуюся. По поводу огромного числа - это просто крик души был. Блин. Надо бросать протеус и делать прототип.  Т.к. работу с еепром он тоже нормально не может симулировать.

Может кто посмотрит, что не так может быть с работой с еепром.

#define F_CPU 8000000L // óñòàíàâëèâàåì ðàáî÷óþ ÷àñòîòó êîíòðîëëåðà
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/eeprom.h>


unsigned int temp_ADC; //àíàëîãîâàÿ ïåðåìåííàÿ äàò÷èêà òåìïåðàòóðû
volatile //ìàêñèìóì 1024 ïðè íàïðÿæåíèè 5Â
//0 ãðàäóñîâ Öåëüñèÿ = 376
//100 ãðàäóñîâ Öåëüñèÿ = 451
volatile unsigned int tempint=0; // ïåðåìåííàÿ äëÿ öåëîãî çíà÷åíèÿ òåìïåðàòóðû
volatile unsigned int termo_error = 0; //ôëàã îøèáêè òåðìîäàò÷èêà
volatile unsigned char regim=0, R1_SHIBER=0, R1_VENT=0, R2_SHIBER=0, R2_VENT=0, R3_SHIBER=0, R3_VENT=0; //ïåðåìåííûå ðåæèìîâ ðàáîòû
volatile char press = 0, pr = 0, pr1 = 0, set = 0; //äîïîëíèòåëüíûå ïåðåìåííûå äëÿ êíîïîê

#define SHIBER_PB	1 //øèáåð ïîäà÷è òîïëèâà
#define SHIBER_PWM	OCR1A
#define VENT_PB	2 //âåíòèëÿòîð ïîäà÷è âîçäóõà
#define VENT_PWM	OCR1B


#define LED1_ON PORTD |= _BV(PD3) // ñâåòîäèîä ðåæèì 1
#define LED1_OFF PORTD &= ~_BV(PD3)
#define LED2_ON PORTD |= _BV(PD4) // ñâåòîäèîä ðåæèì 2
#define LED2_OFF PORTD &= ~_BV(PD4)
#define LED3_ON PORTD |= _BV(PD6) // ñâåòîäèîä ðåæèì 3
#define LED3_OFF PORTD &= ~_BV(PD6)
#define LED4_ON PORTD |= _BV(PD7) // ñâåòîäèîä 4 ïðîãðàììèðîâàíèå
#define LED4_OFF PORTD &= ~_BV(PD7)

#define BUT_M PIND & (1 << PD1)  // êíîïêà MENU
#define BUT_U PIND & (1 << PD2)  // êíîïêà UP
#define BUT_D PIND & (1 << PD0)  // êíîïêà DOWN

unsigned char eep1 EEMEM; // ðåæèì ðàáîòû
unsigned char eep2 EEMEM; // ðåæèì 1 ØÈÌ øèáåð
unsigned char eep3 EEMEM; //ðåæèì 1 ØÈÌ âåíòèëÿòîð
unsigned char eep4 EEMEM; // ðåæèì 2 ØÈÌ øèáåð
unsigned char eep5 EEMEM; //  ðåæèì 2 ØÈÌ âåíòèëÿòîð
unsigned char eep6 EEMEM; // ðåæèì 3 ØÈÌ øèáåð
unsigned char eep7 EEMEM; // ðåæèì 3 ØÈÌ âåíòèëÿòîð
unsigned char eep8 EEMEM; // ôëàã ïåðâîãî çàïóñêà


ISR (ADC_vect)//Ïðåðûâàíèÿ àíàëîãîâîãî âõîäà
{ 
	temp_ADC = ADCW;
	ADCSR |= (1<<ADSC);//çàíîâî âêëþ÷àåì àíàëîãîâûé âõîä
}



void pin_init(void) { //èíèöèàëèçàöèÿ ïîðòîâ ØÈÌ
    DDRB |= (1<<SHIBER_PB) | (1<<VENT_PB);
    PORTB &= ~((1<<SHIBER_PB) | (1<<VENT_PB));
}


void timer1_init(void) { //èíèöèàëèçàöèÿ òàéìåðà ØÈÌ 
   TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
   TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10);
   TCNT1 = 0x00;
   ICR1 = 0xFF;
   OCR1A = 0x00;
   OCR1B = 0x00;
}

//***************** îáðàáîòêà íàæàòèÿ êíîïîê **********************
void buttons(){ 

	if(~BUT_U){if(set == 0)pr++;// êíîïêà UP
	//ðåæèì ðàáîòû +1 è âêëþ÷åíèå
	if(pr >= 1 && pr < 10){ 
			set = 20;
			regim++;
		if (regim>3){regim=3;}
		eeprom_write_byte(&eep1, regim); // ñîõðàíåíèå íàñòðîéêè â eeprom
		_delay_ms(200);
			set = 0;
			pr = 0;
		}
	}

	if(~BUT_D){if(set == 0)pr1++;// êíîïêà DOWN
	//ðåæèì ðàáîòû -1 è äî âûêëþ÷åíèÿ
	if(pr1 >= 1 && pr1 < 10){ 
			set = 20;
			regim--;
		//if (regim<1){regim=1;}
		eeprom_write_byte(&eep1, regim); // ñîõðàíåíèå íàñòðîéêè â eeprom
		_delay_ms(200);
			set = 0;
			pr1 = 0;
		}
	}

	if(~BUT_M){ // êíîïêà MENU
	//ïåðåõîä â íàñòðîéêè
		press++;  
	asm("cli");
		if(press >= 1 && set != 0){set++;} // ïåðåõîä ïî íàñòðîéêàì
		if(press <10 && set == 0){set = 1; _delay_ms(200);} // õîä â íàñòðîéêè
		
		if(set == 1) eeprom_write_byte(&eep2, R1_SHIBER);
		if(set == 2) eeprom_write_byte(&eep3, R1_VENT);
		if(set == 3) eeprom_write_byte(&eep4, R2_SHIBER);
		if(set == 4) eeprom_write_byte(&eep5, R2_VENT);	
		if(set == 5) eeprom_write_byte(&eep6, R3_SHIBER);
		if(set == 6) eeprom_write_byte(&eep7, R3_VENT);
	
		if(set == 8){ _delay_ms(100); set = 0; press = 0;} // âûõîäèì èç íàñòðîåê
		_delay_ms(200);
	asm("sei");			
	}

}
//*****************ðåæèì íàñòðîåê********************

void settings(){ 
//âèçóàëüíîå ïîäòâåðæäåíèå íàñòðîåê
if(set == 1) {
LED1_ON;
LED2_OFF;
LED3_OFF;
LED4_ON;
VENT_PWM = 0;
SHIBER_PWM = R1_SHIBER;} //ØÈÌ øèáåð 0-255
if(set == 2) {
LED1_ON;
LED2_OFF;
LED3_OFF;
LED4_ON;
SHIBER_PWM = 0;
VENT_PWM = R1_VENT;} //ØÈÌ âåíòèëÿòîð 0-255
if(set == 3) {
LED1_OFF;
LED2_ON;
LED3_OFF;
LED4_ON;
VENT_PWM = 0;;
SHIBER_PWM = R2_SHIBER;} //ØÈÌ øèáåð 0-255
if(set == 4) {
LED1_OFF;
LED2_ON;
LED3_OFF;
LED4_ON;
SHIBER_PWM =0;
VENT_PWM = R2_VENT;} //ØÈÌ âåíòèëÿòîð 0-255
if(set == 5) {
LED1_OFF;
LED2_OFF;
LED3_ON;
LED4_ON;
VENT_PWM = 0;
SHIBER_PWM = R3_SHIBER;} //ØÈÌ øèáåð 0-255
if(set == 6) {
LED1_OFF;
LED2_OFF;
LED3_ON;
LED4_ON;
SHIBER_PWM = 0;
VENT_PWM = R3_VENT;} //ØÈÌ âåíòèëÿòîð 0-255
if(set == 7) {
if (tempint>40){LED1_ON;}else{LED1_OFF;}
if (tempint>60){LED2_ON;}else{LED2_OFF;}
if (tempint>80){LED3_ON;}else{LED3_OFF;}} //êîíòðîëü äàò÷èêà òåìïåðàòóðû


switch(set) // âêëþ÷åíà íàñòðîéêà
	{
	case 1: // íàñòðîéêà R1_SHIBER
		if(~BUT_U){R1_SHIBER++; if(R1_SHIBER > 254) R1_SHIBER = 255; _delay_ms(100);}
		if(~BUT_D){R1_SHIBER--; if((~BUT_D) && R1_SHIBER == 0) R1_SHIBER = 0; _delay_ms(100);}
	break;

	case 2: // íàñòðîéêà R1_VENT
		if(~BUT_U){R1_VENT++; if(R1_VENT > 254) R1_VENT = 255; _delay_ms(100);}
		if(~BUT_D){R1_VENT--; if((~BUT_D) && R1_VENT == 0) R1_VENT = 0; _delay_ms(100);}
	break;

	case 3: // íàñòðîéêà R2_SHIBER
	if(~BUT_U){R2_SHIBER++; if(R2_SHIBER > 254) R2_SHIBER = 255; _delay_ms(100);}
		if(~BUT_D){R2_SHIBER--; if((~BUT_D) && R2_SHIBER == 0) R2_SHIBER = 0; _delay_ms(100);}
	break;

	case 4: // íàñòðîéêà R2_VENT
		if(~BUT_U){R2_VENT++; if(R2_VENT > 254) R2_VENT = 255; _delay_ms(100);}
		if(~BUT_D){R2_VENT--; if((~BUT_D) && R2_VENT == 0) R2_VENT = 0; _delay_ms(100);}
	break;

	case 5: // íàñòðîéêà R3_SHIBER
	if(~BUT_U){R3_SHIBER++; if(R3_SHIBER > 254) R3_SHIBER = 255; _delay_ms(100);}
		if(~BUT_D){R3_SHIBER--; if((~BUT_D) && R3_SHIBER == 0) R3_SHIBER = 0; _delay_ms(100);}
	break;

	case 6: // íàñòðîéêà R3_VENT
		if(~BUT_U){R3_VENT++; if(R3_VENT > 254) R3_VENT = 255; _delay_ms(100);}
		if(~BUT_D){R3_VENT--; if((~BUT_D) && R3_VENT == 0) R3_VENT = 0; _delay_ms(100);}
	break;	
	}
}


int main(){

	/*******************************íàñòðîéêà ïåðåôåðèè******************************/	
	asm("cli");
	if(eeprom_read_byte(&eep8) != 1){ // ÷èòàåì eeprom, åñëè òàì ìóñîð (ïåðâûé çàïóñê), ïèøåì ñâîè äàííûå
		eeprom_write_byte(&eep1, 0); // ðåæèì ðàáîòû
		eeprom_write_byte(&eep2, 150); // ðåæèì 1 ØÈÌ SHIBER
		eeprom_write_byte(&eep3, 100); //ðåæèì 1 ØÈÌ VENT
		eeprom_write_byte(&eep4, 200); //ðåæèì 2 ØÈÌ SHIBER
		eeprom_write_byte(&eep5, 150);  //ðåæèì 2 ØÈÌ VENT
		eeprom_write_byte(&eep6, 230); //ðåæèì 3 ØÈÌ SHIBER
		eeprom_write_byte(&eep7, 200); //ðåæèì 3 ØÈÌ VENT
		eeprom_write_byte(&eep8, 1); // ôëàã ïåðâîãî çàïóñêà
	
	}
	//÷èòàåì íàñòðîéêè èç ïàìÿòè
	regim = eeprom_read_byte(&eep1); // ÷èòàåì ðåæèì ðàáîòû èç eeprom
	R1_SHIBER = eeprom_read_byte(&eep2); // ÷èòàåì ðåæèì 1 ØÈÌ âåíòèëÿòîð èç eeprom
	R1_VENT = eeprom_read_byte(&eep3); //÷èòàåì ðåæèì 1 ØÈÌ øèáåð
	R2_SHIBER = eeprom_read_byte(&eep4); //÷èòàåì ðåæèì 2 ØÈÌ âåíòèëÿòîð
	R2_VENT = eeprom_read_byte(&eep5); //÷èòàåì ðåæèì 2 ØÈÌ øèáåð
	R3_SHIBER = eeprom_read_byte(&eep6); //÷èòàåì ðåæèì 3 ØÈÌ âåíòèëÿòîð
	R3_VENT = eeprom_read_byte(&eep7); 	//÷èòàåì ðåæèì 3 ØÈÌ øèáåð

	_delay_ms(100);

	pin_init();
 	timer1_init();

	ADMUX |= (1<<REFS0);//íàñòðàèâàåì àíàëîãîâûé âõîä íà ïîðò (PC0)
	//îïîðíîå íàïðÿæåíèå 5Â ïèòàíèÿ êîíòðîëëåðà
	ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADPS1) | (1<<ADPS0);	                                                                        
	asm("sei");

	_delay_ms(100);

/**********************************èíèöèàëèçàöèÿ *************************************/

	while(1){

buttons();//îáðàáîòèê íàæàòèÿ êíîïîê

//âûâîäèì êîä îøèáêè äàò÷èêà òåìïïåðàòóðû
if (temp_ADC>1000){LED1_ON;LED2_OFF;LED3_ON;termo_error=1;} else {termo_error=0;}

//äåëàåì ðàñ÷åò òåìïåðàòóðû îò äàò÷èêà
tempint=((((((float)temp_ADC)*5)/1024)*100)-273);

if (termo_error == 0){//áëîêèðîâêà ïî òåðìîäàò÷èêó
if(set == 0) { //íîðìàëüíûé ðåæèì ðàáîòû
	if (regim == 0){ //ðåæèì ðàáîòû 0
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	LED4_OFF;
	SHIBER_PWM = 0; //ØÈÌ øèáåð 0-255
	_delay_ms(20);
	VENT_PWM = 0; //ØÈÌ âåíòèëÿòîð 0-255
	}

	if (regim == 1){ //ðåæèì ðàáîòû 1
	LED1_ON;
	LED2_OFF;
	LED3_OFF;
	LED4_OFF;
	VENT_PWM = R1_VENT; //ØÈÌ âåíòèëÿòîð 0-255
	_delay_ms(20);
		if (tempint>40) { //áëîêèðîâêà ïî òåìïåðàòóðå
		SHIBER_PWM = 0; //ØÈÌ øèáåð 0-255
		}else{SHIBER_PWM = R1_SHIBER;} //ØÈÌ øèáåð 0-255
	}

	if (regim == 2){ //ðåæèì ðàáîòû 2
	LED1_OFF;
	LED2_ON;
	LED3_OFF;
	LED4_OFF;
	VENT_PWM = R2_VENT; //ØÈÌ âåíòèëÿòîð 0-255
	_delay_ms(20);
	if (tempint>60) { //áëîêèðîâêà ïî òåìïåðàòóðå
		SHIBER_PWM = 0; //ØÈÌ øèáåð 0-255
		}else{SHIBER_PWM = R2_SHIBER;} //ØÈÌ øèáåð 0-255
	}

	if (regim == 3){ //ðåæèì ðàáîòû 3
	LED1_OFF;
	LED2_OFF;
	LED3_ON;
	LED4_OFF;
	VENT_PWM = R3_VENT; //ØÈÌ âåíòèëÿòîð 0-255
	_delay_ms(20);
	if (tempint>80) { //áëîêèðîâêà ïî òåìïåðàòóðå
	SHIBER_PWM = 0; //ØÈÌ øèáåð 0-255
	}else{SHIBER_PWM = R3_SHIBER;} //ØÈÌ øèáåð 0-255
	}
}
}else{
SHIBER_PWM = 0;
_delay_ms(20);
VENT_PWM = 0;
}

	
	if(set != 0){settings();} //âõîä â íàñòðîéêè
} 

	return 0;
}


 

Ссылка на комментарий
Поделиться на другие сайты

Только что, balistik сказал:

 Т.к. работу с еепром он тоже нормально не может симулировать.

это золотым рукам обычно всегда что то мешает.

 

Ссылка на комментарий
Поделиться на другие сайты

В 23.08.2017 в 19:56, Alexeyslav сказал:

DS18B20

работу с ним нужно разбить на две операции: сначала быстро плюнуть в него командой на замер темепературы и уйти дальше дела делать, а потом, смустя сколько то там времени (есно без этой delay) послать ему команду, получить данные. Все в главном цикле. Все очень быстро и совершенно не  тормозит и не нагружает. Никаких прерываний, кроме инкрементирования системного счетчика времени.

ps.

вобще использовать delay можно только в загрузочном куске main, до главного цикла. В цикле delay только при отладке или совсем уж калечных девайсах....

Изменено пользователем dasZebra
Ссылка на комментарий
Поделиться на другие сайты

7 минут назад, dasZebra сказал:

сначала быстро плюнуть в него командой на замер темепературы и уйти дальше дела делать

6 минут назад, dasZebra сказал:

Все очень быстро и совершенно не  тормозит и не нагружает.

бабушке расскажешь...  команда "замер температуры" длится минимум 10мс = критический участок= запрет прерываний= ошибка системного таймера +/-10мс

 

 

Ссылка на комментарий
Поделиться на другие сайты

20 часов назад, IMXO сказал:

его как раз и следует опрашивать в прерывании по одному байту , только уж точно не библиотеками

Вы предлагаете вариант, требующий неслабых навыков в программировании, и говорите так, будто лучше этого варианта и быть не может. Я не согласен. Проще, чем опрашивать датчик в основном цикле при помощи уже готовой библиотечки, ничего не придумать. Всего -навсего надо убедиться, что в начале тайм-слота чтения и записи на 17-65 мкс запрещаются прерывания (в нормальной библиотечке это должно быть уже сделано).

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Цитата

"замер температуры" длится минимум 10мс

Это где такие сказки рассказывают? Длится-то оно длится, но процесс происходит внутри термометра и на контроллер никак не влияет - пока выполняется команда измерения температуры контроллер может заниматься своими делами, а потом просто прочитать значение хоть через две минуты. Надо только обеспечить термометру минимальное время на измерение(чем больше точность тем дольше) перед тем как давать любую команду, в т.ч. и на чтение иначе процесс будет прерван.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Цитата

говорите так, будто лучше этого варианта и быть не может.

Лучше варианта и не может быть. Но... не всем под силу. Всякие там библиотеки, будь даже трижды проверенные, содержат в себе целые поля граблей на которые наступаешь в тех или иных условиях. Но увы... вечные компромиссы между временем разработки и качеством кода.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Alexeyslav сказал:

Это где такие сказки рассказывают?

не поверишь в даташите....

мастер для команды "конвертирование температуры"

передает сброс 480мкс + пауза 1-20мкс , ответ слейва 480мкс+пауза 1-20мкс итого грубо 1мс...

далее 64бита индификационого кода + 8 бит команды , итого 72бита по 125мкс = 9мс

общие время передачи команды 10мс, фирштейн?

а время конвертирования это из другой оперы и составляет для 12бит 750мс...

5 часов назад, ARV сказал:

Всего -навсего надо убедиться, что в начале тайм-слота чтения и записи на 17-65 мкс запрещаются прерывания (в нормальной библиотечке это должно быть уже сделано).

вот именно что в библиотеке запрет идет на все время передачи команды, те от 10мс = сбой системного таймера, даже если речь о 65мкс для системного тика 10-20мс это уже много, о сигнале  сброс и сигнале присутствие вообще молчу ...

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, IMXO сказал:

мастер для команды "конвертирование температуры"

передает сброс 480мкс + пауза 1-20мкс , ответ слейва 480мкс+пауза 1-20мкс итого грубо 1мс...

далее 64бита индификационого кода + 8 бит команды , итого 72бита по 125мкс = 9мс

общие время передачи команды 10мс, фирштейн?

Ja, Sie kann deutsch sprechen? Das ist prima!  Aber muss ich Sie ein mal traurich machen. Sie sind mehr denken oder überlegen. Diese Zeit ist für uns überhaupt nicht wichtig. Die Hauptsache ist, das Intervall zwischen die erste und zweite Order. 

Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, IMXO сказал:

вот именно что в библиотеке запрет идет на все время передачи команды, те от 10мс = сбой системного таймера, даже если речь о 65мкс для системного тика 10-20мс это уже много, о сигнале  сброс и сигнале присутствие вообще молчу

Что такое 10 мс? Вроде как преобразование в худшем случае длится от 750 мс, тайм-слот длится не более 120 мкс, что такое 10 мс - не могу понять... А вообще, я вам уже говорил: в нормальной библиотеке запрет прерываний при реализации протокола 1-wire длится где-то от 17 до 65 мкс (в разных случаях по-разному), и разговор о всяких "системных тиках" это уже не по теме (или вы имеете ввиду какую-то ОС для AVR?!). Что касается импульсов RESET и PRESENCE, то для них вообще не требуется запрещать прерывания, т.к. допуски на их длительность достаточно большие по меркам быстродействия МК.

По поводу кривых библиотек я в курсе, но выпрямить их, сделав запрет прерываний только в нужных местах, гораздо проще, чем реализовать побитный прием данных из сети 1-wire по прерываниям таймера...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

В случае одного датчика на шине передавать идентификационый код не нужно, только команду начала преобразования.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...