Мелкие вопросы по МК и ПЛИС.

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

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

Что то не пойму:
Перенёс проект из Atollic в IAR и теперь IAR'у не нравится такой #define:

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

#define SPI_Tx  while (SPI1->SR & SPI_SR_BSY); SPI1->DR = (uint16_t)
а код такой:

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

SPI_Tx (data|0x00);
ошибка такая:
Error[Pe018]: expected a ")" D:\My designs\PJT\IAR\Nokia_1616.c 101
А такой код:

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

SPI_Tx 0x11;
его устраивает.

Как переписать дефайн, чтобы заработало?
Макрофункцией? Тоже не работает (data|0x00);

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

#define SPI_Tx(cd)  while (SPI1->SR & SPI_SR_BSY); SPI1->DR = (uint16_t)cd

SPI_Tx(0x11);
есть ещё способы?

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

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

[uquote="Chettuser",url="/forum/viewtopic.php?p=3695815#p3695815"]Как переписать дефайн, чтобы заработало?[/uquote]Оба варианта рабочие. Ошибка скорее всего где-то в другом месте по коду выше. Это и есть слабое место макросов - плохо отлаживать. Во втором варианте аргумент cd надо в скобки взять.

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

#define SPI_Tx(cd)  while (SPI1->SR & SPI_SR_BSY); SPI1->DR = (uint16_t)(cd)
[uquote="Chettuser",url="/forum/viewtopic.php?p=3695815#p3695815"]есть ещё способы?[/uquote]Функцию надо оформлять функцией и не парить себе мозги.

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

static inline void SPI_Tx(uint32_t cd)
{
  while (SPI1->SR & SPI_SR_BSY); 
  *(uint16_t *)&SPI1->DR = cd;
}
Обрати внимание, я включил интуицию и предположил, что тебе нужна 16-битная операция записи в регистр SPI->DR. Это делается так как у меня в функции, а не как у тебя в макросе. Ну и (data|0x00) это прикол такой? :)

ЗЫ: На самостоятельную проработку предлагаю подумать что будет с таким применением твоего макроса и функции.

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

if(data==0xAA)
  SPI_Tx(data|0x01);
else
  SPI_Tx(data|0x02);
Поэтому макрос вообще правильно вот так

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

#define SPI_Tx(cd)  do{while (SPI1->SR & SPI_SR_BSY); SPI1->DR = (uint16_t)(cd);}while(false)
Последний раз редактировалось VladislavS Пт сен 06, 2019 21:49:53, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение ARV »

а, извиняюсь, чего вы хотели добиться вот этим data|0x00 ?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

А ещё вот так можно сделать

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

template<typename T>
static inline void SPI_Tx(uint32_t data)
{  
  while (SPI1->SR & SPI_SR_BSY); 
  *(T*)&SPI1->DR = data;
}
Или даже лучше вот так

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

template<typename T>
static inline void SPI_Tx(uint32_t data)
{  
  static_assert(std::is_same_v<T,uint8_t> || std::is_same_v<T,uint16_t>, "User fool");
  while (SPI1->SR & SPI_SR_BSY); 
  *(T*)&SPI1->DR = data;
}

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

  if(x>255)
    SPI_Tx<uint16_t>(x);
  else
    SPI_Tx<uint8_t>(x);
Всё контролируется и диагностируется на этапе компиляции, всё инлайнится и оптимизируется - красота.
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

data|0x00 - по шаблону написал, на время отладки, чтобы не путаться.
Всё оказалось просто - в IAR нет поддержки записи двоичных чисел. GCC судя по всему поддерживает.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3695868#p3695868"]Функцию надо оформлять функцией и не парить себе мозги.

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

static inline void SPI_Tx(uint32_t cd)
{
  while (SPI1->SR & SPI_SR_BSY); 
  *(uint16_t *)&SPI1->DR = cd;
}
[/uquote]
Конечно, только эта функция не рабочая, volatile нельзя пропускать:

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

static inline void SPI_Tx(uint32_t cd)
{
  while (SPI1->SR & SPI_SR_BSY) {}
  *(volatile uint16_t*)&SPI1->DR = cd;
}
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

[uquote="Chettuser",url="/forum/viewtopic.php?p=3696000#p3696000"]Всё оказалось просто - в IAR нет поддержки записи двоичных чисел. GCC судя по всему поддерживает.[/uquote]Вот так новость, а мы пользуемся и не подозреваем.

[uquote="Reflector",url="/forum/viewtopic.php?p=3696015#p3696015"]Конечно, только эта функция не рабочая, volatile нельзя пропускать:[/uquote]Согласен, просто IAR такие вещи "прощает" и при компиляции им эта функция рабочая. А так да, volatile, конечно же.
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3696100#p3696100"]а мы пользуемся и не подозреваем.[/uquote]
Я переправил 0b100000000 на 0x100 и заработало, ЧЯДНТ?

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

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Вот кусок из рабочего проекта

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

