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

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

isx писал(а):Использую в STM32 часовой кварц.
Тут не так давно обсуждалось. Генератор LSE у STM32 рассчитан на кварцы с load capacitance (CL) <=7 пФ. Подробности в даташите на конкретный камень, в разделе External clock source characteristics, во второй половине раздела (в первой идут материалы по HSE).

Практически, в продаже встречаются кварцы с CL = 6 пФ, но не так часто, как хотелось бы. Гораздо чаще продаются кварцы с CL = 12 пФ. По внешнему виду их не отличишь - спичка и спичка. Только вот с кварцами, у которых CL > 7 пФ, генератор LSE чипов STM32 работает крайне неустойчиво . Может не запускаться, может врать по частоте...

И взятый наугад кварц 32768, скорее всего, не будет 6-пикушечным. Да и китайцы на свои пробные платы тоже, бывает, лепят что попало, особенно на дешевые.

На Али 6-пФ кварцы ищутся по <32768 6pF>.

Добавлено after 20 minutes 36 seconds:
Да, разбираться с периферией STM32 надо не по даташиту, а по Reference manual'у на соответствующую серию камней.
Последний раз редактировалось afz Пт апр 26, 2019 14:29:05, всего редактировалось 1 раз.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Реклама
Опытный кот
Аватара пользователя
Сообщения: 819
Зарегистрирован: Вт окт 23, 2012 13:17:25
Откуда: Прокопьевск

Сообщение Oxford »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3612942#p3612942"]Где-то видел картинку, на ней была обозначена область ОЗУ, в конце самом стек, а куча лишь часть памяти, которая располагалось перед стеком. Так же тоже стеку некуда расти...[/uquote]

Куча не является обязательным для реализации приложения. Она в основном нужна для стандартной библиотеки Си для работы с динамическим распределением памяти типо malloc это обеспечивает переносимость кода.
Вы можете убрать ее и сохранить ОЗУ.

По стеку тут чтиво:
Overview of stack size requirement estimations in Cortex-M based applications
https://community.arm.com/developer/ip- ... plications
Инженер R@D

Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Контактная информация:
Реклама
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

[uquote="afz",url="/forum/viewtopic.php?p=3623315#p3623315"]Да, разбираться с периферией STM32 надо не по даташиту, а по Reference manual'у на соответствующую серию камней.[/uquote]
Я его и имел ввиду, просто по привычке RM даташитом обозвал :)
За информацию спасибо, проверю обязательно.

Добавлено after 1 minute 49 seconds:
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=3623061#p3623061"]Тут что-то по этому поводу было[/uquote]

Видел, но тут нет описания работы с регистрами (формулы вычисления и т.п).
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="Oxford",url="/forum/viewtopic.php?p=3623298#p3623298"]Сам конфиг выглядит так на CMSIS, это то что вы напридумывали:

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

GPIOA->CRL = GPIO_CRL_MODE0_0 | GPIO_CRL_CNF0 | GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1 | GPIO_CRL_MODE3_1 | GPIO_CRL_CNF3_1;
GPIOA->CRH = GPIO_CRH_MODE8_1 | GPIO_CRH_CNF13_1 | GPIO_CRH_CNF14_1;
[/uquote]
Крайне дерьмово он у вас выглядит. Нечитабельно. И после компиляции тоже хрень полная:

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

;GPIOA->CRL = GPIO_CRL_MODE0_0 | GPIO_CRL_CNF0 | GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1 | GPIO_CRL_MODE3_1 | GPIO_CRL_CNF3_1;
    4B06        ldr r3, =0x40010800
    F64A028D    movw r2, #0xA88D
    601A        str r2, [r3]

