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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

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

Сообщение VladislavS »

Мне лень фигнёй заниматься. У тебя, судя по всему, IAR есть. Поставь оптимизацию на скорость и сам листинги смотри какие хочешь.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

Только ты с iar-овских листингов сам и начал.
Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.
Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

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

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Только ты с iar-овских листингов сам и начал.[/uquote]Я только недавно писал, что IAR для AVR это самый вменяемый инструмент. По листингу вижу, что он сделал то что я ожидал. Почему я не могу им пользоваться?

[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.[/uquote]Мне то до этого какое дело? Пишите в чём хотите.

[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.[/uquote]Я приводил сравнение??? Чьи "фирменные" тесты c того и спрашивай. А для начала научись компилятором пользоваться! Никогда не поверю, что GCC в 2 раза медленнее код делает. Попытай ARV, накрайняк, у него вроде проблем никогда не было.

На 8-битке, кстати, можно ещё побыстрей сделать, если не uint32_t использовать, а требуемые 24 бита. На глаз, такта на 4 меньше.
Спойлер

Код: Выделить всё

#include "stdint.h"

struct W24
{ 
  uint8_t b1;
  uint8_t b2;
  uint8_t b3;    
};

void foo(volatile W24 *w24, const uint32_t a, bool f)
{  
  uint16_t tmp = ((a&0xF800)<<1) | (f?(1L<<11):0) | (a&0x700);
  w24->b1=(a<<1)>>16; w24->b2=tmp>>8; w24->b3=a;
}

volatile W24 y;

int main()
{
  uint32_t  a=0;
  volatile bool f = true;
  
  while (1)
  {
    foo(&y,a,f);
    a++;
  }
}
ЗЫ: Кстати, ты там про битовые поля что-то двигал. Попробуй их на ARM, должно быть забористо.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

VladislavS писал(а):что GCC в 2 раза медленнее код делает.
Ну по чему медленнее, то ваше было, а вот 52 и 47, 40 и 36, мое. Не вижу тут в 2 раза, какие-то 11-12 тактов разница, в пользу iar.
VladislavS писал(а):Попробуй их на ARM, должно быть забористо.
Не думаю что там забористо будет, возможно будет значительно хуже.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

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

Сообщение VladislavS »

95/42 это больше чем 2 раза.
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

В моем случае я предоставил выбор компилятору, а как он на оптимизировал ... х бы его знал.
Вот на arm stm32f100rb
Спойлер

Код: Выделить всё

iar-arm
мой			его
51 такт	33		без inline
34			23		inline
измерены такты вместе с a++; на реальном чипе.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

братцы, что я делаю не так?

стоит задача: есть некая фигура, описанная точками на плоскости. надо повернуть эту фигуру относительно другой точки на заданный угол.


поворот точки относительно другой точки описывается такими выражениями:
x1=(x-x0)∗cos(ϕ)−(y-y0)∗sin(ϕ) + x0
y1=(x-x0)∗sin(ϕ)+(y-y0)∗cos(ϕ) + y0
, где (xy) - исходная точка, (x1y1) - результат поворота, а (x0y0) - точка, относительно которой делается поворот

формулы общеизвестны, однако, вместо поворота получается хрень...
проверяю:

Код: Выделить всё

#include <stdio.h>
#include <stdint.h>
#include <math.h>

#define CENTER 127

void rotate(int *x, int *y, float a){
	int tx = *x - CENTER;
	int ty = *y - CENTER;
	tx = tx * cos(a) - ty * sin(a);
	ty = tx * sin(a) + ty * cos(a);
	ty += CENTER;
	tx += CENTER;
	*x=tx; *y = ty;
}

int x, y;
int x0 = 127;
int y0 = 127;
float r;

int main(void) {
	// your code goes here
	for(uint8_t i = 0; i<60; i++){
		x = 127; y = 200;
		rotate(&x, &y, i * 3.1415 * 2 / 60);		
		rotate(&x0, &y0, i * 3.1415 * 2 / 60);
		r = sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y));
		printf("i=%d, x0=%d, y0=%d, x=%d, y=%d, r=%f\n", i,x0, y0, x, y, r);
	}
	return 0;
}
то есть тупо поворачиваю точку с определенным шагом, заодно вычисляю длину отрезка, соединяющего центр поворота и повернутую точку - если все хорошо, этот отрезок должен быть одинаковым. но он плавает, как говно в проруби!!!
i=0, x0=127, y0=127, x=127, y=200, r=73.000000
i=1, x0=127, y0=127, x=120, y=198, r=71.344238
i=2, x0=127, y0=127, x=112, y=195, r=69.634758
i=3, x0=127, y0=127, x=105, y=189, r=65.787537
i=4, x0=127, y0=127, x=98, y=181, r=61.294373
i=5, x0=127, y0=127, x=91, y=172, r=57.628117
i=6, x0=127, y0=127, x=85, y=161, r=54.037025
i=7, x0=127, y0=127, x=79, y=149, r=52.801514
i=8, x0=127, y0=127, x=73, y=135, r=54.589375
i=9, x0=127, y0=127, x=68, y=123, r=59.135437
i=10, x0=127, y0=127, x=64, y=109, r=65.520988
i=11, x0=127, y0=127, x=61, y=97, r=72.498276
i=12, x0=127, y0=127, x=58, y=84, r=81.301903
i=13, x0=127, y0=127, x=56, y=73, r=89.202019
i=14, x0=127, y0=127, x=55, y=64, r=95.671310
i=15, x0=127, y0=127, x=55, y=56, r=101.118744
i=16, x0=127, y0=127, x=55, y=48, r=106.887794
i=17, x0=127, y0=127, x=56, y=43, r=109.986366
i=18, x0=127, y0=127, x=58, y=39, r=111.825760
i=19, x0=127, y0=127, x=61, y=38, r=110.801628
i=20, x0=127, y0=127, x=64, y=36, r=110.679718
i=21, x0=127, y0=127, x=68, y=37, r=107.615051
i=22, x0=127, y0=127, x=73, y=39, r=103.247276
i=23, x0=127, y0=127, x=79, y=41, r=98.488579
i=24, x0=127, y0=127, x=85, y=44, r=93.021500
i=25, x0=127, y0=127, x=91, y=46, r=88.639717
i=26, x0=127, y0=127, x=98, y=49, r=83.216583
i=27, x0=127, y0=127, x=105, y=51, r=79.120163
i=28, x0=127, y0=127, x=112, y=53, r=75.504967
i=29, x0=127, y0=127, x=120, y=54, r=73.334846
i=30, x0=127, y0=127, x=127, y=55, r=72.000000
i=31, x0=127, y0=127, x=134, y=54, r=73.334846
i=32, x0=127, y0=127, x=142, y=53, r=75.504967
i=33, x0=127, y0=127, x=149, y=51, r=79.120163
i=34, x0=127, y0=127, x=156, y=49, r=83.216583
i=35, x0=127, y0=127, x=163, y=46, r=88.639717
i=36, x0=127, y0=127, x=169, y=44, r=93.021500
i=37, x0=127, y0=127, x=175, y=41, r=98.488579
i=38, x0=127, y0=127, x=181, y=39, r=103.247276
i=39, x0=127, y0=127, x=186, y=37, r=107.615051
i=40, x0=127, y0=127, x=190, y=36, r=110.679718
i=41, x0=127, y0=127, x=193, y=38, r=110.801628
i=42, x0=127, y0=127, x=196, y=39, r=111.825760
i=43, x0=127, y0=127, x=198, y=43, r=109.986366
i=44, x0=127, y0=127, x=199, y=48, r=106.887794
i=45, x0=127, y0=127, x=199, y=55, r=101.823380
i=46, x0=127, y0=127, x=199, y=64, r=95.671310
i=47, x0=127, y0=127, x=198, y=73, r=89.202019
i=48, x0=127, y0=127, x=196, y=84, r=81.301903
i=49, x0=127, y0=127, x=193, y=97, r=72.498276
i=50, x0=127, y0=127, x=190, y=109, r=65.520988
i=51, x0=127, y0=127, x=186, y=123, r=59.135437
i=52, x0=127, y0=127, x=181, y=135, r=54.589375
i=53, x0=127, y0=127, x=175, y=149, r=52.801514
i=54, x0=127, y0=127, x=169, y=161, r=54.037025
i=55, x0=127, y0=127, x=163, y=172, r=57.628117
i=56, x0=127, y0=127, x=156, y=181, r=61.294373
i=57, x0=127, y0=127, x=149, y=189, r=65.787537
вот тут все можно еще раз проверить: https://ideone.com/vdqbQx

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

