Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Синусоида  (Прочитано 27874 раз)
0 Пользователей и 1 Гость смотрят эту тему.
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« : 26-05-2011 14:50 » 

Привет, пишу прогу для МК. Цель-генерация ШИМ сигналов.
Проблема следующая.
Код:


double high;
unsigned int fin;
int z;
                              for (z=1;z<=10;z++)
{
  high=sin((2*PI/10)*z);
                               high=high*100;
                               if (high>0)
{
fin=high;
PCA0CPH0=128+fin;
}
else
{
fin=high;
PCA0CPH0=128-fin;
                                           }
}
                              

В даном случае функция sin выдает некорректные значения. В чем может быть проблема?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 26-05-2011 15:02 » 

хех


а не проще ли рассчитать синусоиду заранее, сохранить в таблице, а затем по индексу вытягивать?


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #2 : 26-05-2011 15:07 » 

goodking, а что значит "неправильные"? И именно ли функция sin(), а не твой код? В каком месте ты снимаешь показания?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-05-2011 17:39 » 

goodking, просто интересно... а зачем вам такая дикая связь между синусоидой и широтно-импульсной модуляцией?))))

PS кстати, классный микроконтроллер с поддержкой float point... дайте два!)

PPS прикольно с преобразованиями должно выглядеть. из double в unsigned int....

Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #4 : 27-05-2011 06:39 » 

Прошу прощения за несвоевременный ответ =)).

По порядку

Цитата
а не проще ли рассчитать синусоиду заранее, сохранить в таблице, а затем по индексу вытягивать?

дело в том, что я никогда раньше не работал с ШИМ, пока просто прикидываю, как оно будет.

Цитата
просто интересно... а зачем вам такая дикая связь между синусоидой и широтно-импульсной модуляцией?))))

связь такая, что скважность ШИМ сигнала должна изменяться по синусоидальному закону, задается количество периодов в секунду, ну и количество ШИМ импульсов...
Цитата
PS кстати, классный микроконтроллер с поддержкой float point... дайте два!)
silabs, а что, еще есть такие, что не поддерживают
Цитата
PPS прикольно с преобразованиями должно выглядеть. из double в unsigned int....
согласен, но это так прикидка, если посоветуете, как значение в 8-битном регистре изменять пропорционально полученному значению double буду благодарен

Цитата
а что значит "неправильные"? И именно ли функция sin(), а не твой код? В каком месте ты снимаешь показания?

то-есть сначала я посчитал вручную. в отладочном окне смотрю значение переменной в этом
Код:
high=high*100;
месте. С тем, что должно быть не совпадает. =)
Записан
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #5 : 27-05-2011 06:52 » 

Попробуй явно указывать double для операций. Также вынеси PI на первое место, что бы выражение интерпретировалось как float:
Код:
  high=sin((PI*2/10)*double(z) );
   high=high*100.0;
Какой прототип для sin()? Может, double не поддерживается, а только float? Может, h-файл с прототипом sin() не подключен, и компилятор не понимает, с чем работает sin(), и предполагает int sin(int) ?
« Последнее редактирование: 27-05-2011 06:55 от PredatorAlpha » Записан
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #6 : 27-05-2011 07:21 » 

спасибо, с синусом вроде разобрался.

теперь вопрос, как это значение занести в регистр PCA0CPH0 ?
Записан
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #7 : 27-05-2011 12:17 » 

спасибо, с синусом вроде разобрался.
теперь вопрос, как это значение занести в регистр PCA0CPH0 ?
Ну, неплохо было бы уточнить, что это за регистр и как он расположен - в памяти, на портах или как......

Наверняка в h-файлах он как-то описан, например

#define PCA0CPH0 (*(volatile Uint16*)0x1234)

Что означает 16-битный регистр расположенный по адресу 0х1234
(Естественно, вместо Uint16 может стоять что-то типа unsigned short)
Тогда доступ к нему получается так:

#include "mcregisters.h"
.....
{
  PCA0CPH0 = 0x6655; // Записываем 0x6655 в регистр PCA0CPH0
}

Если нет h-файлов, что описывают регистры, то можно описать самому. Если он в памяти - то так как выше, если на портах - смотри руководство по компилятору как организован доступ к портам.
Если это не memory-mapped регистр и не портовый регистр, а регистр процессора, то разработчик компилятора должен описать способ доступа к такому, нередко это делается напрямую, хотя может быть и через inline-функции на ассемблере.
« Последнее редактирование: 27-05-2011 12:34 от PredatorAlpha » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 27-05-2011 12:32 » 