;GPIOA->CRH = GPIO_CRH_MODE8_1 | GPIO_CRH_CNF13_1 | GPIO_CRH_CNF14_1;
    4B04        ldr r3, =0x40010800
    4A04        ldr r2, =0x08800002
    605A        str r2, [r3, #4]
Через некоторое время забудете свой код и будете вспоминать как же вы там придумали конфигурировать,
Протрите глаза и сравните оба варианта:

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

/* 1. ================ */

  GPIOA->CRL = GPIO_CRL_MODE0_0 | GPIO_CRL_CNF0 | GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1 | GPIO_CRL_MODE3_1 | GPIO_CRL_CNF3_1;
  GPIOA->CRH = GPIO_CRH_MODE8_1 | GPIO_CRH_CNF13_1 | GPIO_CRH_CNF14_1;

/* 2. ================ */

  *(uint64_t *) GPIOA = (
    PIN_CFG(0,  O_AF + O_OD + O_10MHZ) |
    PIN_CFG(1,  I_PULL)                |
    PIN_CFG(2,  I_PULL)                |
    PIN_CFG(3,  O_AF + O_PP + O_2MHZ)  | 
    PIN_CFG(8,  O_2MHZ)                |
    PIN_CFG(13, I_PULL)                |
    PIN_CFG(14, I_PULL)
  );
Если и теперь не понимаете, что нагляднее и понятнее, то я не знаю, чем вам помочь.
и в сети вас не поймут.
Постарайтесь за себя говорить, а то выглядит, будто вы сами сомневаетесь в убедительности своих доводов.
Вы лучше аппаратуру, OS, драйверы изучайте и пишите хорошо. Книжки почитайте.
Не припоминаю, чтобы спрашивал у вас, чего мне лучше поучить и почитать. Держите ваши сверхценные советы при себе. Вам нужнее.
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3620645#p3620645"]Желаю слышать критику, чем вышеозначенный подход плох, если он действительно плох.[/uquote]Не буду касаться формы записи. Во-первых, это вкусовщина. Во-вторых, можно и лучше написать. Но я не об этом. Давай по технике.

Вот смотри. Твой код даёт.

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

4A0A        ldr r2, =0x40010800
F64A038D    movw r3, #0xA88D
4C09        ldr r4, =0x08800002
E9C23400    strd r3, r4, [r2, #0]
Казалось бы, всё круто. Но давай его сделаем "по классике". На форму записи закрываем глаза пока.

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

  GPIOA->CRL =                         
    PIN_CFG(0,  O_AF + O_OD + O_10MHZ) | /*  TIM2_CH1 PWM (OUTPUT, OPEN DRAIN, MEDIUM SPEEED)  */
    PIN_CFG(1,  I_PULL)                | /*  EXTI1 (INPUT, PULL-DOWN)                          */
    PIN_CFG(2,  I_PULL)                | /*  USART2 RX (INPUT, PULL-UP)                        */
    PIN_CFG(3,  O_AF + O_2MHZ)         | /*  USART2 TX (OUTPUT, PUSH-PULL, LOW SPEED)          */
    PIN_CFG(4,  I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(5,  I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(6,  I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(7,  I_ANALOG)              ; /*                                      - unused -    */    
  GPIOA->CRH =            
    PIN_CFG(0,  O_2MHZ)                | /*  GPIO (OUTPUT, PUSH-PULL, LOW SPEEED)              */
    PIN_CFG(1,  I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(2, I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(3, I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(4, I_ANALOG)              | /*                                      - unused -    */
    PIN_CFG(5, I_PULL)                | /*  SWDIO (INPUT, PULL-UP)                            */
    PIN_CFG(6, I_PULL)                | /*  SWCLK (INPUT, PULL-DOWN)                          */
    PIN_CFG(7, I_ANALOG)              ; /*                                      - unused -    */   
Получаем

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

LDR.N    R0,??PinCfg1_0   ;; 0x40010800
LDR.N    R2,??PinCfg1_0+0x4  ;; 0x8800002
MOVW     R1,#+43149
STR      R1,[R0, #+0]
STR      R2,[R0, #+4]
Размер кода такой же (команда STR 16-битная, а STRD 32-битная). Скорость исполнения по тактам посчитать (с учётом работы конвейера и разных шин) не берусь, но что-то мне подсказывает...

Так что, остаётся только удобство записи. Оно, конечно же, на порядок лучше чем предлагает Oxford, но работать ещё есть над чем :)
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Подключаю Wiznet5300 по параллельной шине 16 бит

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

/*-- FSMC Configuration ------------------------------------------------------*/

p.FSMC_AddressSetupTime = 3;

p.FSMC_AddressHoldTime = 2;

p.FSMC_DataSetupTime = 3;

p.FSMC_BusTurnAroundDuration = 1;

p.FSMC_CLKDivision = 1;

p.FSMC_DataLatency = 0;

p.FSMC_AccessMode = FSMC_AccessMode_A;

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //8-bit Wiznet DATA line
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

/*!< Enable FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);



Чтение заработало (первого регистра с адресом 0)
теперь делаю запись

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

#define SHAR_M            (0x60000008)
*(uint16_t *)SHAR_M = 0xFFFF;
Осциллографом смотрю а на линиях данных нули прут :shock:, причем одна линия в 1 даже если пишешь туда 0
Адрес выставляется правильно проверил.
Что не так делаю ?

PS: Железо рабочее, сначала подрыгал пинами отдельно и инициализировал w5300.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Клоки включать надо раньше чем начинаешь инициализировать периферию. И пины все в альтернативную функцию перевёл?
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Точно благодарю, так и знал что где-то в элементарном косячу.
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3626174#p3626174"]Не буду касаться формы записи. Во-первых, это вкусовщина. Во-вторых, можно и лучше написать.[/uquote]
Можно подробнее с этого места?

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

LDR.N    R0,??PinCfg1_0   ;; 0x40010800
LDR.N    R2,??PinCfg1_0+0x4  ;; 0x8800002
MOVW     R1,#+43149
STR      R1,[R0, #+0]
STR      R2,[R0, #+4]
Размер кода такой же (команда STR 16-битная, а STRD 32-битная). Скорость исполнения по тактам посчитать (с учётом работы конвейера и разных шин) не берусь, но что-то мне подсказывает...
Я бы на вашем месте не слишком доверял подобным нелокализуемым "подсказкам". У кортекса-м3 обе названных команды 32-битные, где первая выполняется 2 цикла, а вторая 3.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="a5021",url="/forum/viewtopic.php?p=3626379#p3626379"]У кортекса-м3 обе названных команды 32-битные, где первая выполняется 2 цикла, а вторая 3.[/uquote]
STR пайплайнятся, STRD - нет, так что скорее всего пара STR тоже выполнится за 3 такта. И, кстати, STRD не атомарна.
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Две STR атомарны? К чему это уточнение?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

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

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3626379#p3626379"]Можно подробнее с этого места?[/uquote]Нельзя. Не хочу в очередной раз ссориться на ровном месте.

[uquote="a5021",url="/forum/viewtopic.php?p=3626379#p3626379"]Я бы на вашем месте не слишком доверял подобным нелокализуемым "подсказкам". У кортекса-м3 обе названных команды 32-битные, где первая выполняется 2 цикла, а вторая 3.[/uquote]Нет оснований не доверять компилятору.
Изображение
str.png
(16.45 КБ) 784 скачивания
А если учесть, что это одноразовая инициализация, то удобство записи важно, размер кода тоже имеет значение, а вот разница в несколько тактов на 72 МГц это десятки наносекунд. Вообще ни о чём. Частенько наоборот приходится десятки миллисекунд ждать пока вся схема оживёт и закончатся переходные процессы.
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

Так понял, что возражения если и есть, то касаются они третьестепенных деталей. Это хорошо.

В качестве средства для развития алгоритмического воображения, предлагаю определить, что делает нижеследующий алгоритм, будучи запущенным на F103 c частотой 72мгц.

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

void main(void) {

  RCC->APB1ENR = RCC_APB1ENR_TIM2EN;
  RCC->APB2ENR = RCC_APB2ENR_IOPCEN;

  TIM2->ARR = GPIO_ODR_ODR13 * 2;
  TIM2->PSC = SystemCoreClock / (GPIO_ODR_ODR13 * 2) - 1;
  TIM2->CR1 = TIM_CR1_CEN;

  GPIOC->CRH = GPIO_CRH_MODE13_0;

  for(__O int *i = &GPIOC->ODR;; *i = TIM2->CNT & GPIO_ODR_ODR13);

}
Что изменится, если цифру 3 везде заменить на 4 ?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3626679#p3626679"]что делает нижеследующий алгоритм[/uquote]Для начала, лишает автора премии. Затем, если компилятор принципиальный, то

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

Error[Pe144]: a value of type "uint32_t volatile *" cannot be used to initialize an entity of type "int volatile *"
И только если уговорить компилятор, то 1 Гц на выходе. В чём вопрос то? Причём тут "алгоритмическое воображение", если тут надо тупо знать регистры конкретного чипа?
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

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

Сообщение VladislavS »

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

for(__O int *i = &GPIOC->ODR;; *i = TIM2->CNT & GPIO_ODR_ODR13);
Вот с этой хренью не справился?

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

//for(__O int *i = &GPIOC->ODR;; *i = TIM2->CNT & GPIO_ODR_ODR13);
        LDR.N    R0,??main_0      ;; 0x4001100c
        LDR.N    R1,??main_0+0x4  ;; 0x40000024
??main_1:
        LDR      R2,[R1, #+0]
        AND      R2,R2,#0x2000
        STR      R2,[R0, #+0]
        B.N      ??main_1
Ну, да, конечно.

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

for(;;) GPIOC->ODR = TIM2->CNT & GPIO_ODR_ODR13;
Найди отличие

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

        LDR.N    R0,??main_0      ;; 0x4001100c
        LDR.N    R1,??main_0+0x4  ;; 0x40000024
//for(;;) GPIOC->ODR = TIM2->CNT & GPIO_ODR_ODR13;
??main_1:
        LDR      R2,[R1, #+0]
        AND      R2,R2,#0x2000
        STR      R2,[R0, #+0]
        B.N      ??main_1
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Сообщение a5021 »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3626839#p3626839"]Вот с этой хренью не справился?[/uquote]
Вообще ни с чем. Конкретный вопрос был задан в самом начале. Вместо ответа на него, вы блистаете азами владения средой разработки. Из исходного кода смогли получить листинг дизасемблера. Ну тоже наверное достижение.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

Эй, котаны! https://www.youtube.com/watch?v=JqDCFxEmPIU
теперь куб прямо в среду встроен :)))
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="a5021",url="/forum/viewtopic.php?p=3626862#p3626862"]Конкретный вопрос был задан в самом начале.[/uquote]Ну давай почитаем конкретный вопрос.
В качестве средства для развития алгоритмического воображения, предлагаю определить, что делает нижеследующий алгоритм, будучи запущенным на F103 c частотой 72мгц.
И почитаем конкретный ответ[uquote="VladislavS",url="/forum/viewtopic.php?p=3626725#p3626725"]И только если уговорить компилятор, то 1 Гц на выходе.[/uquote]

[uquote="a5021",url="/forum/viewtopic.php?p=3626862#p3626862"]Вместо ответа на него, вы блистаете азами владения средой разработки. Из исходного кода смогли получить листинг дизасемблера. Ну тоже наверное достижение.[/uquote]А это чтобы у тебя не было возможности юлить и фантазировать, что там что-то "волшебное" происходит. И что даже эту глупость без ошибки не смог написать. Ну вот объясни, зачем было марать нам мониторы вот этой какашкой

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

for(__O int *i = &GPIOC->ODR;; *i = TIM2->CNT & GPIO_ODR_ODR13);
вместо понятного и ошибкоустойчивого

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

for(;;) GPIOC->ODR = TIM2->CNT & GPIO_ODR_ODR13;
???
Ответить

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