Страница 1 из 2

АЦП в ATTINY13 настройка

Добавлено: Пн фев 25, 2013 17:07:03
Dr. Alex
Помогите пожалуйста разобраться с АЦП. Никак не пойму что надо настроить и как результат забрать............ ХЕЛП!...... Запутался конкретно....
Растолкуйте мне, как говорил мой наставник, на сковородках))))) Пишу на AVRStudio 4

Re: АЦП в ATTINY13 настройка

Добавлено: Пн фев 25, 2013 17:13:54
blackx
А это читали?

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 17:21:32
rus084
а сколько ацп у attiny13 ?
Нужно 1 и частотой 1гц , и 2 с частотой 10гц . Больше частоты необязательно .

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 18:33:07
blackx
У тини13 один четырехканальный 10-битный АЦП с максимальным временем преобразования 260 мкс.

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 20:38:46
rus084
а как понять 4 канальный?

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 20:48:25
axillent
rus084 писал(а):а как понять 4 канальный?..
значит, что можно использовать четыре входа для преобразований аналогового сигнала в цифру

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 21:47:09
rus084
в 1 кб флеш памяти влезет прошивка эбу ?

Re: АЦП в ATTINY13 настройка

Добавлено: Вт июн 18, 2013 22:44:02
blackx
А вы проверьте.

Re: АЦП в ATTINY13 настройка

Добавлено: Ср июн 19, 2013 10:07:58
rus084
а что происходит с мк присподаче сигнала сброса? это тоже самое что выключить и включить питание ?
за сколько времени при сбросе мк , порты конфигурируются?
а то у меня идея как съэкономить немножко памяти : по сигналу от зажигания подавать сброс на мк , после впрыска переходить в спящий режим до следущего сброса .
но в таком случае нельзя сделать програмно эпхх и еще несколько проблем .
тогда что лучше : сделать преобразователь частота-напряжение (понятно ) и подавать на оставшийся неиспользованным канал ацп ; или програмно высчитывать частоту , есть несколько способов : неиспользовать сброс и считать как у всех эбу или еще способ :
искра дается 1 раз за оборот , а у 4т мотора топливо засасывается раз за 2 оборота ; значит делать сброс через делитель частоты на2 (тм2) ; по первому сбросу мк включается а когда идет следущий импульс , мк считает прошедшее время и вычисляет сколько впрыскивать .
какой способ лучше?

Re: АЦП в ATTINY13 настройка

Добавлено: Ср июн 19, 2013 10:38:53
ploop
а что происходит с мк присподаче сигнала сброса?
Описано в даташите
это тоже самое что выключить и включить питание ?
Нет
за сколько времени при сбросе мк , порты конфигурируются?
Они сами не конфигурируются. Сконфигурировать их должны вы, а там, соответственно, будете знать время.
а то у меня идея как съэкономить немножко памяти : по сигналу от зажигания подавать сброс на мк
Плохая идея. И память так не сэкономите.

Вообще не пойму, мы в начале 90х живём и zx-спектрум - суперкомпьютер? Если не хватает ресурсов - возьмите МК пожирнее. Они сейчас в пять раз дешевле бутылки пива.

Re: АЦП в ATTINY13 настройка

Добавлено: Пт янв 03, 2014 08:09:51
ak-47m
Доброе время суток.
Есть ли у кого нибудь рабочий проект АЦП ATTINY13 для gcc ???
Если можно дайте исходники.
Уж сильно хочется разобратца с этим АЦП.

Re: АЦП в ATTINY13 настройка

Добавлено: Пт янв 03, 2014 09:55:50
pyzhman
Такое, надеюсь, подойдет:

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

//
//
//
#include <avr/io.h>
#include <avr/interrupt.h>  //Для доступа к функции sei()
#include <avr/signal.h>     //Для доступа к макросу INTERRUPT

