С вычислением арктангенса вроде разобрался. Сделал массив из значений тангенса для 0...89 +чуть больше 89 (см.таблиц 10000 ниже) град. Т.е позиция в массиве некого значения будет соответствовать арктангенсу этого значения.
А для того чтобы избавится от чисел с плавающей запятой float значения массива были предварительно умножены на 100 и округлены. Да еще и исходные тоже нужно *100. к примеру A/B =1 1 нужно умножить на 100. Чтобы соблюдался масштаб значений
к примеру 0 соответствует 0град, 100=45 град, 5729=89 град
Код:
const unsigned int arct[91]=
{0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, 27, 29, 31, 32, 34, 36,
38, 40, 42, 45, 47, 49, 51, 53, 55, 58, 60, 62, 65, 67, 70, 73, 75, 78, 81,
84, 87, 90, 93, 97, 100, 104, 107, 111, 115, 119, 123, 128, 133, 138, 143,
148, 154, 160, 166, 173, 180, 188, 196, 205, 214, 225, 236, 248, 261, 275,
290, 308, 327, 349, 373, 401, 433, 470, 514, 567, 631, 712, 814, 951, 1143,
1430, 1908, 2864, 5729, 10000 };
Получилась "Вывернутая таблица"
Для того чтобы быстро находить позицию значения использовал метод деления по палам
к примеру Phi = arc(100); Phi=0x002D или 45(десят)
Код:
unsigned char arc (unsigned int D)
{
unsigned char i;
unsigned char toLeft=0;
unsigned char toRight=89;
unsigned char pol0=0;
unsigned char pol1=0;
while (1)//сам поиск
{
i=(toLeft+toRight) / 2;
if (D < arct[i])
{
toRight= i-1;
pol1 = i;
}
else if (D > arct[i])
{
toLeft= i+1;
pol0=i;
}
if ((((pol0-pol1)<2)&&(pol0)&&(pol1))||(toLeft > toRight)||(D == arct[i]) ) break;
}
return i;// позиция значения или что близкое
}
Сам бы не разобрался помогал
=DeaD= За эт ему большое СПС Метод рабочий сам проверял.
Это было для углов 0-90
А для остальных углов прописал условия
Для Всех углов:
Код:
U[0..3] значения АЦП
unsigned int Phi=0;
unsigned int Phi_0;
if (((U[0])+(U[2])+(U[1])+(U[3]))>50)
{
if ((U[0]>U[2])&&(U[1]>=U[3]))
{if (U[1]==U[3]) Phi_0=10000;else
{
Phi_0=(((U[1]-U[3])*100)/((U[0]-U[2])));
if (Phi_0>6000) Phi=10000;
}
Phi=0;
}
if ((U[0]<=U[2])&&(U[1]>U[3]))
{if (U[0]==U[2]) Phi_0=10000;else
{
Phi_0=(((U[2]-U[0])*100)/((U[1]-U[3])));
if (Phi_0>6000) Phi=10000;
}
Phi=90;
}
if ((U[0]<U[2])&&(U[1]<=U[3]))
{if (U[1]==U[3]) Phi_0=10000;else
{
Phi_0=(((U[3]-U[1])*100)/((U[2]-U[0])));
if (Phi_0>6000) Phi=10000;
}
Phi=180;
}
if ((U[0]>=U[2])&&(U[1]<U[3]))
{if (U[0]==U[2]) Phi_0=10000;else
{
Phi_0=(((U[0]-U[2])*100)/((U[3]-U[1])));
if (Phi_0>6000) Phi=10000;
}
Phi=270;
}
Phi += arc(Phi_0);
Вроде так.
Вопрос по усреднению значения для углов 350-0-10 как правильно выполнить?
Добавлено спустя 56 минут 31 секунду:Да еще вопрос по USART. Данные в моем случае нужно передавать без ожидания освобождения
while ( !( UCSR0A & (1<<UDRE0)) ); т.е через прерывания: байт ушел прерывание следующий байт ит.д . Не хотелось изобретать велосипед. Этот while сильно тормозит программу. Скорость 57600. 8 байт передать всего то.
Может примеры есть или ссылки?? Спасибо за ранее!