Перейти к содержанию

STM32 для чайника


ART_ME

Рекомендуемые сообщения

Вы  - хозяин массива. Что захотите, то туда и запишете. Зачем данные в нём изначально переворачивать, чтобы потом наживать гемор с их обратным переворотом ?
И для чего вообще это всё ?

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

9 минут назад, Alex сказал:

Зачем данные в нём изначально переворачивать

Там ничего не перевернуто, там все как надо, первый байт это количество передаваемых данных DLC, следующие четыре это идентификатор посылки CAN шины, он 32 битный и может занимать 11 или 29 бит, поэтому и выделено 4 байта.

0x00,0x00,0x00,0xB4, это тойота  11 бит,   0x00,0xE2,0x40,0x26, это вольво 29 бит.  Именно так они должны лежать и ни как не по другому. В таком виде они и заносятся в регистры,   расширенного  hcan.pTxMsg->ExtId = id_data; ,  или стандартного  hcan.pTxMsg->StdId = id_data;   идентификаторов 

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Проблема в том что если применить memcpy то она и перевернет данные,  вот и пошел этот сыр бор с переворачиванием! По этому  memcpy можно использовать только в связке с  _REV(); тогда все работает как надо. Именно это я и пытаюсь доказать!

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

Изменено пользователем optima

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

Только что, optima сказал:

По этому  memcpy можно использовать только в связке с  _REV();

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

Ссылка на комментарий
Поделиться на другие сайты

Зачем? если считывая данные с CAN шины я вижу ID 580 то почему я должен его записать как 8005 вместо правильной записи 580 ?   Любое читаемое слово мы записываем именно так как оно есть, но ни как не наоборот.

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

Ну вот, уже считывание идёт. Я спрашивал же про массив. И Вы сказали, что создаёте его ручками, сами.

Если эти данные читаются откуда то уже в таком формате, то это уже другое дело...

Ссылка на комментарий
Поделиться на другие сайты

Блин, и все таки я не прав!  функция memcpy действительно ничего не переворачивает Вуйко был прав!

Только сейчас обратил внимание на 103 камне строка выглядит так  id_data = __REV(*(__IO uint32_t *)((uint32_t)&(moimassiv[l]) + 1));  Сразу не обратил внимание на присутствие __REV теперь все встало на свои места.

При переносе данных из 8 битного массива в 32 битный массив или переменную для правильного расположения байтов без функции __REV не обойтись.

 

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

7 часов назад, optima сказал:

функция memcpy действительно ничего не переворачивает Вуйко был прав!

Это - функция обычного побайтного копирования. Что она переворачивать должна ?
2 страницы Вам об этом твердят, а Вы заметили только пост Вуйко ? :lol2:

7 часов назад, optima сказал:

При переносе данных из 8 битного массива в 32 битный массив или переменную для правильного расположения байтов без функции __REV не обойтись.

Не знаю. Я обхожусь... Даже интересно, как ... Не расскажите секрета ?  :)

Ссылка на комментарий
Поделиться на другие сайты

В 8 битных массивах данные лежат 01 02 03 04  именно в этом виде нам и необходимы данные в 32 битной переменной, при копировании этих данных  получаем 04030201 четвертый байт становится старшим, а надо что бы он был младшим!

По этому и нужен __REV,   или любой другой метод реверса данных!  Вами же выше приведен пример, вот и поделитесь опытом, каким способом обойтись если необходимо перевернуть 32 битную переменную?

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

@optima , а покажите тело макроса __REV() ? Найти нигде не могу ... :unknw:

Надеюсь, там ни какая-нибудь подобная хрень :

(var<<24) | (var>>24) | ((var>>8)&0xFF00) | ((var<<8)&0xFF0000)

?
:wacko:

Ссылка на комментарий
Поделиться на другие сайты

Вообще, в таком случае, проще сделать как-нибудь так, топорно :


void uint32_copy_rev(uint32_t *var, uint8_t* buf){
    ((uint8_t*)var)[3] = buf[0];
    ((uint8_t*)var)[2] = buf[1];
    ((uint8_t*)var)[1] = buf[2];
    ((uint8_t*)var)[0] = buf[3];    
}

uint8_t        arr[]={0x00, 0x01, 0x02, 0x03, 0x04};
uint32_t       var;


uint32_copy_rev(&var, &arr[1]);

По времени выполнения, на нормальном камушке, займёт порядка 10 тактов. По-любому будет быстрей всяческих memcpy и реверсов.
Да и кэшу такой линейный код будет приятней обрабатывать.

Ссылка на комментарий
Поделиться на другие сайты

4 часа назад, Alex сказал:

Надеюсь, там ни какая-нибудь подобная хрень :

Думаю там ничего нового не придумали, посмотри cmsys_iar.h, или core_sm0.h во втором функция обзывается __CM0_REV.  Еще почитать можно тут

3 часа назад, Alex сказал:

проще сделать как-нибудь так, топорно

Согласен, думаю это будет лучший вариант попробую реализовать его, спасибо!

Сергей.

Ссылка на комментарий
Поделиться на другие сайты

__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
  return __builtin_bswap32(value);
#else
  uint32_t result;

  __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
  return(result);
#endif
}

Для GCC правда, а не для IAR.

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Проблема такая, прикупил f407 камень и начал изучать, и все вроде ничего, но вот с ЮАРТ проблема появилась, а именно не могу настроить альтернативные функции на PA9 PA10, для ЮАРТ    

IAR ругается на такую запись GPIO_AFR_AFRH9_2, находил в нете где просто присваивают значение всему регистру, типа что-то такого GPIOA->AFR [1]=0x00077, но тут не могу понять как его правильно записывать, если остальные ноги порта мне не нужно назначать как альтернативные функции то пишем нули?, тогда получается для PA9 PA10, нужна 7-я альтернативная функция - это 2-й 1-й и 0-й биты по 1, Screenshot_1.thumb.png.e00113abf05005bf2bdb6057d7fb8e49.png

тогда так что ли  GPIOA->AFR [1]=0b00000000000000000000011101110000, или GPIOA->AFR [1]=0x770  ?

И не понятно почему я не могу таким образом записать это побитно, так:

GPIOA->AFR |=GPIO_AFR_AFRH9_2|GPIO_AFR_AFRH9_1|GPIO_AFR_AFRH9_0|GPIO_AFR_AFRH10_2|GPIO_AFR_AFRH10_1|GPIO_AFR_AFRH10_0 ;//назначение альтернативных функций

Почему IAR пишет что не знает такого?

И еще вопрос почему при назначении скорости в регистре  GPIOx_OSPEEDR , если я напишу  GPIO_OSPEEDR- без буквы E между D  и R( вот так выделил красным где должна быть буква E:  GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR14_1, в слове OSPEEDER, то IAR ругается, а если с этой буквой все хавает, ведь в мануале, нигде об этом не написано, это ошибка разработчиков, или компилятора, или что- то другое?

Вот так без проблем работает:
 GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR14_1;//   GPIO_OSPEEDER-должна быть буква E между D  и R, в слове OSPEEDER

И еще вопрос на 103 камень нужно включать тактирование альтернативных функций, на 407 не нужно? Если я правильно понял.

 

Ссылка на комментарий
Поделиться на другие сайты

25 minutes ago, Электронщик said:

И не понятно почему я не могу таким образом записать это

Все обозначения типа OSPEEDER, прописываются не в мануале, а в подключаемых файлах типа stm32f4x_gpio.h. Если хитите их использовать, подключите их в свой проект.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...