двойное условие

Обсуждаем контроллеры компании Atmel.
Ответить
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

привет. не знаю как правильно это называется. хочу сделать детектор напряжения на attiny13. нашёл вот такой проект: http://thinkl33t.co.uk/r2-project-log-b ... r-circuit/ переписвыаю под себя. сейчас получилось - если ниже 3в - выдать 0. выше 3в - выдать 1. на входе будет стоять делитель из резисторов 10к и 3к так что 3,6в будут соответствовать 1005, а 3в - 837. вопрос: как реализовать такое условие: если напряжение меньше 3в - выдать на выход 0 и не выставлять 1 пока оно не поднимется выше 3,6в?
Спойлер

Код: Выделить всё

/*
 * GccApplication1.cpp
 *
 * Created: 11.10.2014 18:00:12
 *  Author: user
 */ 


#define F_CPU 10000000UL
#include <avr /io.h>
#include <util /delay.h>

// delay for up to 65k milliseconds
void delayms(uint16_t millis)
{
	// loop, delaying 1ms each iteration
	while ( millis )
	{
		_delay_ms(1);
		millis--;
	}
}

// initialise the adc
void init_adc ( void )
{
	//select internal (1.1) voltage as the reference voltage (x1xx xxxx)
	ADMUX = 0x40;
	//enable ADC (1000 0000)
	ADCSRA |= 0x80;
}

// read the specified adc
int adc_read ( uint8_t n )
{
	// set the adc to the chosen channel
	ADMUX = n;
	// start the ADC conversion, set the ADC clock to cpu clock / 16 (0100 0100)
	ADCSRA |= 0x44;
	// wait for the adc conversion to be completed
	while((ADCSRA & 0x40) !=0){};
	// return the adc result
	return ADC;
}

int main(void)
{
	// set PB3 to output
	DDRB |= 1< <PB3;
	// turn on the ADC
	init_adc();
	// set up our variables
	int reading = 0;
	// loop for ever
	while(1) {
		// take a new adc reading
		reading = adc_read(2);
		// if the voltage is less than 3
		if ( reading < 837 )
		{
			// turn the output pin off
			PORTB |= 1<<PB3; /* LED off */
		}
		else
			
		{
			// turn the output pin on
			PORTB &= ~(1< <PB3);
		}
		// wait for 20ms
		delayms(20);
	}
	return 0;
}
Реклама
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

Элементарно, Ватсон!

Код: Выделить всё

if (ADCW <=837) PORTx &= ~_BV(y);
if (ADCW >=1005) PORTx |= _BV(y);
Последний раз редактировалось Pink-Pank Сб окт 11, 2014 15:31:33, всего редактировалось 1 раз.
Fucking static initialization order fiasco
Контактная информация:
Реклама
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Ну например так

Код: Выделить всё

   int threshold = 837;
   while(1) {
      // take a new adc reading
      reading = adc_read(2);
      // if the voltage is less than 3
      if ( reading < threshold )
      {
         // turn the output pin off
         PORTB |= 1<<PB3; /* LED off */
         threshold = 1005; // не включим пока не будет 3,6В
      }
      else
      {
         // turn the output pin on
         PORTB &= ~(1< <PB3);
      }
      // wait for 20ms
      delayms(20);
   }
А если гистерезис нормальный делать, то как-то так

Код: Выделить всё

   int threshold = 921;
   while(1) {
      // take a new adc reading
      reading = adc_read(2);
      // if the voltage is less than 3
      if ( reading < threshold )
      {
         // turn the output pin off
         PORTB |= 1<<PB3; /* LED off */
         threshold = 1005; // не включим пока не будет 3,6В
      }
      else
      {
         // turn the output pin on
         PORTB &= ~(1< <PB3);
         threshold = 837; // не выключим пока не будет 3,0В
      }
      // wait for 20ms
      delayms(20);
   }
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

чё-то у меня atmelstudio ругается что avr /io.h: No such file or directory
Реклама
Эиком - электронные компоненты и радиодетали
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Пробел лишний
Реклама
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

ks0 да и без пробела тоже =) я же когда пишу avr он открывает папку прям в этом месте и можно файл выбрать... я выбираю, он сам подставляет io.h. а при компилировании ругается что его нет О_о как так

наверное потому что я выбрал проект с++, а надо было с =)
Реклама
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

всем спасибо

ks0 и не работает =) отключается на 2,7 (ну это внутренний источник неточный, надо значения подгонять), но и включается на 2,7. использовал последний код. причём отключается на 2,7 даже если на вход ничего не подаёшь О_о так что скорее всего это bod срабатывает
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

вообще не работает :( до 1,7в садится, потом контроллер видимо просто отрубается. помогите пожалуйста =)
Спойлер

Код: Выделить всё

/*
 * GccApplication1.cpp
 *
 * Created: 11.10.2014 18:00:12
 *  Author: user
 */ 


#define F_CPU 10000000UL
#include <avr/io.h>
#include <util/delay.h>

// delay for up to 65k milliseconds
void delayms(uint16_t millis)
{
	// loop, delaying 1ms each iteration
	while ( millis )
	{
		_delay_ms(1);
		millis--;
	}
}

// initialise the adc
void init_adc ( void )
{
	//select internal (1.1) voltage as the reference voltage (x1xx xxxx)
	ADMUX = 0x40;
	//enable ADC (1000 0000)
	ADCSRA |= 0x80;
}

// read the specified adc
int adc_read ( uint8_t n )
{
	// set the adc to the chosen channel
	ADMUX = n;
	// start the ADC conversion, set the ADC clock to cpu clock / 16 (0100 0100)
	ADCSRA |= 0x44;
	// wait for the adc conversion to be completed
	while((ADCSRA & 0x40) !=0){};
	// return the adc result
	return ADC;
}

int main(void)
{
	// set PB3 to output
	DDRB |= 1<<PB3;
	// turn on the ADC
	init_adc();
	// set up our variables
	int reading = 0;
	int threshold = 921;
	// loop for ever
	
	while(1) {
		// take a new adc reading
		reading = adc_read(2);
		// if the voltage is less than 3
		if ( reading < threshold )
		{
			// turn the output pin off
			PORTB |= 1<<PB3; /* LED off */
			threshold = 1005; // не включим пока не будет 3,6В
		}
		else
		{
			// turn the output pin on
			PORTB &= ~(1<<PB3);
			threshold = 837; // не выключим пока не будет 3,0В
		}
		// wait for 20ms
		delayms(20);
	}
	return 0;
}
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Вот здесь вы Voltage Reference сбрасываете на VCC
shinji2009 писал(а):

Код: Выделить всё

	// set the adc to the chosen channel
	ADMUX = n;
Должно быть ADMUX = 0x40+n;
Вообще лучше писать не цифрами, а константами
ADMUX = (1<<REFS0)+n;
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

ks0
но если я поменяю на ADMUX = 0x40+n; то заработает? я вообще не рублю в С. я немного понимаю что означает, но сам писать не могу =)
Электрический кот
Аватара пользователя
Сообщения: 1058
Зарегистрирован: Ср мар 17, 2010 18:19:09
Откуда: новосибирск

Сообщение shinji2009 »

всё равно не работает :( помогите
Ответить

Вернуться в «AVR»