Al Volovich (20.01.2009 10:42, просмотров: 176) ответил Vladimir Ljaschko на Требования по точности приблизительно 5% линейных размеров, а по скорости ... пока не готов сформулировать. А какой алгоритм обнаружения срабатывания используете? Повторяемость показаний?
5% легко получается, даже без калибровки. Меняя SampleCnt можно изменять точность/время опроса
Постобработка от дребезга тоже полезна, но тут ее нет - это уже дело долгое и оставлено на усмотрение пользователя.
#define SampleCnt 5 //количество точек для усреднения результата
void StandbyTouchScreen(void)
//переводит выводы тачскрина в дежурное положение
{
Y1_dir = 1;//Подаем напряжение на диагональ
Y1_out = 1;
X1_dir = 1;
X1_out = 0;
X2_dir = 0;
X2_out = 0;
Y2_dir = 0;
Y2_out = 0;
}
void TouchScreenOn(void)
//переводит выводы тачскрина в положение определения нажатия
{
Y1_dir = 0;//Подаем напряжение на диагональ
Y1_out = 0;
X1_dir = 0;
X1_out = 0;
X2_dir = 1;
X2_out = 0;
Y2_dir = 1;
Y2_out = 1;
}
void MeasureXPins(void)
//Переводит выводы в положение измерения X
{
X1_dir = 1;//Подаем напряжение
X1_out = 1;
X2_dir = 1;
X2_out = 0;
Y1_dir = 0;
Y1_out = 0;
Y2_dir = 0;
Y2_out = 0;
}
void MeasureYPins(void)
//Переводит выводы в положение измерения Y
{
Y1_dir = 1;//Подаем напряжение
Y1_out = 0;
Y2_dir = 1;
Y2_out = 1;
X1_dir = 0;
X1_out = 0;
X2_dir = 0;
X2_out = 0;
}
uword ReadWithAvg(ubyte adc_ch, ubyte samcnt)
//устанавливает канал АЦП adc_ch и считывает и усредняет samcnt выборок. Возвращает результат измерения
{
uword res = 0;
ubyte cnt;
SetADCInp(adc_ch);//включаем канал
ReadADC(); //dummyread
for(cnt = 0;cnt<samcnt;cnt++)res += ReadADC10bit();
res = res/samcnt; //считаем среднее от выборок
return res;
}
void PollTouchScreen(struct TTouchPos* pos)
//опрашивает тачпанель и возвращает координаты нажатия и силу нажатия
//если нажатия нет - то pressure = 0; Если ошибка измерения - pressure = 255
{
uword Z1, X1, Y1,pm, pp;
pos->X = pos->Y = pos->Pressure = 0;
__disable_interrupt();
ADCInit10bit();//настраиваем АЦП. Ноги д.б. уже настроены в Standby
SetVrefVdc; //Опорное - питалово
StandbyTouchScreen();//Определяем нажатие
Z1 = ReadWithAvg(X2_ADC_num,2);
TouchScreenOn();//переворачиваем диагональ
Z1 = (ReadWithAvg(X1_ADC_num,2)+Z1)>>1;
if((Z1&0xFFF8)!=0){ //Если нажатия нет - быстро возвращаем все нули
MeasureYPins();//Переключаем выходы
pm = ReadWithAvg(Y1_ADC_num,SampleCnt);
Y1 = ReadWithAvg(X2_ADC_num,SampleCnt);
pp = ReadWithAvg(Y2_ADC_num,SampleCnt);
Y1 = (ulong)(Y1-pm)*255/(pp-pm);
MeasureXPins();//Переключаем выходы
pm = ReadWithAvg(X2_ADC_num,SampleCnt);
X1 = ReadWithAvg(Y2_ADC_num,SampleCnt);
pp = ReadWithAvg(X1_ADC_num,SampleCnt);
X1 = (ulong)(X1-pm)*255/(pp-pm);
pos->Pressure = Z1>>2;
pos->X = X1;
pos->Y = Y1;
};
//возвращем все в начальное состояние
ADCInit();
SetADCInp(7);//включаем канал Avdd
SetVref1_1V;
ReadADC(); //dummyread
__enable_interrupt();
}