enum class STM32F1_PinMode : uint32_t
{
  NotDefined = 0x12345678,
  // ODR[4] : CNF[3:2] : MODE[1:0]
  Floating                    = 0b0'01'00, // 0x04
  PullUp                      = 0b1'10'00, // 0x18
  PullDown                    = 0b0'10'00, // 0x08
  // Analog mode
  Analog                      = 0b0'00'00, // 0x00
  // Output Open Drain modes
  OpenDrain_LowSpeed          = 0b0'01'10, // 0x06
  OpenDrain_MediumSpeed       = 0b0'01'01, // 0x05
  OpenDrain_HighSpeed         = 0b0'01'11, // 0x07
  // Output Push-Pull modes
  PushPull_LowSpeed           = 0b0'00'10, // 0x02
  PushPull_MediumSpeed        = 0b0'00'01, // 0x01
  PushPull_HighSpeed          = 0b0'00'11, // 0x03
  // Alternate Function Open Drain modes
  AF_OpenDrain_LowSpeed       = 0b0'11'10, // 0x0E
  AF_OpenDrain_MediumSpeed    = 0b0'11'01, // 0x0D
  AF_OpenDrain_HighSpeed      = 0b0'11'11, // 0x0F
  // Alternate Function Push-Pull modes
  AF_PushPull_LowSpeed        = 0b0'10'10, // 0x0A
  AF_PushPull_MediumSpeed     = 0b0'10'01, // 0x09
  AF_PushPull_HighSpeed       = 0b0'10'11  // 0x0B
};
ЧМДНТ?

Попробуй вот это скомпилировать

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

int main()
{
  [](){[](){[](){[](){[](){}();}();}();}();}();
  for(;;);
}
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Reflector »

[uquote="Chettuser",url="/forum/viewtopic.php?p=3696000#p3696000"]Всё оказалось просто - в IAR нет поддержки записи двоичных чисел. GCC судя по всему поддерживает.[/uquote]
Не gcc, а С++14.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Тссс, я плавно подвожу либо к включению С++ режима компилятора, либо обновлению последнего. Но я уже даже забыл когда он С++14 не поддерживал и где такую древнюю версию можно откопать.
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3696152#p3696152"]и где такую древнюю версию можно откопать.[/uquote]
С официального сайта с ограничением )
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Ну версию то хоть озвучь, что-ли...
Chettuser

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Chettuser »

IAR Embedded Workbench for ARM 8.40.1.21539 - свежак ) Ещё мухи не снош..сь!
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Тогда поставь галку С++ в настройках проекта раз и навсегда и не пудри нам мозги.
Аватара пользователя
smalcom
Встал на лапы
Сообщения: 128
Зарегистрирован: Пн фев 08, 2016 10:57:14

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение smalcom »

*(T*)&SPI1->DR = data;
Потенциальный источник ошибок. Лучше правую часть приводить к левой:
"*(volatile uint16_t*)&SPI1->DR = cd;" => "SPI1->DR = (decltype(SPI1->DR))cd;" или просто "SPI1->DR = (uint16_t)cd;"; эстеты могут использовать static_cast.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Нет, так не прокатит. Регистр SPI_DR чувствителен к разрядности команды записи в него. Правая часть автоматом из uint32_t во время записи командой STRH или STRB обрежется до необходимых 16 и 8 бит.

Насчёт volatile при записи по указателю надо бы стандарт почитать на досуге. Iar, например, "понимает", что если я пишу по указателю, то это не просто так.

Добавлено after 7 hours 2 minutes 45 seconds:
Проделел эксперимент.

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

  *(uint8_t *)&SPI1->DR = 0xA0;
  *(uint8_t *)&SPI1->DR = 0xA1;
  *(uint8_t *)&SPI1->DR = 0xA2;
  *const_cast<uint8_t *>((uint8_t *)&SPI1->DR) = 0xA3;
  *const_cast<uint8_t *>((uint8_t *)&SPI1->DR) = 0xA4;
  *const_cast<uint8_t *>((uint8_t *)&SPI1->DR) = 0xA5;
  *(volatile uint8_t *)&SPI1->DR = 0xA6;
  *(volatile uint8_t *)&SPI1->DR = 0xA7;
  *(volatile uint8_t *)&SPI1->DR = 0xA8;
IAR делает 9 операций записи, GCC три. Комментарии излишни.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3697189#p3697189"]IAR делает 9 операций записи, GCC три. Комментарии излишни.[/uquote]
Кстати, volatile не работает в constexpr контексте, потому из языка его выпиливают, в С++20 большинство volatile уже deprecated, вместо него предлагают использовать функции volatile_load/store(), как в Rust.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Мелкие вопросы по МК и ПЛИС.

Сообщение VladislavS »

Ну чтож, будем загонять регистры в классы и продолжать пользоваться присваиваниями :)
Ответить

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