Страница 1 из 1
усреднение двухполярного значения ADC
Добавлено: Пн ноя 26, 2012 13:50:28
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;
}
но правильно не работает

что я делаю не так?
Re: усреднение двухполярного значения ADC
Добавлено: Пн ноя 26, 2012 16:06:50
menzoda
Ммм... Что ты понимаешь под "усреднить"? Какой вид имеет входной сигнал?
Re: усреднение двухполярного значения ADC
Добавлено: Пн ноя 26, 2012 17:02:02
sad-angel
Входной сигнал постоянное напряжение с блока питания светодиодов. Под усреднением понимаю Uc = (U1+U2+...+Un)/n
Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 00:59:58
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
*/
Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 01:41:21
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
Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 02:42:44
xVekx
Вспомнил что тут на 6 бите минус, поправил код

.
Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 09:24:19
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;
}
Как-то так, если ничего не напутал.
Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 12:33:40
sad-angel
xVekx писал(а):Вспомнил что тут на 6 бите минус, поправил код

.
в даташите написано что минус - 7 бит:
http://www.cypress.com/?docID=40538 Но совсем не ясно в каком коде отрицательное напряжение - прямом,обратном или дополнительном...

Re: усреднение двухполярного значения ADC
Добавлено: Вт ноя 27, 2012 12:55:31
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.
Смотри внимательнее. Скопировал из указанного тобой даташита.