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    575

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

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


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

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

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

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


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

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

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

 

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


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

DS18B20

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

ps.

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

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

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


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

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

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

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

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

 

 

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


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

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

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

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


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

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

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

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


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

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

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

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


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

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

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

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

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


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

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

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


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

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

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


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

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

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

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

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

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

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

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

Загрузка...

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

    • Автор: TIGER53501
      Привет, никак не могу разобраться с таймером в режиме сброса по внешнему событию,
      сам сброс работает, таймер сбрасывается, вопрос вот в чём, могу ли я в этом режиме использовать захват на оставшихся каналах?
      т.е. по внешнему событию сбрасывать таймер, и потом внешними событиями записывать сколько он протикал с момента сброса?
      STM32F429ZI
      СИ + VisualGDB + HAL + Cube
    • Гость controller86
      Автор: Гость controller86
      Доброго времени суток!
      Подскажи, будьте любезны. Посоветуйте шим контроллер на подобии sg3525, чуть по-проще и только с одним выходом, желательно в корпусе на 8 пин.
       
    • Автор: Zabar31
       
      Всех приветствую! Вообщем ситуация такая - (сейчас будет предыстория) стал понемногу интересоваться МК и набрел на статью о подключении экрана нокии 3310 к атмеге8. Вот она http://cxem.net/mc/mc201.php  Сказать что заинтриговало - ничего не сказать... к тому же автор в комментариях написал, что можно поочередно выводить изображения, и таким образом создать анимацию. Так вот, к чему я, была у меня монохромная моторолла и на ней был прикольный "скринсейвер" с рыбками, теперь который я хочу воссоздать. Надписей "Hello, world!" я не планирую, а только чистый вывод изображений.
      Теперь сама суть моего обращения на форум.
      1) Так как в Bascom я начинающий, решил идти по пути наименьшего сопротивления, то есть немного подправив код в проэкте, предоставленный автором статьи. Подправить то я его подправил, но вот правильно ли... Вообщем мне бы хотелось чтобы знающие люди проверили бы мой код. Хотя Bascom компилирует код без проблем.
      Вот исходный код:
      Вот мой код: (на одинаковость стека изображений не обращайте внимания, мои в процессе воссоздания, а мне нужна проверка самого принципа вывода изображений, который я написал)
      Таким образом я хочу выводить изображения поочередно с интервалом в 1 секунду.
      2)Еще более интересующий меня вопрос - если открыть даташит на атмега8, то там написано, что флеш памяти для программ 8 кб. Но вот что интересно и вводит меня в ступор. Если просто взять проэкт автора статьи и скомпилировать его в .hex, то получаем: Bascom пишет при компиляции "Flash used - 55%", то есть как бы половина атмеги пустая, но вот выходной файл .hex имеет размер 13кб. Вот я и не могу понять как даже авторский проэкт в 13кб прошивается в атмегу с 8кб? Магия наверное. Скомпилировав "свой" проэкт, я получаю  "Flash used - 66%" и файл на 15кб. Вот и возник такой вопрос - это нормально и так и должно быть? А если нет - то как правильно скомпилировать?
      Так как пока проверить код в железе нет возможности (еще едет), вот к Вам, знающим людям, за помощью и обращаюсь. Ниже прикрепляю видеофайл с  компиляцией проэкта автора статьи в Bascom.
       clip0002.avi
       
    • Автор: iv_h
      Добрый день
      Имеется мощный симистор ТС (вроде ТС122-25, на 40 А). С помощью него предполагается управлять мощным ТЭНом.
      В качестве регулятора будет Ардуина. Т.к. симистор коммутируется хорошим током и напряжением 220 В, то использую промежуточное звено - твердотельное реле на 2 А (вот такое: http://wiki.iarduino.ru/page/tverdotelnoe-rele-trema-modul/).
      Для предварительной проверки собрал простую схему, в которой управляю лампой накаливания. Скважность ШИМ формируется в зависимости от положения подключенного потенциометра.
      Собрал, запрограммировал. Все работает, но лампа офигенно мерцает (не мерцает только при нуле и при максимуме, что ожидаемо). Вот так примерно все это выглядит на видео: https://yadi.sk/i/6yF2iGSb3Lb66c)
      ШИМ Ардуины работает на 500 Гц. 
      Вопросы:
      1) Как я понимаю, проблема в том, что симистор открывается в нуле, а ШИМ сигнал не синхронизирован с переходом через ноль. Из-за этого выпадает часть импульсов.
      Есть ли какое-то простое решение этого вопроса в рамках существующей схемы?
      2) Правильно ли я понимаю, что такое "мерцание" при управлении ТЭНом совершенно безвредно для ТЭНа и продолжительности его жизни?
      3) Может ли быть проблема в том, что твердотельное реле не справляется с частотой или проблема полностью относится к п.1?
      Заранее спасибо!
       
       
  • Сообщения

    • усилитель с платкой 1557 пришлось впаять в дохлую китайскую автомагнитолку В продаже Цена новая 900р,пересылка по России моя
    • Любопытное устройство. Но скорее это не балласт, а все-таки электронный трансформатор. Судя по диодам мостика, транзисторам и силовому трансформатору на 250-300Вт потянет. Похоже есть и защита, но не гарантирую - радиаторы заслоняют обзор. Если умеете, срисуйте схему, если нет, пришлите более четкие фото с обоих сторон.
    • Подскажите пожалуйста не сложную схему, что бы  она потребляла минимум  тока  в режиме бездействия. Время задержки на отключение можно не регулируемое- от 30 мин. до 2-х-3-х часов. Разброс времени выдержки в зависимости от перепада температур и прочих факторов- не важен. Емкость- размером не более 50 миллилитров  Цель- что-бы автомагнитола временно продолжала работать и дальше на проводе +12в  от аккумулятора, после отключения питания + 12 на проводе ААС  замком зажигания. По истечении выдержки  заданного времени, ток потребляемый схемой, желательно  до 5-10 мА, что бы не  разряжал аккумулятор при многодневных стоянках автомобиля.   Для справки-  в магнитоле предусмотрено подключение 2-х проводов питания :    тонкий +12в от замка зажигания (ААС)  и толстый +12в  напрямую от аккум. При  отключении питания ААС,  магнитола автоматически  выключается, ток потребления составляет - 6 мА. ,при этом +12 от аккум. не отключается.  При  подачи питания ААС,  ток потребляемый магнитолой увеличивается до - 60мА и только после этого можно  вкл. магнитолу и только вручную.
    • Малый тор крепление обфранцузь как нибудь. В глаз бьет
    • Ты че? Какие каскады,тут прямо к внятному специалисту. Вместе с главной микросхемой
    • - Вам нужно поменять материал, как минимум болтов и гаек. Наверное, тоже нержавейку. Т.к. она с "обьічньім" железом (сталью, цинком) образует пару, как медь-алюминий. Гуглите "Электрохимические пары и контакты между ними" или "Недопустимые гальванические пары".
    • Там вообще ОУ не используются. Нарисуйте свою схему с указанием номиналов и качественные фото монтажа покажите. И скажите что вы ждёте от этого усилителя? Нагрузка какая у него?