ISR (ADC_vect) //Обработчик прерывания от интегрированного АЦП
{
unsigned int ADCdata;  //Буферная переменная для. хранения
ADCdata = ADCW;        	//результата преобразования
if (ADCdata > (2046 / 5)) PORTB = 1; //Если U > 2 В
else if (ADCdata < (1023 / 5)) PORTB = 4; //Если U < 1 В
else PORTB = 2;  //Если U = 1..2 В
ADCSRA = ADCSRA | 0x40; //Устанавливаем разряд ADSC в регистре ADCSR, чтобы начать новое преобразование 
}
 
int main (void) 
{
DDRB = 7;		//Три младших разряда порта B - выходы  
ADMUX = 3; 		//Назначаем в качестве аналогового входа РBЗ ; 
ADCSRA = 0xCE; 	/* 0b11001110 - активизируем АЦП с коэффициентом деления 64, 
						разрешаем прерывание от АЦП и начинаем преобразование */  
sei();			//Общее разрешение прерываний
while(1) ; 	//Бесконечный цикл в ожидании прерывания от АЦП
}
Ни в железе, ни в протеусе не прогонял. Честно содрал в нэте и подрихтовал под тиньку13. :))

Re: АЦП в ATTINY13 настройка

Добавлено: Пт янв 03, 2014 17:13:54
ak-47m
опгромное спасибо

Re: АЦП в ATTINY13 настройка

Добавлено: Пт янв 03, 2014 17:28:35
pyzhman
Пожалуйста.

Re: АЦП в ATTINY13 настройка

Добавлено: Сб янв 04, 2014 10:55:43
axillent
Здесь мой рабочий проект http://radiokot.ru/lab/controller/66/
Ацп применен для измерения тока

Re: АЦП в ATTINY13 настройка

Добавлено: Вс янв 05, 2014 20:29:00
c2n
вроде все делаю по Евстифееву... но!
Не фурычит:(
Помогите провести операцию по трансплантации попы рук на место :)

Хочу АЦП запустить в режиме непрерывного преобразования... что бы в любой момент можно было бы достучаться до регистра ADCH... и получить с него показания....

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

//========Разрешения прерываний АЦП микроконтроллера======
	ADCSRA = ADCSRA|(1<<ADEN)|(1<<ADATE); //Установил разрешение на работу АЦП,подключил автозапуск.
	ADCSRA = ADCSRA|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0); //установка предделителя для задания частоты АЦП в пределах 100-200кГц, 1/64 FCPU.
	ADCSRB = ADCSRB|(1<<ACME); //Установил режим работы непрерывного преобразования.
	ADMUX = ADMUX|(1<<MUX1)|(1<<MUX0);//указал, какой у меня вход задействован в качестве АЦП.
	ADMUX = ADMUX&(~(1<<REFS0));// установка источника опорного напряжения = VCC
	ADMUX = ADMUX|(1<<ADLAR); // Результат преобразования сдвинут вправо. Результат можно читать из ADCH при этом в ADCL будут храниться в 7 и 8 бите младшие разряды преобразования, ими в нашем случае можно пренебречь.
	DIDR0 =  DIDR0|(1<<ADC3D); // отключение цифрового буфера от канала ADC3.
		ADCSRA = ADCSRA|(1<<ADIE); // разрешил прерывания по окончании 
	ADCSRA = ADCSRA|(1<<ADSC);//Запуск первого преобразования!!!
	//=======КОНЕЦ Разрешения прерываний АЦП микроконтроллера=
Но АЦП почему то не завелся :(

помогите в вопросе трансплантологии.

Или ... или мне надо самому ручками в прерывании ISR(ADC_vect) каждый раз требовать продолжения банкета???

НО оно в прерывание не попадает... :shock:

А трансплантолог нужен риальне.. ибо пример
http://radiokot.ru/forum/viewtopic.php? ... 9#p1877209
в этой же теме - работает :))))..
а я в 3,14чале(((

Re: АЦП в ATTINY13 настройка

Добавлено: Пн янв 06, 2014 15:53:36
Alkul
c2n писал(а):Но АЦП почему то не завелся
в этой же теме - работает ..
А где у Вас собственно код обработчика прерывания по завершению АЦП-преобразования?
И вообще, что-то я не увидел в Вашем коде команды sei, которая глобально разрешает прерывания.

Re: АЦП в ATTINY13 настройка

Добавлено: Пн янв 06, 2014 17:51:04
c2n
Alkul писал(а): код обработчика прерывания
я понял, что можно завести АЦП в режиме непрерывного преобразования.
соответственно результат можно получить практически всегда из регистра ADCH/ADCL.

код тут:
Спойлер

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

#define F_CPU 9600000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

ISR(ADC_vect)
{
//ADCSRA = ADCSRA | 0x40; //Устанавливаем разряд ADSC в регистре ADCSR, чтобы начать новое преобразование 
//Что с этой строкой, что без этой строки - дурь выходит в протеусе
}


int main(void)
{
	cli(); //Запретил прерывания, дабы не повадно было
	DDRB = 0b00111; //установил пол порта на вход, половину на выход
	PORTB = 0b00000; //вЫключил порт
	//========Разрешения прерываний АЦП микроконтроллера======
	ADCSRA = ADCSRA|(1<<ADEN)|(1<<ADATE); //Установил разрешение на работу АЦП,подключил автозапуск.
	ADCSRA = ADCSRA|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0); //установка предделителя для задания частоты АЦП в пределах 100-200кГц, 1/64 FCPU.
	ADCSRB = ADCSRB|(1<<ACME); //Установил режим работы непрерывного преобразования.
	ADMUX = ADMUX|(1<<MUX1)|(1<<MUX0);//указал, какой у меня вход задействован в качестве АЦП.
	ADMUX = ADMUX&(~(1<<REFS0));// установка источника опорного напряжения = VCC
	ADMUX = ADMUX|(1<<ADLAR); // Результат преобразования сдвинут вправо. Результат можно читать из ADCH при этом в ADCL будут храниться в 7 и 8 бите младшие разряды рпеобразования, ими в нашем случае можно пренебречь.
	DIDR0 =  DIDR0|(1<<ADC3D); // отключение цифрового буфера от канала ADC3.
//		ADCSRA = ADCSRA|(1<<ADIE); //Разрешение прерывания от АДЦ
//что с этой строкой, что без нее - дурь...
	ADCSRA = ADCSRA|(1<<ADSC);//Запуск первого преобразования!!!

//====кусок из примера на форуме=====
//	ADMUX = 3;       //Назначаем в качестве аналогового входа РBЗ ; Из примера
//	ADCSRA = 0xCE;    /* 0b11001110 - активизируем АЦП с коэффициентом деления 64, из примера*/
//====кусок из примера на форуме=====
	
	//=======КОНЕЦ Разрешения прерываний АЦП микроконтроллера=
	
	
	
	PORTB = (PORTB&0b111000); // обнулил младшие три бита порта.
	_delay_ms(100);
	
	sei(); //Разрешил прерывания
	
	while(1)
	{
		PORTB = ADCH;//(0^~Counter); //вывожу переменную с АЦП в порт.
		//в протеусе вообще ничего не происходит....на реальном железе непонятные поморгульки...

		
		
	}
}

Re: АЦП в ATTINY13 настройка

Добавлено: Пн янв 06, 2014 19:45:29
Alkul
c2n писал(а):соответственно результат можно получить практически всегда из регистра ADCH/ADCL.
Наверное, можно. Но правильнее было бы написать обработчик прерывания по завершению преобразования и брать данные уже там.

Дальше
Я пишу на ассемблере, а на Си программировал только для компьютеров, поэтому не очень хорошо знаком с Си-шными нотациями применительно к программированию для МК.
Но вот эта запись

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

PORTB = ADCH;//(0^~Counter); //вывожу переменную с АЦП в порт.

вызывает во мне смутные опасения. Допустимо ли так делать? Для надежности не лучше считывать данные в переменную, а уже её выводить в порт?
Но самое главное не в этом
Скажите, вы даташит читали?
Вот это там видели?
Изображение
Как так вы читаете только ADCH? Кто будет читать ADCL, который, к слову, даташит требует читать первым? Ибо там существует особая логика работы с этими регистрами. В даташите про все это написано.

Re: АЦП в ATTINY13 настройка

Добавлено: Пн янв 06, 2014 21:21:05
c2n
Разобрался поманешку.
Спойлер

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

#define F_CPU 9600000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>

volatile unsigned char Counter=1;//тупо счетчик
volatile unsigned char ResultADC = 0; //результат АЦП


char _74HC595(unsigned char varible)
{
	for (char i = 0; i<8; i++)
	{
		PORTB = PORTB&0b111000; //PB1 = SCK Set is 0;
		PORTB = PORTB|((varible>>i)&1); //PB0 = DS. Show bit? getting of shr on pos geting circular counter i.
		PORTB = PORTB|0b010; //PB1 is set 1.
	}
	PORTB = (PORTB&0b111000)|0b000100; //PB3 is SW.
}


ISR(ADC_vect)
{
	if ((ADCH>>1) != (ResultADC>>1)) // отбрасываю младший разряд и проверяю, есть ли изменения. Устранение "дребезга"
	{
		ResultADC = ADCH;
	}
}


int main(void)
{
	cli(); //Запретил прерывания, дабы не повадно было
	DDRB = 0b00111; //установил пол порта на вход, половину на выход
	PORTB = 0b00000; //вЫключил порт
	//========Разрешения прерываний АЦП микроконтроллера======
	ADCSRA = ADCSRA|(1<<ADEN)|(1<<ADATE); //Установил разрешение на работу АЦП,подключил автозапуск.
	ADCSRA = ADCSRA|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0); //установка предделителя для задания частоты АЦП в пределах 100-200кГц, 1/64 FCPU.
	ADCSRB = ADCSRB|(1<<ACME); //Установил режим работы непрерывного преобразования.
	ADMUX = ADMUX|(1<<MUX1)|(1<<MUX0);//указал, какой у меня вход задействован в качестве АЦП.
	ADMUX = ADMUX&(~(1<<REFS0));// установка источника опорного напряжения = VCC
	ADMUX = ADMUX|(1<<ADLAR); // Результат преобразования сдвинут вправо. Результат можно читать из ADCH при этом в ADCL будут храниться в 7 и 8 бите младшие разряды рпеобразования, ими в нашем случае можно пренебречь.
	DIDR0 =  DIDR0|(1<<ADC3D); // отключение цифрового буфера от канала ADC3.
	ADCSRB = (ADCSRB&0b11111000)|(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); //Установка источника сигнала для выполнения преобразования...000 - непрерывное преобразование.
	ADCSRA = ADCSRA|(1<<ADIE); //Разрешение прерывания от АДЦ
	ADCSRA = ADCSRA|(1<<ADSC);//Запуск первого преобразования!!!
	//=======КОНЕЦ Разрешения прерываний АЦП микроконтроллера=
	sei(); //Разрешил прерывания
	
	while(1)
	{
		_74HC595(ResultADC);//Вывожу до посинения результат преобразования АЦП....
	}
}
соответственно этот код выводит в сдвиговый регистр значение "без проблем".

По поводу чтения из регистров.
В ДШ и у Евстифеева сказано, что регистры ADCL и ADCH блокируются для записи, до тех пор, пока не будет прочитан ADCH.
соответственно у меня идет выравнивание влево, и 2 разряда я игнорирую.
В протеусе - работает :)

Изображение
сказано:
если результат притянут влево, и 8 бит точности достаточно, достаточно прочитать АДЦХ....

В моем случае, 8 бит мне за глаза :)))

У меня код заведен на непрерывное преобразование. Но! есть одно но! Если в обработчике прерывания ADC_vect ничего нет - протеус деятельность не иммитирует.
Возможно в реальном камне такая же фигня. Так что по окончании преобразования, я подтираю шумок.... и протеус моделит. Я с этими граблями натрахался за 2 дня. Реализую наверное так.

Думаю мой код поможет кому нибудь :)