в любом случае все должно быть сведено к целочисленному значению

синусоида сначала рассчитывается с определенным шагом (шаг определяется возможностью адресации)
Причем ее не нужно рассчитывать от 0 до пи
достаточно рассчитать от 0 до пи/2
Значения вычислять от квадранта
x<=PI/2 - берем напрямую из таблицы
PI/2<x<=PI инвертируем индекс и берем из таблицы
PI<x<=PI*3/2 инвертируем индекс и берем из таблицы и инвертируем данные
PI*3/2<x<=2PI инвертируем данные


ps если не ошибся...
« Последнее редактирование: 27-05-2011 12:37 от Sla » Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #9 : 27-05-2011 12:39 » 

Sla, не забывай что на МК памяти (оперативной) часто и килобайта нет... Для десятка пойдёт, но ведь это только предварительный пример....
Это надо специально рассчитанные таблицы к коду прилинковывать, записывать во flash вместе с программой, потом их отдельной подпрограммой, собственно для этого написанной, читать. Для новичка это может оказать непосильной задачей, что намертво прибъёт всё начинание программиста.
Хотя так и стоит сделать.
Хотя если подумать, то возиться с float на МК это очень большое извращение.
« Последнее редактирование: 27-05-2011 13:07 от PredatorAlpha » Записан
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #10 : 27-05-2011 13:08 » 

Цитата
Ну, неплохо было бы уточнить, что это за регистр и как он расположен - в памяти, на портах или как.

это регистр- старший байт 16ти разрядного модуля захвата. ШИМ сигнал генерится следующим образом: В регистр PCA0CPH0 заносится величина захвата. Запускается таймер/счетчик. Если код таймера совпадает с кодом в регистре PCA0CPH0-ножка микроконтроллера устанавливается в высокий уровень. Когда величина счетчика достигает значения 0xff-на ножке устанавливается лог.0. То есть меняя значение в PCA0CPH0 меняем скважность выходного сигнала. Вообще-то можно использовать 16-ти разрядный ШИМ, но там частота сигнала получается 49MGz/65535=747Hz, а это мало, поэтому использую 8 битный.
 Вопрос как лучше значение регистра сравнения изменять пропорционально получаемой переменной double??
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 27-05-2011 13:20 » 

синусоида рассчитывается предварительно и хранится в коде... Так что ОЗУ здесь не очень-то и нужно.

Может я уже отстал, но что-то мне не встречались МК с плавающей запятой. Но даже если и есть, то все равно нужно переводить в целочисленное, для того чтоб, хотя бы записать или в порт, или в тот же регистр таймера

Судя по названию регистра PCA0CPH0 это что-то из 51-ой серии а там пока о флоат рано думать
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #12 : 27-05-2011 13:42 » 

PCA0CPH0 это что-то из 51-ой серии а там пока о флоат рано думать

ну почему, silabs 8051f120, все поддерживается. Память 2к функций, 64к прогр.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 27-05-2011 13:59 » 

goodking, что поддерживается? float?
а ну-ка командочку в студию...
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #14 : 27-05-2011 14:09 » 

goodking, что поддерживается? float?
а ну-ка командочку в студию...

а почему бы ей не поддерживатся Улыбаюсь, включаю файл C51FPS.LIB и все работает

Добавлено через 27 минут и 54 секунды:
если интересует http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/CIP-51.pdf&src=SupportDocLibrary вот ссылка на систему команд ядра CIP-51, какое и используется! Улыбаюсь
« Последнее редактирование: 27-05-2011 14:37 от goodking » Записан
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #15 : 27-05-2011 14:43 » 

Ну, если тебя не смущает, что вычисление синуса идёт от 823 до 5558 тактов, то вперёд!

Добавь ещё пару сотен тактов на умножение, и сотню на несколько преобразований int=>float и float=>int. И зацени время одного прохода по циклу.
Кстати, команд я там не заметил... Только описание некоторых функций (программных!!) библиотеки.
« Последнее редактирование: 27-05-2011 14:52 от PredatorAlpha » Записан
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #16 : 27-05-2011 14:52 » 

Ну, если тебя не смущает, что вычисление синуса идёт от 823 до 5558 тактов, то вперёд!

Добавь ещё пару сотен тактов на умножение, и сотню на несколько преобразований int=>float и float=>int. И зацени время одного прохода по циклу.

То-есть лучше вычислять синусоиду заранее?
Записан
PredatorAlpha
Помогающий

ua
Offline Offline

« Ответ #17 : 27-05-2011 14:54 » 

То-есть лучше вычислять синусоиду заранее?
Если есть время попить кофе, то можно и так....
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #18 : 27-05-2011 16:29 » 

Если нужно вычислить функцию синуса с постоянным приростом угла, То сушествует замечательная фунция в тригонометрии.
Код:
sin(A+B) = sin(A) * cos(B) + cos(A) * sin(B)
cos(A+B) = cos(A) * cos(B) - sin(A) * sin(B)
Т.е. действие вычисления следуюшего синуса сведется к 4 умножениям, 1 прибавлению и 1 отниманию.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 27-05-2011 16:43 » 

А ещё существуют таблицы Брадиса Улыбаюсь Уже давно посчитаны, осталось только найти электронный вариант (а у нас были такие жёлтые брошурки - всеобщая ненависть школьников Отлично )
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #20 : 27-05-2011 16:44 » 

Алексей1153++, Ну это то, что предлагал уже Слава Улыбаюсь
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
кот глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 27-05-2011 16:53 » 

ну да )

кстати, в экселе за 5 минут вся эта таблица делается, а при желании - сразу в нужном для вставки в код форматированном виде.
Записан

Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 27-05-2011 18:41 » 

в целочисленных процах синус(и вытекающие) считают четырмя методами.
1. по таблице, на четверть периода по фазе, с требуемым шагом - жрет много памяти, если нужна хоть какая то точность.
2. при помощи какой нибудь апроксимирующей функции. порядка 5-7го. довольно кривенько, но иногда прокатывает. иногда такие либы и идут комплекте (обнаружил в TMS)
3. по кордику - это классика жанра, описаний в нете полно должно быть. считается итеративно, но очень простой цикл. у меня точность 14бит получалось за 160тактов помоему, на TMS с двумя АЛУ. хотя на C51 не факт что это будет очень быстро.
4. сочетание таблицы с последующим уточнением по кордику - самый смак) любой компромисс между памятью, скоростью и точностью.

ЗЫ тема по-моему в раздел мк)
PPS по кордику, это почти как Finch изложил)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 27-05-2011 20:24 » 

Ochkarik, согласен, переношу тему в "Микроконтроллеры"
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #24 : 28-05-2011 09:01 » 

Silabs делает хорошие чипы, но система команд там по прежнему MCS-51. По этому будет много быстрее работать с фиксированной точкой, а не с плавающей. Я не про синусы, а про умножения (синусы надо через таблицы делать - 128..512 байт программной памяти на всю таблицу). Встроенный умножитель всего на 8 бит - потребуются функции работы с большей разрядностью.


Возвращаясь к базовой задаче. Очень хотелось бы увидеть словесное описание алгоритма, применительно к данному железу. Повторение синуса - не такая простая задача, как может показаться. Также хотелось бы услышать физические параметры: тактовая частота чипа, частота ШИМ, диапазон частот воспроизводимого через ШИМ сигнала.
« Последнее редактирование: 28-05-2011 09:06 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 28-05-2011 12:01 » 

Цитата: Finch
Т.е. действие вычисления следуюшего синуса сведется к 4 умножениям, 1 прибавлению и 1 отниманию.
Если итеративно считать A+dA, будет накапливаться погрешность. Если по условию значение хранится в 8-битном регистре, погрешность будет накапливаться очень быстро. При желании можно даже составить функцию, которая по заданному dA и заданным точностям исходных данных и результата определить предельное количество итераций.

Для 8-бит аргумента оптимально будет вбить статическую хэш-таблицу значений. Её размер 256 значений (если значение тоже 8 бит - 256 байтов) - думаю, без проблем влезет даже в самый скромный контроллер. Производительность - как у выборки значения из массива по индексу.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #26 : 30-05-2011 11:28 » 

Цитата
описание алгоритма, применительно к данному железу.

Думаю так- рассчитываю значения синусов для определенного количества точек=>заношу все значения в массив=> в непрерывном цикле поочередно заношу эти значения в регистр сравнения.

Цитата
физические параметры: тактовая частота чипа, частота ШИМ, диапазон частот воспроизводимого через ШИМ сигнала.
тактовая-макс.4.9 MGz
ШИМ-меняется (макс.30000 Gz)

Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #27 : 30-05-2011 13:38 » 

30кГц, это частота основной гармоники ШИМ или частота дискретизации выходных отсчетов?
в последнем случае вы должны уложится в 160тактов/отсчет.
про первый вариант я пока молчу)

