Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-май-22 11:27

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
СообщениеДобавлено: 2016-окт-24 11:38 
Не в сети

Зарегистрирован: 2016-янв-29 17:53
Сообщения: 54
Здравствуйте, скажите пожалуйста, сколько тактов в среднем(или минимальное/максимальное кол-во тактов) выполняется операция sin, cos? Есть ли другое решение, которое выполняется быстрее? какие параметры лучше подбирать(с плавающей запятой или int)?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2016-окт-24 11:50 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 67
Думаю, что количество тактов для выполнения Си-функций sin и cos не отражено в документации. Проще самому провести эксперимент, вычислив sin и cos и засекая по SysTick или иному аппаратному таймеру время до и после вычисления.
Другим решением может быть табличное представление функции sin и cos, в том числе, целочисленное представление функции вида z = A * sin (t / T), где А - амплитуда, Т - период. Т.е. заранее (при включении контроллера или даже в исходнике проекта) вычисляйте значения функции, заносите их в массив, а затем извлекайте ранее вычисленные значения из соответствующих элементов массива. Такой подход часто используют при генерации сигнала с помощью ЦАП.
Конкретизируйте задачу, может быть, подскажу подробней.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2016-ноя-03 13:51 
Не в сети

Зарегистрирован: 2016-янв-29 17:53
Сообщения: 54
Код:
//Constants
#define cordic_1K 0x26DD3B6A    // 1/k = 0.6072529350088812561694
#define half_pi 0x6487ED51      // pi / 2
#define MUL 1073741824.000000   // 1.0 = 1073741824
#define CORDIC_NTAB 32

int cordic_tab [] = {
    0x3243F6A8, 0x1DAC6705, 0x0FADBAFC, 0x07F56EA6, 0x03FEAB76, 0x01FFD55B, 0x00FFFAAA, 0x007FFF55,
    0x003FFFEA, 0x001FFFFD, 0x000FFFFF, 0x0007FFFF, 0x0003FFFF, 0x0001FFFF, 0x0000FFFF, 0x00007FFF,
    0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF, 0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F,
    0x0000003F, 0x0000001F, 0x0000000F, 0x00000008, 0x00000004, 0x00000002, 0x00000001, 0x00000000
};

void cordic32_sin_cos(int alpha, int *s, int *c, int n)
{
    int k, d, tx;
    int z = alpha;
    *c = cordic_1K, *s = 0;
    n = (n > CORDIC_NTAB) ? CORDIC_NTAB : n;
    if(n<3) n = 3;
    for (k=0; k<n; ++k)
    {
        d = z >> 31;    //d = z>=0 ? 0 : -1;
        tx = *c;
        *c -= (((*s>>k) ^ d) - d);
        *s += (((tx>>k) ^ d) - d);
        z -= ((cordic_tab[k] ^ d) - d);
    }
}
Вот что для себя нашел


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2016-ноя-03 14:43 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1098
Откуда: Тула
fryn3 писал(а):
Вот что для себя нашел

Как тут нормируются входные-выходные данные?

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2016-дек-13 16:09 
Не в сети

Зарегистрирован: 2016-янв-29 17:53
Сообщения: 54
prostoRoman писал(а):
fryn3 писал(а):
Вот что для себя нашел

Как тут нормируются входные-выходные данные?

Что такое нормирование?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2016-дек-13 16:49 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1098
Откуда: Тула
fryn3 писал(а):
prostoRoman писал(а):
fryn3 писал(а):
Вот что для себя нашел

Как тут нормируются входные-выходные данные?

Что такое нормирование?

Сколько будет два*Пи, Пи/4 - на входе и +1,0,-1 на выходе?

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2018-мар-27 20:11 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 67
Может, кому-нибудь будет интересно. Придумал алгоритм, позволяющий генерировать синусоидальный сигнал вида S = A*sin(t/A) без использования вещественных вычислений и таблиц.
Ниже приведен исходник консольного приложения:

Код:
#include <stdint.h>
#include "stdio.h"

#define A 50  // Амплитуда сигнала
#define N 2   // Количество периодов сигнала

int main(void)
{
  int32_t a;   // Амплитуда

  int32_t s;   // Значение sin в пределах
               // 1-го квадранта
  int32_t e_s; // Ошибка вычисления sin
  int32_t sin; // Значение sin
 
  int32_t c;   // Значение cos в пределах
               // 1-го квадранта
  int32_t e_c; // Ошибка вычисления cos
 
  uint32_t Q;  // Квадрант
 
  uint32_t t;  // Номер отсчета
  uint32_t n;  // Номер периода
 
  // Вспомогательные переменные
  int32_t e0, e1, ae0, ae1;
 
  a = A; Q = 1;
  s = 0; e_s = 0;
  c = A; e_c = 0;
  t = 0; sin = s;
 
  printf ("%8d\t%8d\n", t, sin);
 
  for (t = 1, n = 1; n <= N; t++)
  {
    // Оценка ошибки при вычислении c
    e0 = e_c - s; // Если c = c + 0
    e1 = e0 + a;  // Если c = c - 1
    ae0 = ((e0 < 0) ? -e0 : e0); // |e0|
    ae1 = ((e1 < 0) ? -e1 : e1); // |e1|
 
    // Выбираем вариант, при котором
    // модуль ошибки вычисления c меньше
    if (ae1 < ae0) // |e1| < |e0|
    {
      e_c = e1;
      c--;
    }
    else
      e_c = e0;
   
    // Оценка ошибки при вычислении s
    e0 = e_s - c;  // Если s = s + 0
    e1 = e0 + a;   // Если s = s + 1
    ae0 = ((e0 < 0) ? -e0 : e0); // |e0|
    ae1 = ((e1 < 0) ? -e1 : e1); // |e1|
   
    // Выбираем вариант, при котором
    // модуль ошибки вычисления s меньше
    if (ae1 < ae0) // |e1| < |e0|
    {
      e_s = e1;
      s++;
    }
    else
      e_s = e0;
   
    // Пересчитать результат
    // в зависимости от квадранта
    switch (Q)
    {
      case 1: // Квадрант 1
        sin = s;
        break;
   
      case 2: // Квадрант 2
        sin = c;
        break;
   
      case 3: // Квадрант 3
        sin = -s;
        break;
   
      case 4: // Квадрант 4
        sin = -c;
        break;
    }
   
    if (c == 0) // Квадрант закончен
    {
      s = 0; e_s = 0;
      c = a; e_c = 0;
   
      if (++Q > 4) // Завершили полный период
      {
        Q = 1;     // Вернулись к квадранту 1
        n++;
      }
    }
   
    printf ("%8d\t%8d\n", t, sin);
  }

  return 0;
}


Прикреплен также проект под Keil uVision 4.72 и отладочную плату К1986ВЕ92QI, в котором реализован этот алгоритм для генерации синусоидального сигнала с помощью ЦАП.

С теорией вопроса можно познакомиться в статье:
Благодаров А.В. Целочисленный алгоритм генерации синусоидального сигнала // Цифровая обработка сигналов. 2017. №4. С. 69-74.


Вложения:
sin.rar [358.5 КБ]
Скачиваний: 30
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: GeniokV и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB