реклама на сайте
подробности

 
 
> Плавная перестройка чатоты генерации меандра., STM32F103
misyachniy
сообщение Jun 23 2014, 15:28
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Для поиска чатоты резонанса поисковой катушки (ориентировочно 5..20 кГц) нужно генерировать меандр с помошью таймера.
Понятно что можно менять как предделитель таймера, так и с помощью регистров OCR.

Прошерстил интернет в поисках готового решения или "рыбы" но не нашел.

Предлагается в основном формирование синусоиды даже с дискретностю до 0.1 или 0.01 Гц.

Меня бы устроила шкала в 10Гц.

Есть ли где "рыба"?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Genadi Zawidowsk...
сообщение Jun 25 2014, 19:24
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Просто для информации...
Около секунды! Это что-то... Ловите мой вариант.
CODE
// возврат позиции старшего значащего бита в числе
static uint_fast8_t
findleftbit(
unsigned long v // число на анализ
)
{
uint_fast8_t n;

for (n = 0; v != 0; ++ n)
v >>= 1;

return n;
}

static uint_fast8_t
calcdivider(
uint_fast32_t divider, // ожидаемый коэффициент деления всей системы
uint_fast8_t width, // количество разрядов в счётчике
uint_fast16_t taps, // маска битов - выходов прескалера. 0x01 - означает bypass, 0x02 - делитель на 2... 0x400 - делитель на 1024
uint_fast16_t * dvalue, // Значение для записи в регистр сравнения делителя
uint_fast8_t substract)
{
const uint_fast8_t rbmax = 16; //позиция старшего значащего бита в маске TAPS
uint_fast8_t rb, rbi;
uint_fast16_t prescaler = 1U;
for (rb = rbi = 0; rb <= rbmax; ++ rb, prescaler *= 2)
{
if ((taps & prescaler) != 0)
{
// такой предделитель существует.
const uint_fast32_t modulus = (divider / prescaler) - substract;
if (findleftbit(modulus) <= width)
{
// найдена подходящая комбинация
// rb - степень двойки - деление предделителя.
// rbi - номер кода для записи в регистр предделителя.
// modulus - что загрузить в регистр сравнения делителя.
* dvalue = (uint_fast16_t) modulus;
return rbi;
}
++ rbi; // переходим к следующему предделителю в списке.
}
}
// Не подобрать комбинацию прескалера и делителя для ожидаемого коэффициента деления.
* dvalue = 1 - substract; // просто пустышка
return (rbi - 1); // если надо обраьатывать невозможность подбора - возврат rbmax
}

...
Код
enum
{
        STM32F_GP_TIMER_WIDTH = 16,    STM32F_GP_TIMER_TAPS = (65535), // General-purpose timers
        STM32F_AC_TIMER_WIDTH = 16,    STM32F_AC_TIMER_TAPS = (65535), // Advanced-control timers
        STM32F_BA_TIMER_WIDTH = 16,    STM32F_BA_TIMER_TAPS = (65535), // Basic timers
        STM32F_SPIBR_WIDTH = 0,    STM32F_SPIBR_TAPS = (256 | 128 | 64 | 32 | 16 | 8 | 4 | 2),

        // LTDC dot clock parameters
        STM32F_LTDC_DIV_WIDTH = 3, // valid values for RCC_PLLSAICFGR_PLLI2SR: 2..7
            STM32F_LTDC_DIV_TAPS = (16 | 8 | 4 | 2),    // valid values for RCC_DCKCFGR_PLLSAIDIVR: 0: /2, 1: /4, 2: /8, 3: /16
};
...
Код
    uint_fast16_t value;
    const uint_fast8_t prei = calcdivider(calcdivround_pclk2(ticksfreq), STM32F_BA_TIMER_WIDTH, STM32F_BA_TIMER_TAPS, & value, 1);
    TIM3->PSC = (1UL << prei) - 1;
    TIM3->ARR = value;
    TIM3->DIER = TIM_DIER_UIE;    //разрешить событие от таймера.


Эта функция и с атмегой справляется... Принцип такой - найти максимально точную аппроксимацию - начиная с минимального зщначения прескалера, которая влезет в указанное количество битов.

зы: откройте для себя принцип NCO/DDS...

Код
#include "sinetable.h"

typedef uint32_t ncoftw_t;
#define VALUELOG2    16    // количество битов в значении из целочисленной таблицы
#define ASH (32 - TABLELOG2)    // 22 = 32 - log2(number of items in sintable)
#define FTW2ANGLEI(ftw)    ((uint32_t) (ftw) >> ASH)
#define FTW2ANGLEQ(ftw)    ((uint32_t) ((ftw) + 0x40000000L) >> ASH)
#define FTWROUND(ftw) ((uint32_t) (ftw))
#define FTW(freq) (((uint_fast64_t) (freq) << 32) / ARMSAIRATE)
#define FTWAF(freq) (((uint_fast64_t) (freq) << 32) / ARMI2SRATE)