PS в непрерывном можно, но вам тогда придется отключить все прерывания, и выравнивать все условные переходы по числу тактов.
иначе фаза гулять будет.
обычно это делают через программирование таймера и прерывание.
« Последнее редактирование: 30-05-2011 13:39 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #28 : 30-05-2011 14:01 » 

goodking, что поддерживается? float?
а ну-ка командочку в студию...

а почему бы ей не поддерживатся Улыбаюсь, включаю файл C51FPS.LIB и все работает

Добавлено через 27 минут и 54 секунды:
если интересует http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/CIP-51.pdf&src=SupportDocLibrary вот ссылка на систему команд ядра CIP-51, какое и используется! Улыбаюсь
Не путай систему команд и библиотеку...

Цитата
Думаю так- рассчитываю значения синусов для определенного количества точек=>заношу все значения в массив=> в непрерывном цикле поочередно заношу эти значения в регистр сравнения.
У тебя синусоида рассчитывается каждый раз по разному?




Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #29 : 30-05-2011 14:45 » 

Цитата
У тебя синусоида рассчитывается каждый раз по разному?

характеристики (обводящая частота, частоат заполнения) будут меняться
Записан
goodking
Постоялец

ua
Offline Offline
Пол: Мужской

« Ответ #30 : 30-05-2011 14:46 » 

30кГц, это частота основной гармоники ШИМ ?


да
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 30-05-2011 19:43 » 

тогда делите частоту вашего процессора частоту дискретизации, которая должна быть в несколько раз выше 30кГц, и получите несколько десятков тактов на отсчет. и одна итерация вашего кода должна в это число тактов уложится.
я так понимаю их будет всего что то около нескольких десятков.

1. использовать  генерацию в цикле... ну это некий секс на самом деле. это вы нормально только ассемблером сможете сделать, потому что иначе придется считать число тактов на цикл, а си-ший компилятор с этим довольно непредсказуемо обходится. придется проверять что он "наварил" после каждой компиляции.
2. посмотрите в сторону таймера и прерываний. это сделает генерацию стабильной, но тут многое зависит от того уложится ваша процедура вместе с обработчиком прерывания в требуемое число тактов или нет. и возможно ли на таймере вашего процессора такое разрешение.
3. вариант - считать не через синус, а фронт/спад этого ШИМа. свободных тактов будет много больше, но это тоже лучше в асемблере делать. собственно вам синус как таковой не нужен. он же у вас только период задает, а это можно пересчитать.
 это если выходной сигнал все таки ШИМ а не смесь прямоугольных импульсов с кусками синусоиды по амплитуде как у вас в первоначальном коде написано.

но вам еще как-то надо исходные данные получать?


Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #32 : 31-05-2011 15:50 » 

4.9 МГц (кстати, по-английски будет MHz, а не MGz) - это, как я вижу, внутренний генератор 24.5 МГц, деленный на пять. Почему именно на пять? Задает эту частоту таймер 0?

Добавлено через 13 минут и 55 секунд:
Судя по мануалу, требующаяся функция timer capture на типовых счетчиках не реализована. Вместо это используется "Programmable Counter Array" (PCA): еще один 16 битный счетчик и 5 модулей сравнения к нему.

Цитата
The Programmable Counter Array (PCA0) provides enhanced timer functionality while requiring less CPU intervention than the standard 8051 counter/timers. The PCA consists of a dedicated 16-bit counter/timer and five 16-bit capture/compare modules. Each capture/compare module has its own associated I/O line (CEXn) which is routed through the Crossbar to Port I/O when enabled.

Я так понимаю, что счет PCA должен задавать период, а модуль захвата задает ширину.
В общем теперь понятно, зачем делить на пять - для использования режима PWM 8 bit. Режим с буферизацией значения ШИМ. Прерывание по переполнению PCA есть.

В чем, собственно, возникла сложность?


Добавлено через 15 минут и 51 секунду:
В обработчике прерывания вычисляем новое значение и загружаем в регистр PCA0CPHn. Вычисление должно быть достаточно быстрое, т.к. период между прерываниями составляет 816-817 тактов (машинный цикл данного чипа - 1 такт). Т.е. тысяч тактов на использование плавающих значений, а уж тем более функций синусов нет. Самым оптимальным будет использование табличных преобразований. Не помешает подсчет погрешности преобразования, иначе будет низкочастотный дрейф.

Считаю, что для данного чипа риалтайм-процедуры нужно писать на ассемблере. На Си можно писать только некритичную ко времени исполнения логику.
« Последнее редактирование: 31-05-2011 16:30 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

Хз, я не очень просто не очень во всё это верю, во всякие там сатурны и прочую поебень.
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines