STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3491764#p3491764"]Это не магические числа, а реальные коэффициенты деления. Можно подумать, задавая поразрядно эти магические числа ты много меняешь.[/uquote]
Неинформативность волшебных чисел -- только часть проблемы. Другая -- это неустойчивость к дефектам ввода (набора). Вместо 96 можно опечататься и ввести 95. Компилятор это проглотит молча, а в глаза такие опечатки не очень бросаются.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3491764#p3491764"]

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

RCC->PLLCFGR = _RCC_PLLCFGR_PLLQ(4) | RCC_PLLCFGR_PLLSRC_HSE | RCC_PLLCFGR_PLLP_div2 | _RCC_PLLCFGR_PLLN(96) | _RCC_PLLCFGR_PLLM(4);
Никакие это не магические числа, а Q=4, N=96 и M=4. Куда уж понятней? Нафига их поразрядно задавать?[/uquote]
Итого у нас есть Q, N, M, P и частота кварца на основе которых нужно получить пару частот. Думаю многие над такой задачкой зависнут минут на 10 и при этом не будут уверены, что подобрали коэффициенты правильно :)
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3491825#p3491825"]Вместо 96 можно опечататься и ввести 95.[/uquote]С дуру и хрен сломать можно. Можно подумать вместо 0 нельзя 1 поставить в твоих битах. Ошибиться в 5 местах (битах) легче чем в одном!

[uquote="Reflector",url="/forum/viewtopic.php?p=3491827#p3491827"]Думаю многие над такой задачкой зависнут минут на 10 и при этом не будут уверены, что подобрали коэффициенты правильно :)[/uquote]Я вполне уверен в своих силах и способности просчитать вручную, но всё равно пользуюсь интерактивными тулзами для этого.
cl.jpg
(57.43 КБ) 452 скачивания
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3491850#p3491850"]С дуру и хрен сломать можно.[/uquote]
Хорошо бы еще и вы это себе отчетливо представляли.
Можно подумать вместо 0 нельзя 1 поставить в твоих битах. Ошибиться в 5 местах (битах) легче чем в одном!
Ошибиться, но не опечататься. А в вашей записи и ошибиться и опечататься.
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3491850#p3491850"]Я вполне уверен в своих силах и способности просчитать вручную, но всё равно пользуюсь интерактивными тулзами для этого.
cl.jpg
[/uquote]
Я же тебе показывал функцию вызов которой выглядит следующим образом:

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

initPll(PllSrc::Hse, 200);
которая еще и частоту USB задает с наименьшей погрешностью и компилируется это все в 3 инструкции. Вместо нее у тебя 3 макроса которыми можно задать 3 константы, но т.к. все равно не очевидно какие частоты получаются после их комбинации, то нужно еще их же прописать в кубе... Это точно проще? :)
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3491854#p3491854"]А в вашей записи и ошибиться и опечататься.[/uquote]
Изображение
ushi.jpg
(26.52 КБ) 767 скачиваний
[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]Я же тебе показывал функцию вызов которой выглядит следующим образом:

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

initPll(PllSrc::Hse, 200);
[/uquote]Это всё замечательно, если у тебя есть время на каждый чих функцию писать. На это надо далеко не 10 минут. А где в этой функции учтено, что выходов у PLL несколько? Мне частоту pll для этого проца надо один раз в жизни задать. Как раз 10 мин почитать RM, потыкать в кубе и перенести в код.

[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]Вместо нее у тебя 3 макроса которыми можно задать 3 константы[/uquote]Макрос стандартный CMSIS-овский.

[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]но т.к. все равно не очевидно какие частоты получаются после их комбинации, то нужно еще их же прописать в кубе... Это точно проще? :)[/uquote]Ты путаешь последовательность. Сначала в кубе ставишь нужную частоту, он сам расставляет все делители. Тут же видишь точные частоты всех узлов и если они тебя устраивают - переносишь в код. И никак не наоборот.

[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]которая еще и частоту USB задает с наименьшей погрешностью[/uquote]А вот как, кстати, ты определяешь что погрешность достаточная? Вот поставил я на PLL и проц 100 МГц. Твоя функция честно 50 МГц на USB поставила и что дальше?

[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]и компилируется это все в 3 инструкции.[/uquote]У меня скомпилируется в две, потому что предыдущей командой я включал HSE и адрес RCC уже лежит в регистре :)
Реклама
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="Reflector",url="/forum/viewtopic.php?p=3491878#p3491878"]Я же тебе показывал функцию вызов которой выглядит следующим образом:[/uquote]
А можно повторить ? Я то ли пролистал по невнимательности, то ли еще каким образом не заметил, а теперь мне любопытно стало, но боюсь, что не найду.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3491881#p3491881"]Это всё замечательно, если у тебя есть время на каждый чих функцию писать. На это надо далеко не 10 минут.[/uquote]
Это не каждый чих, это функция которая будет использоваться в каждом проекте минимум один раз и если ее можно сделать простой, то обычно это и нужно сделать.
А где в этой функции учтено, что выходов у PLL несколько?
Второй выход - 48 MHz, можно лишь пытаться получить максимально приближенную к этой частоту, что и происходит автоматически.
Мне частоту pll для этого проца надо один раз в жизни задать.
Ага, с портами было то же самое :)
Макрос стандартный CMSIS-овский.
Не знаю, зашел в папку с хедерами, там все для всех серий, включая HAL/SPL, дал поиск по _RCC_PLLCFGR_PLLN и ничего не нашло...
Ты путаешь последовательность. Сначала в кубе ставишь нужную частоту, он сам расставляет все делители. Тут же видишь точные частоты всех узлов и если они тебя устраивают - переносишь в код. И никак не наоборот.
Порядок другой, суть не меняется. Код достаточно явно выражающий свои намерения даже без комментариев и позволяющий легко менять частоты на ходу определенно лучше кода в который подставляются константы из некой тулзы, где без комментариев о выставленных частотах можно только гадать.

[uquote="a5021",url="/forum/viewtopic.php?p=3491961#p3491961"]А можно повторить ? Я то ли пролистал по невнимательности, то ли еще каким образом не заметил, а теперь мне любопытно стало, но боюсь, что не найду.[/uquote]
Это на другом форуме было. На самом деле речь шла о классе, что совершенно не важно, т.к. функция все равно статическая:
Спойлер

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

enum class PllSrc { Hsi = 0, Hse = RCC_PLLCFGR_PLLSRC_HSE };

static void init(PllSrc clkSrc, uint32_t freq)	// 50..371 MHz
{
	uint32_t clkSrcFreq = (clkSrc == PllSrc::Hsi) ? 16 : HseValue / 1'000'000;
	uint32_t prediv = clkSrcFreq / 2;
	uint32_t usbdiv = (2 * freq + 24) / 48;
	RCC->PLLCFGR = uint32_t(clkSrc) | prediv | (freq << RCC_PLLCFGR_PLLN_Pos) | (usbdiv << RCC_PLLCFGR_PLLQ_Pos);
}
Кварц должен быть 4/8/12/16 MHz, т.к. входная частота приводится к рекомендуемым 2MHz...
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Reflector",url="/forum/viewtopic.php?p=3491981#p3491981"]Не знаю, зашел в папку с хедерами, там все для всех серий, включая HAL/SPL, дал поиск по _RCC_PLLCFGR_PLLN и ничего не нашло...[/uquote]Это потому что ты видишь то что хочешь увидеть. Пару строк выше был макрос _VAL2FLD из CMSIS. По большому счёту, можно им и ограничиться. _RCC_PLLCFGR_PLLN совершенно бесхитростно доопределяется для гурманов.

[uquote="Reflector",url="/forum/viewtopic.php?p=3491981#p3491981"]На самом деле речь шла о классе[/uquote]Ты же знаешь, что я за классы там где они приносят пользу. Но сконфигурить RCC это десяток строк сниппетса, а не десять экранов классов.
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

[uquote="a5021",url="/forum/viewtopic.php?p=3491273#p3491273"]На хабре появилась статеечка, как ручками через регистры сконфигурировать тактирование на STM32H7. Никогда ранее с седьмой серией не сталкивался, но что и зачем делает автор в общих чертах понятно. Кроме одного момента:

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

//PLLM = 4
	RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_5; //0
	RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_4; //0
	RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_3; //0
	RCC -> PLLCKSELR |=  RCC_PLLCKSELR_DIVM1_2; //1
	RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_1; //0
	RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1_0; //0
Занесение значения в регистр RCC_PLLCKSELR зачем-то разбито аж на шесть шагов. Никто не в курсе, зачем все это и почему нельзя было написать просто

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

RCC -> PLLCKSELR =  RCC_PLLCKSELR_DIVM1_2;
?[/uquote]

Человек как смог так и сделал. Это не учебное пособие по программированию.
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Чет как-то жиденько он смог. Непонятно, зачем такую бурду на хабре публиковать.
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

Ну да, можно было как то так сделать это дело.

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

  RCC->PLLCKSELR = 
  	_VAL2FLD(RCC_PLLCKSELR_PLLSRC, 2) |
	  _VAL2FLD(RCC_PLLCKSELR_DIVM1, 4) |
	  _VAL2FLD(RCC_PLLCKSELR_DIVM2, 32) |
	  _VAL2FLD(RCC_PLLCKSELR_DIVM3, 32);
:tea:
Последний раз редактировалось Oxford Сб окт 27, 2018 00:03:10, всего редактировалось 1 раз.
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Сегодня здесь день волшебных чисел видать.
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

a5021, вам непонятен мой код? Почему волшебные? Самые обычные числа
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Мне непонятно, чем ваше лучше такого:

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

