balistik

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

18 сообщений в этой теме

balistik    0

Всем доброго времени суток. Я реальный нуб в 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;
}


 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alexeyslav    628

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 276
В 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;} }

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    377

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 276
12 минуты назад, ARV сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
balistik    0

Спасибо. Отказался от цифрового датчика. Перешел на аналоговый 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;
}


 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 276
Только что, balistik сказал:

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

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
dasZebra    29
В 23.08.2017 в 19:56, Alexeyslav сказал:

DS18B20

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

ps.

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

Изменено пользователем dasZebra

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 276
7 минут назад, dasZebra сказал:

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

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

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

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    377
20 часов назад, IMXO сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alexeyslav    628
Цитата

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alexeyslav    628
Цитата

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 276
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мс это уже много, о сигнале  сброс и сигнале присутствие вообще молчу ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
dasZebra    29
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. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    377
10 часов назад, IMXO сказал:

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Alexeyslav    628

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
balistik    0

Всем спасибо. Построил прототип, все заработало на нем без проблем. Даже дисплей по i2c подключил еще.

Поделиться сообщением


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

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

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

  Разрешено не более 75 смайлов.

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

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

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

Загрузка...

  • Похожие публикации

    • Автор: DimonRX
      Всем доброго времени суток!
      В AVR-ках я новичёк и очень нуждаюсь в вашей помощи.
      Задача у меня следующая. Есть драйвер управления серводвигателем на ATmega88. Помимо основной задачи ATmega88 через 74HC164D выводит на сдвоенный 7-ми сегментный индикатор направление вращения мотора в виде анимации (вращает сегмент по или против часовой стрелки). Рядом есть некая поделка на ATmega8, одной из задач которой является определение направления вращения мотора и, в зависимости от направления, выполнение различных действий. Как мне это сделать? Как подружить две меги? Всем заранее спасибо.
    • Автор: 12312313
      Добрые люди. Собрал данную схему. В протеусе все нормально работает. А вот когда прошиваю мк не работает. Принцип такой : если на первом входе компаратора сигнал больше второго то загорается первый если наоборот то второй. Где ошибка? Заранее благодарю

    • Автор: Melandr
      Добрый день, уважаемые форумчане. Подскажите по такому вопросу. Есть девайс, управляет автоматикой гелиосистемы (4 датчика DS1820, два насоса, индикация на семисегментном индикаторе). В первой реализации был установлен микроконтроллерATtiny2313, но памяти уже не хватало. чтобы не переделывать плату, было принято решение заменить микроконтроллер на ATtiny4313. Но возникла одна проблема. Так как девайс уже установлен на объекте, все изменения нужно как-то проверить, а уже потом на месте прошивать. Но для проверки прошивки в Proteus модели ATtiny4313 нет, поэтому есть мысль сделать директивы условной компиляции, допустим в начале выбор целевого микроконтроллера и дефайны по используемым регистрам. Чтобы изменением одной строчки можно было компилировать либо под ATmega8 либо под ATtiny4313. Как добавить в Proteus больше памяти на основе ATtiny2313 не знаю. Если можно какой-то простой пример, чтобы на его основе сделать условную компиляцию.
    • Автор: gsclock
      Всем привет!
      Пишу диплом, на тему импульсных источников питания. Один из разделов это анализ вариантов преобразования напряжения для питания систем управления электроприводом.
      Необходимо рассмотреть три варианта преобразований:
      1. Преобразование AC/DC 220/15V, затем 15V в 5V(DC) 
      2. Преобразование AC/DC 220/5V, затем  5V в 15V (DC)
      3. Использование импульсного источника питания с различным выходным напряжением.
      Определить какой вариант преобразований эффективней в использовании, и как влияет паразитная емкостная связь.
      Подскажите пожалуйста какие-нибудь книги или статьи,автора по этим темам.
      Сам я нашел какую-то информацию, но ее очень мало, а книгу всего одну "Импульсные источники питания от А до Z" Санджай М.
      Благодарю.