Мой уютный бложик... заходите!
Аватара пользователя
JMC.Hard
Мучитель микросхем
Сообщения: 445
Зарегистрирован: Ср сен 16, 2020 20:38:41
Откуда: Краснодарский край, г.Абинск

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

Сообщение JMC.Hard »

Так исходные точки (x,y) не принадлежат одной окружности с радиусом в точке поворота ...
Изображение
... потому и r разные :wink:
Лучше сделать и жалеть, чем жалеть, что не сделал ...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
JMC.Hard
Мучитель микросхем
Сообщения: 445
Зарегистрирован: Ср сен 16, 2020 20:38:41
Откуда: Краснодарский край, г.Абинск

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

Сообщение JMC.Hard »

[uquote="ARV",url="/forum/viewtopic.php?p=4213531#p4213531"]... где (xy) - исходная точка, (x1y1) - результат поворота, а (x0y0) - точка, относительно которой делается поворот
...
i=0, x0=127, y0=127, x=127, y=200, r=73.000000
i=1, x0=127, y0=127, x=120, y=198, r=71.344238
i=2, x0=127, y0=127, x=112, y=195, r=69.634758
...
[/uquote]
Может что-то в консерватории подправить? (С) М.Жванецкий :)
Лучше сделать и жалеть, чем жалеть, что не сделал ...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

ну, в консерватории можно подправить... хотя по коду видно же, что сначала x и y присваиваются, а потом передаются в функцию поворота, и уже оттуда возвращаются с новыми (повернутыми) значениями, которые и выводтся
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

Сообщение da-nie »

tx = tx * cos(a) - ty * sin(a);
ty = tx * sin(a) + ty * cos(a);
У вас меняется tx. Так эти формулы не работают. Надо новые координаты запомнить в отдельных переменных.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Аватара пользователя
JMC.Hard
Мучитель микросхем
Сообщения: 445
Зарегистрирован: Ср сен 16, 2020 20:38:41
Откуда: Краснодарский край, г.Абинск

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

Сообщение JMC.Hard »

Мне, почему-то не совсем нравится:
rotate(&x, &y, i * 3.1415 * 2 / 60); где i - целое, а в функцию должен уйти float результат
Может, для уверенности rotate(&x, &y, float(i * 3.1415 * 2 / 60)); ?

Я однажды запал на такое:
(stepAngle -- float, stepFrame -- int)
причём:
stepAngle = 360/stepFrame;
и stepAngle = float(360/stepFrame);
давало мне совсем не то, что я в столбик посчитал :)
и только stepAngle = float(360.0/stepFrame) привело к тому, что было нужно.
Лучше сделать и жалеть, чем жалеть, что не сделал ...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

da-nie писал(а):У вас меняется tx
да чтоб меня!!! вот, блин, ступил, так ступил!!!
спасибо тебе, добрый человек!!! :beer: :beer: :beer:

Добавлено after 4 minutes 40 seconds:
было:


стало:


вот что крест животворящийвзгляд незамыленный делает! :)))

еще раз спасибо, da-nie!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7357
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

прошу подсказать, как вычислить время требуемое на то чтобы пройти заданное расстояние по формуле t=√S/(2*a). Проблема в квадратном корне. Но я вычитал, что на третьем кортексе быстрее всего целочисленное привести к флоату, взять корень и снова перевести в целочисленное. Но так как a у меня задаётся как изменение 0.01rpm за 2.5 мс (1r = 220mm)? формула получается такая: √(3000000 * S)/(11 * a). Так вот если я подкоренное выражение считаю целочисленным, то при S=800 (0.8 метра) я уже оказываюсь в переполнении. Как было бы лучше считать. Может эти 3 миллиона уже сделать флоатом и пусть всё считается в плавающей точке?

Пока сделал так. Хотя теряю немного точность - это не принципиально. Функция используется для расчета оптимального маршрута. Главное, чтобы результат был бы всегда повторяем. Но зато вызывается очень много раз.

Код: Выделить всё

int TimeToRunStraight(int distance) {  // in milliseconds from millimeters.
      return sqrt(3000000/11 * distance/data.acceleration);
}
data.acceleration сейчас порядка 100-200 и distance должна быть до 10 метров (но лучше пусть будет запас еще на порядок).
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

А если sqrt(3000000*x) воспринимать как 1000*sqrt(3*x)? 3000000 - это же константа, как я понял?

P.S. Хотя, точность будет теряться при целочисленных делениях и умножениях.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7357
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Увы, тогда точность упадёт грохнется. Так как результат будет всегда равен целым секундам. А у меня они как раз скачут в районе секунды - поворот 660мс, прямой участок 531мм - 1474мс итп. И главное, нельзя получить результатом 0 - алгоритм может зациклиться. Собственно, я так на это переполнение набрёл - получил в результате переполнения при умножении отрицательное число (задрал один параметр до максимального значения), квадратный корень из него дал 0 и алгоритм зациклился.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Ещё можно на в целочисленных вычислениях на int64_t перейти. Это несильно замедлит вычисления (по сравнению с floag).
Аватара пользователя
Viper_Snake
Электрический кот
Сообщения: 1046
Зарегистрирован: Вс мар 01, 2009 19:47:16
Откуда: Ростов-на-Дону

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

Сообщение Viper_Snake »

Ребята, приветствую, есть задача, которую я в принципе решил, но нужна консультация, может кто ее решил бы иначе или проще. Короче: имеем TM1628, задача - считать с него состояния кнопок в матрице с первой по двадцатую. Микросхема для этих целей имеет регистр размером в 5 байт, считывание производится последовательно. Все 5 байт мне не нужны, третий байт я не использую. Читаю с помощью команды shiftln, пишу в 4-хбайтную переменную.

Мой метод: переменной присваиваю значение 128, чтобы впоследствии иметь под рукой все 32 бита
Считываю в переменную первый байт (считываю по методу LSBFIRST, т. К в каждом регистре ТМ два последних бита всегда нулевые)
Сдвигаю биты в переменной на 8 бит влево
Читаю и записываю следующий бит тем же макаром.
Сдвигаю на 8
Третий (ненужный) бит просто читаю, никуда не записывая,
Четвертый читаю, пишу и сдвигаю, пятый просто читаю и пишу без сдвига.

В итоге имею набор из 32 бит с постоянным старшим в единице, который очень удобно разбирать при опросе кнопок, однако сама процедура считывания довольно громоздкая. Вопрос: можно ли упростить и оптимизировать? Код выложу позднее.

Добавлено after 26 minutes 16 seconds:
Вот код. Прошу сильно не пинать - пишу в среде ардуино, но не для ардуины, поэтому все же сюда настрочил - вроде как C, мать его.

СпойлерКод

Код: Выделить всё

void readTMData(unsigned long * data) {
  digitalWrite(PIN_STB, LOW);
  shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42);  //Команда на чтение регистров с ТМ1628
  pinMode(PIN_DIO, INPUT_PULLUP);
  delayMicroseconds(1);
  bitWrite(*data,7,1); // ставим 7-й бит в 1. После всех сдвигов он станет MSB. Маска ненажатых кнопок будет выглядеть как 10000000000000000000000000000000
  * data =*data+ shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали первый байт
  * data= * data<<8; // Сдвинули
   * data = *data+shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали второй байт
    * data= * data<<8; // Сдвинули
    shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Вот тут просто считали, никуда не записывая, чтобы не рвать последовательность чтения
     * data =*data+ shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали четвертый байт
     * data= * data<<8; // Сдвинули
   * data = *data+shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали пятый байт
  
  pinMode(PIN_DIO, OUTPUT);
  digitalWrite(PIN_STB, HIGH);
}
Не важно чем все начнется. Важно чем кончится!
veso74
Поставщик валерьянки для Кота
Сообщения: 1903
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

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

Сообщение veso74 »

Идея:

В:

Код: Выделить всё

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_shift.c
строка 25..38, посмотрите как написано shiftIn() для 8 бит. Напишите напр. локальную функцию (под другим именем) или просто перепишите логику для 4 * 8 бита (long) или больше (5 байт) (при этом, конечно, соблюдая разрядность новых типов данных - некоторые типы перейдут на uint64_t. А можете оптимизировать: до uint32_t, как написали напр. есть ненужный байт).

Код: Выделить всё

uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
	uint8_t value = 0;
	uint8_t i;

	for (i = 0; i < 8; ++i) {
		digitalWrite(clockPin, HIGH);
		if (bitOrder == LSBFIRST)
			value |= digitalRead(dataPin) << i;
		else
			value |= digitalRead(dataPin) << (7 - i);
		digitalWrite(clockPin, LOW);
	}
	return value;
}
Последний раз редактировалось veso74 Вт авг 02, 2022 21:20:44, всего редактировалось 1 раз.
Ответить

Вернуться в «Разные вопросы по МК»