RCC->PLLCKSELR = RCC_PLLCKSELR_PLLSRC_HSE | RCC_PLLCKSELR_DIVM1_2 | RCC_PLLCKSELR_DIVM2_5 | RCC_PLLCKSELR_DIVM3_5;
?
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

Вы складываете побитово, запись длинная и не сразу можно понять что складывается и для чего, какие поля, какие значения, нужно сидеть внимательно читать код высчитывать, просмотреть всю запись и не пропустить бит.
В моем случае используется макрос ПОЛЕ-ЗНАЧЕНИЕ, если вы посмотрите на регистр он имеет 5 полей. В макрос передается название поля и его параметр. К примеру вам надо по даташиту в поле установить 110110, вместо длинной цепочки битов, вы просто передаете в макрос 54.

Так же макросы логически разбивают на блоки настройку регистров, восприятие кода легче и приятнее.

Например:
_VAL2FLD(RCC_PLLCKSELR_PLLSRC, 2)

Означает установить в поле PLLSRC значение 2 (10: HSE selected as PLL clock (hse_ck))

Такая запись не создает путаницы, улучшает понимание кода, уменьшает ошибки. Более эффективный кодинг.

Но, отдельные биты тоже используются, например если требуется просто сбросить бит или установить. По ситуации надо смотреть.

Эти макросы сообщество узнало от меня, показывал как проще и быстрее прогать на CMSIS.
Их придумали не для красоты.
:tea:
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Это чё, он сейчас будет доказывать, что в этой простой и понятной записи магические числа, легко ошибиться и ничего не понятно

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

//Настройка PLL: тактирование от HSE, Q=4, P=2, N=96, M=4
RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC_HSE | _RCC_PLLCFGR_PLLQ(4) | RCC_PLLCFGR_PLLP_div2 | _RCC_PLLCFGR_PLLN(96) | _RCC_PLLCFGR_PLLM(4);
Зато вот в этом непотребстве, которое под спойлер на приличных форумах положено прятать, всё понятно, магических чисел нет и хрен ошибёшься.

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

RCC->PLLCFGR = (
   0 * RCC_PLLCFGR_PLLSRC_HSI  |
   1 * RCC_PLLCFGR_PLLSRC_HSE  |

   0 * RCC_PLLCFGR_PLLQ_0      |
   0 * RCC_PLLCFGR_PLLQ_1      |
   1 * RCC_PLLCFGR_PLLQ_2      |
   0 * RCC_PLLCFGR_PLLQ_3      |
   
   1 * RCC_PLLCFGR_PLLP_div2   |
   0 * RCC_PLLCFGR_PLLP_div4   |
   0 * RCC_PLLCFGR_PLLP_div6   |
   0 * RCC_PLLCFGR_PLLP_div8   |
       
   0 * RCC_PLLCFGR_PLLN_0      |
   0 * RCC_PLLCFGR_PLLN_1      |
   0 * RCC_PLLCFGR_PLLN_2      |
   0 * RCC_PLLCFGR_PLLN_3      |
   0 * RCC_PLLCFGR_PLLN_4      |
   1 * RCC_PLLCFGR_PLLN_5      |
   1 * RCC_PLLCFGR_PLLN_6      |
   0 * RCC_PLLCFGR_PLLN_7      |
   0 * RCC_PLLCFGR_PLLN_8      |

   0 * RCC_PLLCFGR_PLLM_0      |
   0 * RCC_PLLCFGR_PLLM_1      |
   1 * RCC_PLLCFGR_PLLM_2      |
   0 * RCC_PLLCFGR_PLLM_3      |
   0 * RCC_PLLCFGR_PLLM_4      |
   0 * RCC_PLLCFGR_PLLM_5
 );
Кому-то явно построчно за работу платят. :kill:

PS: Если кто-то скажет, что неCMSIS-овские макросы применяю, то милости просим под спойлер
СпойлерМакрос _VAL2FLD мне не шибко нравится. Единственный его плюс, что он есть в CMSIS и код переносимый получается. Я же не ленюсь и доопределяю макросы по настроению, либо так

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

#define _RCC_PLLCFGR_PLLQ(value)            ((RCC_PLLCFGR_PLLQ_Msk & ((value) << RCC_PLLCFGR_PLLQ_Pos)))
либо так

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

#define _RCC_PLLCFGR_PLLQ(value)            _VAL2FLD(RCC_PLLCFGR_PLLQ,(value))
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3492435#p3492435"]Зато вот в этом непотребстве [...] всё понятно, магических чисел нет и хрен ошибёшься.[/uquote]
Именно так. Если вы этого не понимаете, мои вам соболезнования.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

А ошибку которую я специально внёс в это непотребство заметил? :)
Друг Кота
Сообщения: 6457
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Даже не смотрел. Это же ваше непотребство, вам и отвечать.
Ответить

Вернуться в «ARM»