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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Плавная перестройка чатоты генерации меандра., 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
dac
сообщение Jun 23 2014, 15:51
Сообщение #2


Знающий
****

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



делал одну поделку, шаг зависит от частоты, в районе 20кгц как раз около 10Гц, на нижних частотах шаг лучше
кусок который выставляет частоту
CODE
#define PWMDEVMAX 6000
#define PWMDEVMIN 960
#define SYSFREQ 48007000

int frequency = 27850;
unsigned short pwmDevider = 1700;


frequency = SYSFREQ/(unsigned int)(pwmDevider + 1);
pwm_config(pwmDevider);

void pwm_config(unsigned short dev)
{
unsigned int i =10000;

#define PERIOD_VAL 861
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
uint16_t CCR1_Val;

if (dev < PWMDEVMIN) dev = PWMDEVMIN;
if (dev > PWMDEVMAX) dev = PWMDEVMAX;
CCR1_Val = dev/2;
TIM_DeInit(TIM1);
i = 10000;
while (i--);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = dev;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

TIM_OC1Init(TIM1, &TIM_OCInitStructure);

/* Automatic Output enable, Break, dead time and lock configuration*/
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 35;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

/* TIM15 counter enable */
TIM_Cmd(TIM1, ENABLE);

/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);



}


Сообщение отредактировал IgorKossak - Jun 23 2014, 17:55
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 24 2014, 08:51
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если для поиска резонанса подавать прямоугольный сигнал, то резонансов найдется много. Когда каждая гармоника (там они нечетные только будут) попадет на резонанс...
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Jun 24 2014, 15:37
Сообщение #4


Знающий
****

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



Цитата(ViKo @ Jun 24 2014, 11:51) *
Если для поиска резонанса подавать прямоугольный сигнал, то резонансов найдется много. Когда каждая гармоника (там они нечетные только будут) попадет на резонанс...


В первый раз слышу. чтобы контур имел несколько резонансных частот.

По поводу моего вопроса.
Я сегодня написал программу "полного" перебора частот выдаваемых таймером с помощью перебора коэффициентов предделителя и значения до которого считает таймер.

Я ограничил значения от 1 до 256.
На ПК перебирает за доли секунды. На МК займет намного больше. Завтра проверю.

Но задача типичная - нахождение двух множителей произведение которых максимально близко приближаются к требуемому значению делителя.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 24 2014, 16:06
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 24 2014, 14:51) *
Если для поиска резонанса подавать прямоугольный сигнал, то резонансов найдется много. Когда каждая гармоника (там они нечетные только будут) попадет на резонанс...

Основная гармоника всё равно имеет макс. амплитуду. Так что и при попадании основной гармоники на резонанс получится максимальная из всех резонансных амплитуд.
ТС же собирается проходить основной гармоникой весь заданный диапазон в процессе поиска.

Цитата(misyachniy @ Jun 24 2014, 21:37) *
Я сегодня написал программу "полного" перебора частот выдаваемых таймером с помощью перебора коэффициентов предделителя и значения до которого считает таймер.

Только непонятно - зачем так сложно, при том что ещё и ограниченно?
Если есть стандартный путь - формирование синусоиды на ЦАП.
И дискретность задания частоты можно получить практически любую, и со всякими делителями/предделителями таймеров заморачиваться не надо.
Да и КПД аналоговой части после МК повыше будет, так как не нужно расходовать энергию на кучу гармоник, которые будут в спектре
прямоугольного сигнала.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Jun 24 2014, 16:32
Сообщение #6


Знающий
****

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



Цитата(jcxz @ Jun 24 2014, 19:06) *
Только непонятно - зачем так сложно, при том что ещё и ограниченно?
Если есть стандартный путь - формирование синусоиды на ЦАП.
И дискретность задания частоты можно получить практически любую, и со всякими делителями/предделителями таймеров заморачиваться не надо.
Да и КПД аналоговой части после МК повыше будет, так как не нужно расходовать энергию на кучу гармоник, которые будут в спектре
прямоугольного сигнала.


Стандартный путь конечно есть. Но расходы на него тоже есть.
Сейчас я формирую двумя транзисторами, а так нужно еще ОУ ставить.
Go to the top of the page
 
+Quote Post
Scientificer
сообщение Jun 24 2014, 17:49
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 44
Регистрация: 6-07-13
Из: Минск
Пользователь №: 77 417



Цитата(misyachniy @ Jun 24 2014, 18:37) *
В первый раз слышу. чтобы контур имел несколько резонансных частот.


Резонировать будет несколько раз, я это гарантирую. У меня лежит прибор по мотивам "Юного радиолюбителя", основанный на том, что у реального меандра много гармоник, до мегагерца, так точно. Я этим прибором буду промежуточную частоту 465 кГц настраивать в ламповом приемнике на досуге, хотя основная частота этого пробника1 кГц. И таки настрою, не сомневайтесь.

Синусоиду нужно делать, а то будете гадать на кофейной гуще. Мы же серьезные люди.

Сообщение отредактировал Scientificer - Jun 24 2014, 17:54


--------------------
Мысли и действия должны чередоваться как вдох и выдох.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Jun 25 2014, 15:44
Сообщение #8


Знающий
****

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



Написал на Builder несколько ускоренную программу поиска коэффициентов файл "calc_presc.rar"

Функция на STM32F103 на 72 Мгц рассчитывает перебирает варианты за время около секунды.

CODE
#define MAX_PRESC 65535
#define MAX_PERIOD 256
//---------------------------------------------------------------------------
void calc_presc(int target_freq, unsigned short *presc_value, unsigned short *half_period_value)
{
int i, j;

float freq, best_calc_freq;
int presc, period;

// разница между заданой чаcтотой и рассчитаной
// в предыдущей итерации и а текущей
float prev_dif, cur_dif;

best_calc_freq=0;

for (i=0;i<MAX_PRESC; i++)
for (j=1; j<=MAX_PERIOD/2; j++)
{

prev_dif = cur_dif;

freq = (SYSCLK_FREQ_72MHz)/ ((1+i) * j*2);
/*
if (sign(target_freq - freq) == sign(target_freq - (SYSCLK_FREQ_72MHz)/ ((1+MAX_PRESC) * MAX_PERIOD)))
{
j = MAX_PERIOD/2;
}
*/
cur_dif = fabs(freq - target_freq);

if (cur_dif < fabs((best_calc_freq - target_freq)))

{
best_calc_freq = freq;
presc = i;
period =j;
}
else
{
if (j>1) // если уже есть с сравнивать
{
if (fabs(prev_dif) < fabs(cur_dif)) j=MAX_PERIOD/2; //результат ухудшается
}
}

}

*presc_value = presc;
*half_period_value = period;
}



Прескалер прямо пишется в регистры таймера, half_period_value прямо в CCR а удвоенное значение в элемент структуры TIM_Period

CODE
// Инициализация таймера управления катушкой
void coil_generator_init(int prescaller, int period)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;


GPIO_InitStructure.GPIO_Pin = COIL_MASK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(COIL_PORT, &GPIO_InitStructure);

// Map TIM5 OC4 to PA3
GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI,DISABLE);


// Init PWM TIM5
// Enable Timer1 clock and release reset
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM5, DISABLE);

TIM_InternalClockConfig(TIM5);

// Time base configuration
TIM_TimeBaseStructure.TIM_Prescaler = prescaller;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = period*2 -1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);

// Channel 2 Configuration in PWM mode
//TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //vovka TIM_OCMode_Toggle

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;


TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0x00;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

TIM_OC4Init(TIM5,&TIM_OCInitStructure);
// Double buffered
TIM_ARRPreloadConfig(TIM5, ENABLE);

// TIM5 counter enable
TIM_Cmd(TIM5,ENABLE);

TIM5->CCR4 = period;
}



Перебор прескаллера 16 бит, периода 8 бит, так как для частот около 15..20гКц никакой выгоды от двух 16 битных коэффициентов нет.
Закомментированый кусок кода еще должен ускорить перебор, но в IAR нет функции Sign().
Но меня и такой вариант устраивает.

Сообщение отредактировал IgorKossak - Jun 25 2014, 19:56
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!

Прикрепленные файлы
Прикрепленный файл  calc_presc.rar ( 667.94 килобайт ) Кол-во скачиваний: 4
 
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jun 25 2014, 19:24
Сообщение #9


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

Группа: Участник
Сообщений: 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 26 2014, 18:54
Сообщение #10


Знающий
****

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



Цитата
Просто для информации...
Около секунды! Это что-то... Ловите мой вариант.

Чувствуется математическая школа - "абсолютно точный" и абсолютно бесполезный ответ.
Цитата
Эта функция и с атмегой справляется...

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

Не кошерно как-то.
Может лучше 4-х ядерный процессор с частотой тактирования 1,5 ГГц использовать?
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jun 26 2014, 19:01
Сообщение #11


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

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



Абсолютно бесполезный ответ - это мои эмоции по Вашим результатам и способу их получения.
Про атмегу я сказал к тому, что параметрами можно настроить данную функцию на поиск опитимального (по точности) результата даже на извратных делителях атмег.
AD9834 стоит 390 рублей. Общий тон Вашего ответа удивляет, но это уже моё личное. Отвечать не стоит.

Сообщение отредактировал Genadi Zawidowski - Jun 26 2014, 19:02
Go to the top of the page
 
+Quote Post
alexf
сообщение Jun 29 2014, 00:21
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608



DDS - безусловно правильное решение. Не внешний, а програмный. Примеров - куча. Любая разумная точность и хоть синус, хоть меандр с выхода DAC в зависимости от того что в таблице. Не надо искать делителей. Принцип очень простой.
Счетчик фазы 32 бита. Прибавляем произвольное число скажем раз в микросекунду. Младшие 8 бит - адрес в таблице синуса (или чего угодно). Если прибавлять по единице, переполнение произойдет с частотой примерно 1/4295 Гц. Если прибавлять по 4295, получим 1 Гц. Если по 4294967, то 1 КГц. И т.д.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jun 29 2014, 05:38
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



младшие ли биты? Если прибавлять по 256 то в них всегда 0.... скорее старшие 8 бит... В случае ключей, старший бит, если ключа 2, то старшие 2 бита.
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Jun 29 2014, 08:01
Сообщение #14


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Совершенно верно - именно старшие биты аккумулятора используются как индекс в таблице синуса.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 29 2014, 09:00
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Из таблицы - в ЦАП, с ЦАПа - на аналоговый фильтр (RC), с фильтра - на компаратор. Вот тогда получится красивый меандр без дрожания фронтов.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 03:51
Рейтинг@Mail.ru


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