• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
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;
}


 

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


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
Alexeyslav    590

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

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


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

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099
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 099
Только что, balistik сказал:

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

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

 

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


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

DS18B20

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

ps.

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

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

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


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

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

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

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

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

 

 

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


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

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

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

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


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

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

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

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


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

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

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

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


Ссылка на сообщение
Поделиться на других сайтах
IMXO    1 099
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    30
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    262
10 часов назад, IMXO сказал:

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

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

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

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


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

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

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


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

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

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


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

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

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

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

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

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

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

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

Загрузка...

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

    • Автор: dissonance96
      Доброго времени суток.
      Имеется:
      1. RGB LED лента 12 метров, 11,4вт/м.
      2.Импульсный блок питания JC12-240-12. Входное напряжение 170-240В, выходное 10-15В (регулируется), 20А.
      3. китайский LED - контроллер, собранный на ШИМ регуляторе LM2576S - 3.3. Управление осуществляется через приложение, подключение - по WiFi.
      При подключении ленты через контроллер - блок питания начинает сильно пищать и заметно нагреваться. Если снизить яркость - писк становится тише.  Залил дроссель эпоксидкой - не помогло.
      Помимо дросселя в БП установлены трансформатор и две катушки индуктивности. Кажется, этот ансамбль и издает этот противный писк.
      Пробовал добавить на выход БП керамические конденсаторы разной емкости (47 пФ, 47 нФ, 10пФ и т.д.) - не дало никакого результата. 
      Как я понимаю это проблема возникает именно из-за ШИМ модуляции. и частота с которой пищит БП и есть частота работы ШИМ.  Если подключать ленту напрямую - никакого писка нет. без нагрузки БП также ведет себя тихо.
       
      Подскажите, как проще всего избавиться от этого писка?
    • Автор: Petro Pigovskiy
      Здраствуйте. Мне нужен шим регулятор на полуавтомат , двигатель подачи проволоки напряжение 80v 1.5А 30W. Может кто подскажет какую то несложную схему. Буду очень благадарен.
    • Автор: Velmatoff
      Помогите собрать схему
      Преобразователь код-ШИМ. 
      На входе 2-х разрядный код, который определяет коэффициент заполнения по следующему правилу:
      00 0%
      01 33%
      10 66%
      11 100%
       
      Сделал делитель частоты на 3 на основе двух D-триггеров, но не могу додуматься, как проссумировать сигналы...
       

    • Автор: MikadoTerri
      помогите, делаю этот таймер http://sxem.org/2-vse-stati/22-tajmery/38-tajmer-na-atmega8 и он идет очень медленно, одна секунда равняется 3,5 минутам, как это исправить
       
    • Автор: east1095
      Здравствуйте, давно читаю форум, зарегистрировался только сегодня, хочу попросить советов у вас для очередной работы.
       
      1. Мощность 30 кВт, напряжение 2 кВт, 15 А ток.
      2. Планирую полумост;
      вопросы:
      1. Шим контроллер должен поддерживать регулировку к.заполнения, с заданным dU/dT, это планирую делать с МК, потому что в случае пробоя быстроействуюий ключ даст сигнал об остановке преобразователя, потом будет строб, потом пуск источника, при этом он должен выйти на напряжение на котором произошла остановка работы с более коротким (быстрее) dU/dT, это можно реализовать с МК, завести сигнал с датчика КЗ.
      При этом нужна регулировка напряжение и регулировка уставки максимального тока(в приципе в схеме защиты от КЗ она уже реализована)
       
      2. Полумоста хватит на такую мощность?
      3. Можно ли с помощью софта рассчитать трансформатор на такие характеристики? Lite_calcIT не осилил такую задачу.
      4. 1 трансформатор или набор модулей соединенных последовательно для обеспечения нужного напряжения?
      5. Ткните носом в краткую но понятную ветку/статью о резонансных и квазирезонансных и других типах схем, т.к. я недостаточно в этом подкован, немного другие интересы, однако.
       
      Заранее спасибо!