CODE
static ncoftw_t anglestep_lout = FTWAF(700), anglestep_rout = FTWAF(2500);
static ncoftw_t angle_lout, angle_rout;

static ncoftw_t anglestep_lout2 = FTWAF(5600), anglestep_rout2 = FTWAF(6300);
static ncoftw_t angle_lout2, angle_rout2;

int get_rout16(void)
{
// Формирование значения для ROUT
const int v = (sintable [FTW2ANGLEI(angle_rout)]) * (1L << (16 - VALUELOG2));
angle_rout = FTWROUND(angle_rout + anglestep_rout);
return v;
}

int get_lout16(void)
{
// Формирование значения для LOUT
const int v = (sintable [FTW2ANGLEI(angle_lout)]) * (1L << (16 - VALUELOG2));
angle_lout = FTWROUND(angle_lout + anglestep_lout);
return v;
}

int get_rout24(void)
{
// Формирование значения для ROUT
const int v = (sintable [FTW2ANGLEI(angle_rout2)]) * (1L << (24 - VALUELOG2));
angle_rout2 = FTWROUND(angle_rout2 + anglestep_rout2);
return v;
}

int get_lout24(void)
{
// Формирование значения для LOUT
const int v = (sintable [FTW2ANGLEI(angle_lout2)]) * (1L << (24 - VALUELOG2));
angle_lout2 = FTWROUND(angle_lout2 + anglestep_lout2);
return v;
}

//////////////////////////////////////////

// American (AT&T)
// dial tone 350 and 440 Hz
//static ncoftw_t anglestep_af1 = FTWAF(440);
//static ncoftw_t anglestep_af2 = FTWAF(350);

// Dual tone signal generator for SSB TX tests
static ncoftw_t anglestep_af1 = FTWAF(850);
static ncoftw_t anglestep_af2 = FTWAF(1050);

static ncoftw_t angle_af1;
static ncoftw_t angle_af2;

// получение значений выборок для двухтонового сигнала
int get_dualtone16(void)
{
// Формирование значения для LOUT
const int v1 = (sintable [FTW2ANGLEI(angle_af1)]) * (1L << (16 - VALUELOG2));
const int v2 = (sintable [FTW2ANGLEI(angle_af2)]) * (1L << (16 - VALUELOG2));
angle_af1 = FTWROUND(angle_af1 + anglestep_af1);
angle_af2 = FTWROUND(angle_af2 + anglestep_af2);
return (v1 + v2) / 2;
}


Получаемые значения выдавать в ЦАП. Или использовать микросхему DDS - вроде AD9834 или другую с нужными характеристиками...

Сообщение отредактировал IgorKossak - Jun 25 2014, 19:57
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- misyachniy   Плавная перестройка чатоты генерации меандра.   Jun 23 2014, 15:28
- - dac   делал одну поделку, шаг зависит от частоты, в райо...   Jun 23 2014, 15:51
- - ViKo   Если для поиска резонанса подавать прямоугольный с...   Jun 24 2014, 08:51
|- - misyachniy   Цитата(ViKo @ Jun 24 2014, 11:51) Если дл...   Jun 24 2014, 15:37
||- - Scientificer   Цитата(misyachniy @ Jun 24 2014, 18:37) В...   Jun 24 2014, 17:49
||- - misyachniy   Написал на Builder несколько ускоренную программу...   Jun 25 2014, 15:44
|- - jcxz   Цитата(ViKo @ Jun 24 2014, 14:51) Если дл...   Jun 24 2014, 16:06
|- - misyachniy   Цитата(jcxz @ Jun 24 2014, 19:06) Только ...   Jun 24 2014, 16:32
- - misyachniy   ЦитатаПросто для информации... Около секунды! ...   Jun 26 2014, 18:54
- - Genadi Zawidowski   Абсолютно бесполезный ответ - это мои эмоции по Ва...   Jun 26 2014, 19:01
|- - alexf   DDS - безусловно правильное решение. Не внешний, а...   Jun 29 2014, 00:21
- - Golikov A.   младшие ли биты? Если прибавлять по 256 то в них в...   Jun 29 2014, 05:38
- - rx3apf   Совершенно верно - именно старшие биты аккумулятор...   Jun 29 2014, 08:01
- - Сергей Борщ   Из таблицы - в ЦАП, с ЦАПа - на аналоговый фильтр ...   Jun 29 2014, 09:00
- - misyachniy   Цитата(Сергей Борщ @ Jun 29 2014, 12:00) ...   Jun 29 2014, 09:59


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 05:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016