усреднение двухполярного значения ADC

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

Сообщение sad-angel »

Есть 6-битный АЦП,опорное напряжения 2.5В. АЦП двухполярний,тоесть 2.5В - 0 значение, -2.5в -(- 32) и 2.5 значение 32. Измеряеться напряжение источника питания. Мне нужно устреднять значение ацп,но не знаю как правильно сделать.
datasheet for ADC: http://www.cypress.com/?docID=40538 Среда разработки PSoC Disigner 5.3

Сделал так:

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


input_voltage = SAR6_VIN_cGetSample(); //return 6 bit number - signed from PORT		
				
input_voltage = averaging_voltage(input_voltage);

char averaging_voltage( char voltage)
{
	static  char voltage_buffer[16];
	char avv; //averaging voltage
	int sum;
	
	static unsigned char index = 0 ;
	static unsigned char counter = 0 ;
	
	unsigned char i;
	  
	voltage_buffer[index] = voltage;
	index++;
	index &= 0x0F; 
	
	for (i = 0; i < 16; i++)
	{
		if ((voltage_buffer[i] & 0x80) == 0x80)
		{
			sum -= ~voltage_buffer[i]+1;
		}
		else
		{		
			sum += voltage_buffer[i];
		}	
	}
		
	avv =(char)sum >> 4; //16
	
	avv = voltage;
	
	return avv;		
}
но правильно не работает :? что я делаю не так?
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Ммм... Что ты понимаешь под "усреднить"? Какой вид имеет входной сигнал?
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

Сообщение sad-angel »

Входной сигнал постоянное напряжение с блока питания светодиодов. Под усреднением понимаю Uc = (U1+U2+...+Un)/n
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

Если я правильно понял, то так.

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

#include <stdio.h>

char SAR6_VIN_cGetSample()
{
	char a=0xE0;
	a&= ~(0xC0);// -32 в формате 6 бит знак минуса привязан к 6 биту
	return a; //-32

	//return 0x1F;//31
	/*
	Максимальное положительное число равно 31 0x1F
	Минимальное число равно -32 в формате 6 бит равно 0x20 в формате 8 бит 0xE0
	*/
}

__int8 averaging_voltage(unsigned __int16 average)
{
	int a=0;
	for(unsigned __int16 i=0;i<average;i++)
	{
		__int8 adop=(__int8)SAR6_VIN_cGetSample();
		if(adop&(1<<5)) //проверка на наличие 6 бита  (минуса)
		{
			adop |= 0xC0; 
			a+=adop;
		}
		else
		{
			a+=adop;
		}
		
		//TIME
	}
	return (__int8)(a/(int)average);
}

int main()
{
	__int8 a;
	a=31;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);
	a=0;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);
	a=-32;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);

	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)SAR6_VIN_cGetSample(),SAR6_VIN_cGetSample());

	printf("average=%i\n",averaging_voltage(1000));
	getchar();
	
	return 0;
}
/*
HEX=1f DEX=31
HEX=00 DEX=0
HEX=e0 DEX=-32
HEX=20 DEX=32
average=-32
*/
Последний раз редактировалось xVekx Вт ноя 27, 2012 02:40:21, всего редактировалось 1 раз.
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

Сообщение sad-angel »

xVekx писал(а):Если я правильно понял, то так.

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

#include <stdio.h>

char SAR6_VIN_cGetSample()
{
	return 0xE0; //-32
	//return 0x20;
}

__int8 averaging_voltage(unsigned __int16 average)
{
	int a=0;
	for(unsigned __int16 i=0;i<average;i++)
	{
		a+=(__int8)SAR6_VIN_cGetSample();
		//TIME
	}
	return (__int8)(a/(int)average);
}

int main()
{
	__int8 a;
	a=32;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);
	a=0;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);
	a=-32;
	printf("HEX=%.2x DEX=%i\n",(unsigned __int8)a,a);

Не	printf("average=%i\n",averaging_voltage(1000));
	getchar();
	
	return 0;
}
/*
HEX=20 DEX=32
HEX=00 DEX=0
HEX=e0 DEX=-32
average=-32
*/



Спасибо!!! Но я не уверен в правильной работе функции усреднения если будут несколько значений с разним знаком например +3,+2,+1,-1,-2,0
Реклама
Встал на лапы
Сообщения: 125
Зарегистрирован: Вс мар 01, 2009 20:41:19

Сообщение xVekx »

Вспомнил что тут на 6 бите минус, поправил код :facepalm: .
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

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

int8_t get_sample();

// Первый вариант (простое арифметическе среднее).
int8_t get_average()
{
	int16_t acc;
	uint8_t i;
	
	for (acc = 0, i = 0; i < 16; i++)
	{
		acc += get_sample();
	}
		
	// Если кол-во выборок равно степени 2, то можно заменить на это
	// (если сдвиг вправо реализован как арифметический).
	// return (acc + 8) >> 4;
	return (acc + 8) / 16;
}

// Второй вариант (движущееся арифметическе среднее).
int8_t get_average(int8_t value)
{
	static uint8_t i = 0;	
	static int16_t acc = 0;
	static int8_t sample[16] = {0};
	
	acc -= sample[i];
	acc += value;
	sample[i] = value;
			
	
	// Если кол-во выборок равно степени 2, то можно заменить на это.
	// i = i + 1 & 15;
	if (++i >= 16)
		i = 0;
		
	// Если кол-во выборок равно степени 2, то можно заменить на это
	// (если сдвиг вправо реализован как арифметический).
	// return (acc + 8) >> 4;
	return (acc + 8) / 16;
}
Как-то так, если ничего не напутал.
Встал на лапы
Аватара пользователя
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

Сообщение sad-angel »

xVekx писал(а):Вспомнил что тут на 6 бите минус, поправил код :facepalm: .

в даташите написано что минус - 7 бит: http://www.cypress.com/?docID=40538 Но совсем не ясно в каком коде отрицательное напряжение - прямом,обратном или дополнительном... :?
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

CHAR SAR6_cGetSample(void)
Description:
Performs a conversion, returning a 2’s complement value representing the ratio of the input voltage
to the reference voltage, both relative to analog ground.

Смотри внимательнее. Скопировал из указанного тобой даташита.
Ответить

Вернуться в «Разные вопросы по МК»