Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 21:56:49

В юзаемых тобой 32пЫк есть же DMA?

Есть. Они и в 24-ых есть. Только я их как-то "проехал" - сразу выбрал 32-ые.

Re: Вопросы по С/С++ (СИ)

Вт дек 12, 2017 18:51:47

Ну разобрался я в том коде, вывожу на 7-сегм.,что хочу, но.. Блин, автор конечно жжет.этого кода, надо было в STM8S003 с такой ничтожной памятью ОС засунуть! Обслуживание индикатора и кнопок только полпамяти занимает, я остальное своё добавил.тем более с библиотекой math.h- всё- памяти не хватает, придется отдирать 7-сегм. оттуда и убирать библу ос.
"ltkrn.h" и в майне несколько бесконечных циклов-это же ось-как я понимаю? Как у вас там у си-шников-несколько нитей чтоли.. :)

Re: Вопросы по С/С++ (СИ)

Вт дек 12, 2017 19:52:34

Блин, автор конечно жжет.этого кода, надо было в STM8S003 с такой ничтожной памятью ОС засунуть!

а что, собственно, такого? Предположу, что автору памяти вполне хватало)

Re: Вопросы по С/С++ (СИ)

Вт дек 12, 2017 20:01:59

Блин, автор конечно жжет.этого кода, надо было в STM8S003 с такой ничтожной памятью ОС засунуть!

а что, собственно, такого? Предположу, что автору памяти вполне хватало)

Ничего. просто встретил впервые ОС в МК. Автор конечно опытный и написал как знает для готовой платы своё.

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 15:40:13

Добрый день, подскажите пожалуйста как сделать, чтобы компилятор не ругался
warning: #188-D: enumerated type mixed with another type
Подразумеваю приведение типа или типо того)))

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 15:57:06

телепатирую: вы где-то присваиваете переменной с типом enum значение какого-то из int-ов, или наоборот.

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 15:58:33

Здравствуйте.

Нужно циклически сдвинуть массив типа int16_t вправо, как думаете какая из реализаций будет работать быстрее:
Код:
void reverse_arr(int16_t *arr, uint16_t size) { // развернуть массив
   uint16_t i;
   int16_t temp;

   for (i = 0; i < size / 2; i++) {
      temp = arr[i];
      arr[i] = arr[size - 1 - i];
      arr[size - 1 - i] = temp;
   }
}

void shift_arr(int16_t *arr, uint16_t shift, uint16_t size) { // циклически сдвинуть массив размером size на shift элементов
   reverse_arr(&arr[size - shift], shift);
   reverse_arr(arr, size - shift);
   reverse_arr(arr, size);
}

или
Код:
void shift_arr(int16_t *arr, uint16_t shift, uint16_t size) { // циклически сдвинуть массив размером size на shift элементов
   int16_t buf[100];   

   memcpy(buf, &arr[size - shift], shift * 2); // копируем последние елементы в буфер
   memmove(&arr[shift], arr, (size - shift) * 2); // сдвигаем
   memcpy(arr, buf, shift * 2); // копируем из буфера в начало
}


P.S. контроллер STM32 компилятор GCC, на AVR под GCC тоже интересно.

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 17:56:20

Apparatchik писал(а):контроллер STM32 компилятор GCC
по идее memcpy для 32-битной платформы должна активно использовать именно 32-битные пересылки, поэтому должна выигрывать у 16-битного копирования... хотя кто знает, сделано это в arm-libc или нет... да и я не в курсе, есть ли разница у ARM-ов...

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 18:30:47

телепатирую: вы где-то присваиваете переменной с типом enum значение какого-то из int-ов, или наоборот.

Для чего вы вангуете?
Там это явно написано, меня интересует как убрать warning. Как дать понять компилятору, что делаю это осознано.

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 20:18:52

ну первый очевидный и правильный вариант - не делать так) если все-таки это нужно, то можно явно привести типы в нужных местах.

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 20:19:32

телепатирую: вы где-то присваиваете переменной с типом enum значение какого-то из int-ов, или наоборот.

Там это явно написано, меня интересует как убрать warning. Как дать понять компилятору, что делаю это осознано.

Естественно - явно привести типы. А вы чего ожидали?

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 21:03:24

Нужно циклически сдвинуть массив типа int16_t вправо, как думаете какая из

Стесняюсь спросить, а зачем нужно двигать массив? Вообще то принято двигать указателями....

Re: Вопросы по С/С++ (СИ)

Чт дек 21, 2017 23:14:00

Стесняюсь спросить, а зачем нужно двигать массив? Вообще то принято двигать указателями....

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

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 01:15:39

непонятно, зачем сами значения туда-сюда перекладывать. Организуйте кольцевую структуру и двигайте указатель на условное начало

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 04:04:44

В конкретном случае нужно скомпенсировать отставние тока от напряжения при измерении трансформатором тока.

Вам выше подтвердили мою сентенцию на этот счет.
Однако, а зачем вообще Вам нужно это фазирование тока и напряжения? Что Вы собираетесь посчитать?
У меня опять смутные подозрения на Ваш счет... :tea:

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 09:29:00

АЦП складывает выборку в массив за период, пока складывает надо обработать предыдущую. При активной нагрузке ток немного сдвинут относительно напряжения (а не должен) из-за измерительного трансформатора, это видно как на графике так и при вычислении коофициента мощности (PF). Для компенсации индуктивности трансформатора нужно ток сдвинуть относительно напряжения. В общем зачем эти подробности? Я же сказал что уже работает и просто спросил может можно сдвинуть как то быстрее. Нет так нет.

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 09:37:46

Apparatchik писал(а):Эксперементально выяснено что второй вариант работает лучше, но может есть более быстрые варианты.
то есть я угадал, предположив, что libc содержит оптимальную memcpy. тогда снова предположу, что еще быстрее сдвинуть можно при помощи DMA...

Добавлено after 1 minute 27 seconds:
Но вообще гоовря, вам дают верные советы: вместо сдвига буфера целиком можно обрабатывать, грубо говоря, i-ую выборку напряжения и (i+4)-ую выборку тока, вот и будет сдвиг...

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 09:47:38

то есть я угадал, предположив, что libc содержит оптимальную memcpy. тогда снова предположу, что еще быстрее сдвинуть можно при помощи DMA...

Видимо да, но она всеже копирует побайтно, для типа int16_t я размер умножил на 2.
Но вообще гоовря, вам дают верные советы: вместо сдвига буфера целиком можно обрабатывать, грубо говоря, i-ую выборку напряжения и (i+4)-ую выборку тока, вот и будет сдвиг...

Выборки две, они набираются паралельно, на 400 элементов, но одну нужно сдвинуть относительно другой, обычно на 5-6 элементов, но может менятся. Сдвинуть надо именно циклично, тоесть задние элемеенты должны оказатся с переди, это важно для следуйщих расчетов.

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 10:16:22

Apparatchik писал(а):Выборки две, они набираются паралельно, на 400 элементов, но одну нужно сдвинуть относительно другой, обычно на 5-6 элементов, но может менятся. Сдвинуть надо именно циклично, тоесть задние элемеенты должны оказатся с переди, это важно для следуйщих расчетов.
да все понятно уже. все получается абсолютно без сдвигов
Код:
int16_t buf_U[400];
int16_t buf_I[400];

#define SDVIG    5

//обрабатываете свои буферы С УЧЕТОМ СДВИГА как-то так
uint16_t index_I=SDVIG;
int32_t sum;
for(int i=0; i<400; i++){
   sum += buf_U[i] * buf_I[index_I];
   if(++index_I >= 400) index_I = 0;
}
и не надо весь массив двигать, достаточно считывать из него со смещением.

Re: Вопросы по С/С++ (СИ)

Пт дек 22, 2017 10:34:20

Я Вашу мысль понял, но там есче нужно после сдвига сделать вот это (только не спрашивайте зачем):
Код:
   // пишем в первую половину массива разницу между первой и второй половиной,
   for (i = max_index / 2, j = i; i < max_index; i++) {
      current[i - j] -= current[i];
   }
   // во вторую половину пишем первую с противоположным знаком
   for (i = max_index / 2, j = i; i < max_index; i++) {
      current[i] = current[i - j] * (-1);
   }

И только потом массив тока и напряжения используются в расчетах вместе по элементно. Массив напряжения подготавливается отдельно, но там все проще и быстро.
Ответить