Сергей Борщ 134 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба Имеем руководство пользователя для STM32F030, STM32F070. Смотрим картинку тактирования F070: Читаем описание: Уже странновато - в PLLSRC фигурирует откуда-то HSI/2. Ну хорошо, это оно так у STM32F030 из этого же руководства: Допустим, забыли сделать сноску, что у 030 там HSI/2, а у 070, судя по картинке, там должно быть HSI/PREDIV. Нам пофиг, нам нужно запитать PLL от HSE. Берем и спокойно пишем код RCC->CFGR |= 1 * RCC_CFGR_PLLSRC; Все же логично, RCC_CFGR_PLLSRC - однобитовое поле! И захвата PLL не происходит. Причем этот же код на 030 дает захват. А если запитать PLL от HSI, то есть убрать эту строку из кода - захват происходит. В процессе поиска ошибки мы обнаруживаем, что при запитке PLL от HSI значение PREDIV ни на что не влияет, между HSI и PLL гвоздями прибит делитель на 2. И только через часов 6 отладки, разбирая от безысходности сгенеренный кубом исходник мы обнаруживаем в загловочном файле такое: #define RCC_CFGR_PLLSRC_Pos (15U) #define RCC_CFGR_PLLSRC_Msk (0x3U << RCC_CFGR_PLLSRC_Pos) /*!< 0x00018000 */ #define RCC_CFGR_PLLSRC RCC_CFGR_PLLSRC_Msk /*!< PLL entry clock source */ #define RCC_CFGR_PLLSRC_HSI_DIV2 (0x00000000U) /*!< HSI clock divided by 2 selected as PLL entry clock source */ #define RCC_CFGR_PLLSRC_HSI_PREDIV (0x00008000U) /*!< HSI/PREDIV clock selected as PLL entry clock source */ #define RCC_CFGR_PLLSRC_HSE_PREDIV (0x00010000U) /*!< HSE/PREDIV clock selected as PLL entry clock source */ То есть по факту у STM32F070 PLLSRC имеет размер два бита, и запись "1 * RCC_CFGR_PLLSRC" дает в них запрещенную комбинацию из обоих единичек. Шах и блять! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 17 minutes ago, Сергей Борщ said: То есть по факту у STM32F070 PLLSRC имеет размер два бита, и запись "1 * RCC_CFGR_PLLSRC" дает в них запрещенную комбинацию из обоих единичек. Помнится, тоже знатно оттоптался на этих граблях :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба Сергей Борщ подскажите с каким конкретно чипом такая засада, сделаю заметку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба По тексту же STM32F070 несколько раз проскакивает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 10 минут назад, MasterElectric сказал: Сергей Борщ подскажите с каким конкретно чипом такая засада, сделаю заметку. Дело не в чипе, а в библиотеках ST. Там везде для битовых полей определяется маска. И работать с ней нужно как с маской. RCC->CFGR |= 1 * RCC_CFGR_PLLSRC; Так делать нельзя. Нужно как-то так RCC->CFGR &= RCC_CFGR_PLLSRC; RCC->CFGR |= RCC_CFGR_PLLSRC_1; [RCC_CFGR_PLLSRC_HSI_DIV2 | RCC_CFGR_PLLSRC_HSE_PREDIV | etc] Разумеется, кроме описания регистра нужно смотреть и на схему блока, читать весь текст и т.п. Кста, я по ходу добавляю определений в свою библиотеку, где определяю не маски, а номера битов - путаницы гораздо меньше #define RCC_CFGR_PLLSRC (15UL) RCC->CFGR = 0 | (0 << RCC_CFGR_ADCPRE) | (0 << RCC_CFGR_PPRE) | (0 << RCC_CFGR_HPRE) | (4 << RCC_CFGR_PLLMUL) | (2 << RCC_CFGR_PLLSRC) ; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 1 hour ago, adnega said: Там везде для битовых полей определяется маска. И работать с ней нужно как с маской. Так в описании-то это единичный бит, а в хидере - поле. Вот в чем засада. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба Ну да, даташит однозначно один бит показывает. На F0x1, F0x2, F0x3 там уже да, честные 2 бита. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 5 минут назад, aaarrr сказал: Так в описании-то это единичный бит, а в хидере - поле. Вот в чем засада. Я начинал заполнять библиотеку с STM32F0x2. Там это два бита Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 1 час назад, adnega сказал: Так делать нельзя. Какой кошмар! Все мои программы в топку... adnega запертил Открываем заголовочный файл на F030: #define RCC_CFGR_PLLSRC_Pos (16U) #define RCC_CFGR_PLLSRC_Msk (0x1U << RCC_CFGR_PLLSRC_Pos) /*!< 0x00010000 */ #define RCC_CFGR_PLLSRC RCC_CFGR_PLLSRC_Msk /*!< PLL entry clock source */ #define RCC_CFGR_PLLSRC_HSI_DIV2 (0x00000000U) /*!< HSI clock divided by 2 selected as PLL entry clock source */ #define RCC_CFGR_PLLSRC_HSE_PREDIV (0x00010000U) /*!< HSE/PREDIV clock selected as PLL entry clock source */ Там PLLSRC - один бит. Почему с ним нельзя делать RCC->CFGR |= 1 * RCC_CFGR_PLLSRC ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба Насчет преемственности. На днях погубил не один миллиард нервных клеток из-за регистра ADC->CCR. У одних он по адресу +308h (STM32F303, STM32F0xx), а у кого-то +304h (STM32F40x, STM32L152) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MasterElectric 0 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба уже посмотрел что их всего 4 F070 и все в 1 ДШ, бывает просто что ДШ несколько, для мелких и постарше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 8 минут назад, adnega сказал: Я начинал заполнять библиотеку с STM32F0x2. Там это два бита А у меня в плату впаян F070. По наводке AHTOXA я глянул в руководство пользователя F072 - там картинка системы тактирования не имеет ничего общего с картинкой F070. Я в описание его регистров даже и смотреть не стал. 1 час назад, adnega сказал: Так делать нельзя. Нужно как-то так Я делаю иначе: RCC->CFGR = 0 | 0 * RCC_CFGR_PLLNODIV // PLL divider for MCO: 0: MCO = PLL/2, 1: MCO=PLL/1 | 4 * (RCC_CFGR_MCOPRE & -RCC_CFGR_MCOPRE) // MCO prescaler, 0: /1, 1: /2, 2: /4, 3: /8, 4: /16, // 5: /32, 6: /64, 7: /128 | 7 * (RCC_CFGR_MCOSEL & -RCC_CFGR_MCOSEL) // MCO source, 0: disabled, 1: HSI14, 2: LSI, 3: LSE, // 4: SYSCLK, 5: HSI, 6: HSE, 7: PLL | (PLL_MUL - 2) * (RCC_CFGR_PLLMUL & -RCC_CFGR_PLLMUL) // Fvco = Fpll_in / PREDIV * PLLMUL | 0 * RCC_CFGR_PLLXTPRE // LSB of PREDIV | 2 * (RCC_CFGR_PLLSRC &- RCC_CFGR_PLLSRC) // PLL source, 0: HSI/2, 1: HSI/PREDIV 2: HSE/PREDIV | 0 * (RCC_CFGR_ADCPRE & -RCC_CFGR_ADCPRE) // ADC clock: obsolete, use ADC->CFGR2 settings | ( (AHBCLK / APBCLK == 1) ? 0 : (AHBCLK / APBCLK == 2) ? 4 : (AHBCLK / APBCLK == 4) ? 5 : (AHBCLK / APBCLK == 8) ? 6 : (AHBCLK / APBCLK == 16) ? 7 : (1 << 64) // unsupported value, generate uint32_t overflow warning ) * (RCC_CFGR_PPRE & -RCC_CFGR_PPRE) // APB prescaler, 0...3: /1, 4: /2, 5: /4, 6: /8, 7: /16 | ( (SYSCLK / AHBCLK == 1) ? 0 : (SYSCLK / AHBCLK == 2) ? 8 : (SYSCLK / AHBCLK == 4) ? 9 : (SYSCLK / AHBCLK == 8) ? 10 : (SYSCLK / AHBCLK == 16) ? 11 : (SYSCLK / AHBCLK == 64) ? 12 : (SYSCLK / AHBCLK == 128) ? 13 : (SYSCLK / AHBCLK == 256) ? 14 : (SYSCLK / AHBCLK == 512) ? 15 : (1 << 64) // unsupported value, generate uint32_t overflow warning ) * (RCC_CFGR_HPRE & -RCC_CFGR_HPRE) // AHB prescaler, 0...7: /1, 8: /2, 9: /4, 10: /8, 11: /16 // 12: /64, 13: /128, 14: /256, 15: /512 | 2 * (RCC_CFGR_SW & -RCC_CFGR_SW) // SYSCLK source: 0 = HSI, 1 = HSE, 2 = PLL ; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 3 минуты назад, Сергей Борщ сказал: Все мои программы в топку... adnega запертил Ок. Я погорячился. Скажем так: - есть операция деления - на ноль делить нельзя. Это не означает, что делить нельзя. Делить можно, только аккуратно. В общем случае умножать на маску - нельзя, за исключением двух значений "0" или "1". Я так понял, вы ими только так и пользуетесь. Я поторопился и подумал, что вместо "1" можно подставлять "2" и т.д. Т.е. проблема в том, что где-то RCC_CFGR_PLLSRC == 0x0001_0000, а где-то 0x0001_8000. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба 1 минуту назад, adnega сказал: Я так понял, вы ими только так и пользуетесь. Я поторопился и подумал, что вместо "1" можно подставлять "2" и т.д. Да, именно так. Мир-дружба. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 18 марта, 2019 Опубликовано 18 марта, 2019 · Жалоба Только что, Сергей Борщ сказал: Да, именно так. Мир-дружба. Конечно! Просто я видел два варианта использования битовых полей: AVR-подобный (определяет номера битов) и STM-подобный (определяет маски). Исторически сложилось, что мне удобнее AVR-стиль со сдвигами. И библиотеку под STM я начал заполнять задолго до SPL/HAL/etc только на основе RM. У вас получается какой-то гибрид: используете определения масок, а за счет магии работаете как с битами. Мне нравится ваше решение, т.к. оно кажется удобным (поскольку AVR-похожее) и при этом сохраняется совместимость с заголовочными файлами производителя (и их не нужно делать/переделывать самому). эхх... где вы были 10 лет назад ;)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться