Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Управление цифровым резистором по синусоидальному закону
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
asc2000
Добрый день! Пытаюсь с помощью м-к ATtiny261 управлять цифровым потенциометром AD8400 по синусоидальному закону. Из осциллограммы видно, что потенциометр изменяет сопротивление в своем полном диапазоне, но всего лишь за несколько шагов, а не за 256, как должно быть. В чем может быть причина?

Фрагмент кода для CodeVisionAVR:

unsigned int q;
unsigned char s;


while (1)
{
for(q=0;q < 628; q++) //для всех 256 значений сопротивления
{
s=125*(sin(q/100)+1);
set_resistance(0x00, s);
}

};


Нажмите для просмотра прикрепленного файла
gerber
Ошибка округления. У вас q целое число, соответственно, в интервале q от 0 до 99 синус равен нулю и т. д.
blackfin
А если так: s=125*(sin(q/100.0)+1); ..?
gerber
Цитата(blackfin @ Dec 7 2015, 15:09) *
А если так: s=125*(sin(q/100.0)+1); ..?

Вероятно, не поможет, 100.0 будет приведено к целому по первому операнду выражения q/100.0
Нужно s = (unsigned char) (125.0*(sin((float)q/100.0) + 1.0));
XVR
Цитата(gerber @ Dec 7 2015, 15:12) *
Вероятно, не поможет, 100.0 будет приведено к целому по первому операнду выражения q/100.0
Не будет. По правилам С если в арифметическом выражении участвует любое плавающее значение (не важно каким операндом), то все операнды будут приведены в плавающую форму и вычисляться соответственно.

asc2000
Цитата(gerber @ Dec 7 2015, 15:12) *
Нужно s = (unsigned char) (125.0*(sin((float)q/100.0) + 1.0));



Спасибо, получилось! Почти чистая синусоида:

Нажмите для просмотра прикрепленного файла
Mahagam
QUOTE (gerber @ Dec 7 2015, 15:12) *
Вероятно, не поможет, 100.0 будет приведено к целому по первому операнду выражения q/100.0
Нужно s = (unsigned char) (125.0*(sin((float)q/100.0) + 1.0));

поможет. при операциях между int и float по стандарту всё переводится во float. однако 100.0 - это double. и как результат, q сначала будет переведено в double. хотя тут так или иначе будет конверсия в дабл, так как синус требует его на входе.

кроме того, так как результат синуса - дабл, то и добавляемая единичка, и 125 тоже будут переконверчены в double. и только в самом конце пребразованы в char.
для ATtiny261 работа с double - это аДъ. хотя возможно что родная математическая библиотека может иметь синус одинарной точности.
_pv
Цитата(Mahagam @ Dec 7 2015, 19:54) *
для ATtiny261 работа с double - это аДъ. хотя возможно что родная математическая библиотека может иметь синус одинарной точности.

Не знаю как codevision, iar вроде бы по умолчанию считает что doublы равны floatу, то есть оба 32х разрядные - с одинарной точностью.
codevision скорее всего тоже, иначе при 128 байтах памяти в тини261 это дейстительно аДъ

ну а для 8ми битного синуса и полинома третьей степени достаточно будет
Код
unsigned char sinus(unsigned char x){
  unsigned long a = 118;
  a *= x;
  a += 9039;
  a *= x;
  a = 26782194 - a;
  a *= x;
  return (a >> 24);  
}

это если 256 байт под таблицу жалко
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.