Китайские клоны STM32F10x походу не умеют запускать код в RAM и менять тактовую частоту на ходу?

Был у кого опыт менять PLL на ходу? Оригинальные (4хх) умеют а вот 10х не получается у меня.
И из ОЗУ не стартуют.
Что и где я про…бал?

А, забыл, 103, что в протеусе есть прекрасно все меняет. Запускать в ОЗУ не пробовал. Походу подделка. Кто чо скажет?

кодик бы посмотреть…

С “кодиком” трабла, цеж не дуня а кубик. Все волшебство происходит внутри HAL или LL. И показать я его как?
Все самое интересное - если тактовать по классике через множитель, PLL и CSS на 72 МГц то тестовый блинк работает. Если его же переделать на 8 или 16 МГц без PLL и CSS - не работает. Systick не щелкает даже.
Судя по фоткам с нета камень явная подделка но именно STM надпись.
Всякие разные ID через программатор не нашел где и как прочитать чтобы проверить.
Могу накидать простенький код для проверки но что это даст?

А что вы подразумеваете менять PLL на ходу?
В любом STM32, во всяком случае те что я щупал, есть возможность переключать любые делители и множители во время работы программы, но это делается в жестко прописанной в ДШ последовательности.
Опять же есть механизм аварийного восстановления тактирования от внутреннего источника в случае сбоя например внешнего кварцевого резонатора.
Как это делается в HAL/LL я не подскажу, но наверняка можно.

Подозреваю - “дело было не в бобине”

как минимум посмотреть)))) и что не понятно, объяснить должен код…

1️⃣ Почему 8/16 МГц не работают, а 72 работают?
На 72 МГц CubeMX автоматически устанавливает 2 такта ожидания (Wait States) для Flash-памяти (LATENCY=2WS), потому что частота выше 48 МГц.
А когда ты переключаешь на 8 МГц (HSI) без PLL, CubeMX (или твой код) ставит 0 Wait States.
Проблема: В китайских клонах STM32F103 (с маркировкой STM, но перемаркированные GD32 или APM32) Flash-память физически медленнее или имеет другую логику работы на низких частотах. Некоторые клоны не умеют работать на 0 WS даже на 8 МГц, либо у них сбита настройка прескалеров шины AHB/APB при смене источника тактирования. SysTick висит, потому что он считает от HCLK, а HCLK, возможно, вообще не приходит на ядро из-за сбоя в переключении.

2️⃣ Что конкретно тебе нужно сделать (прямо сейчас)
Раз ты работаешь через CubeMX/HAL, ручной "кодик" писать не придется. Сделай так:

Принудительно зафиксируй Wait States вручную, даже на 8 МГц.
В начале main(), ДО вызова HAL_Init() и SystemClock_Config(), вставь:

c
__HAL_RCC_FLASH_CLK_ENABLE();
FLASH->ACR = FLASH_ACR_LATENCY_0WS; // Или попробуй FLASH_ACR_LATENCY_1WS
Либо в CubeMX в разделе RCC -> HSE/LSE ничего не меняй, а в коде принудительно поставь задержку 1WS. Клону может быть пофиг на частоту — ему нужно, чтобы Flash успевал.

Пересобирай проект с тактированием не HSI, а HSE (внешним кварцем) на 8 МГц, но без PLL. В CubeMX выбери HSE, а множитель PLL поставь x1 (чтобы на выходе было 8 МГц). Если на HSE без PLL заработает — значит, у тебя проблема именно с переключением с HSI на HSI же (баг клона).

Самое важное для проверки: После конфигурации тактов вручную вызови:

c
SystemCoreClock = 8000000; // Принудительно для 8 МГц
HAL_InitTick(TICK_INT_PRIORITY); // Переинициализируй SysTick
CubeMX часто не обновляет переменную SystemCoreClock, если не используется PLL, и HAL_Delay() рассчитывает паузу не на 8 МГц, а на старые 72 МГц. Из-за этого блинк кажется, что "не работает", хотя на самом деле он моргает в 9 раз медленнее (или быстрее).

3️⃣ Как проверить, подделка ли это (без сложного кода)
Ты сказал, что не нашел ID. А ты ищешь не "Device ID" в регистрах (которые у клонов часто подделаны и показывают 0x410 как у ST), а уникальный ID (UID) по адресам:

0x1FFFF7E8 (96-битный UID)

У оригинального STM32F103 в последних двух байтах UID есть определенная закономерность. У клонов (GD32) там часто либо нули, либо байты "съезжают" (например, в середине вместо 0x20 стоит 0x00).

Самый простой "детектор подделки" без программатора:
Ткни осциллографом или логическим анализатором в ногу MCO (PA8), если ты ее настроил в CubeMX на вывод частоты SYSCLK/2. На 72 МГц клон выдаст на MCO частоту ровно 36 МГц, а на 8 МГц без PLL — ровно 4 МГц. Если частоты нет или она плавает — камень умер или подделка с бракованным тактовым генератором.

есть ответ от ии, поможет ?)))

нет. Каким боком Flash и отсутствие systick ?

PS. У меня все больше ощущение что главное ИИ впихнуть в любую тему форума :frowning:

Была бы на то моя всемогущая воля - я бы выделил отдельную тему(или несколько тем) , для ИИ-шников, чтобы они там друг с другом тусовались…

P.S. Но уже поздно, мир захвачен, и враги повсюду

тогда нужен код… к тому же главное это найти за что можно порицать ии, что бы он учился, а то без этого он может лениться, а как не на форуме найти базу для обучения, а рекламой ии не занимаюсь…

#include "main.h"
#include "gpio.h" // Подключай свои заголовки, если они есть

// ==============================================
// ФУНКЦИЯ ТАКТИРОВАНИЯ С ХАКОМ ДЛЯ КЛОНА
// ==============================================
void SystemClock_Config_Hack(void)
{
  // Включаем HSI (внутренний 8 МГц) и ждем готовности
  RCC->CR |= RCC_CR_HSION;
  while((RCC->CR & RCC_CR_HSIRDY) == 0);

  // 1. Сбрасываем всё тактирование в дефолтное состояние
  RCC->CFGR = 0x00000000; // AHB/APB прескалеры = 1, SYSCLK = HSI, PLL выключен
  RCC->CIR = 0x00000000; // Все прерывания по тактированию сброшены

  // 2. Включаем HSE (внешний кварц), если он нужен. 
  //    Если работаешь ТОЛЬКО от HSI (8 МГц) - закомментируй следующие 2 строки:
  // RCC->CR |= RCC_CR_HSEON;
  // while((RCC->CR & RCC_CR_HSERDY) == 0);

  // 3. Настраиваем SYSCLK на HSI (8 МГц) или HSE (8 МГц)
  //    Если используешь HSI:
  RCC->CFGR |= RCC_CFGR_SW_HSI;   // SYSCLK = HSI
  //    Если используешь HSE (раскомментируй):
  // RCC->CFGR |= RCC_CFGR_SW_HSE; // SYSCLK = HSE

  // 4. Ждем, пока бит подтвердит переключение
  while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Для HSI
  // while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSE); // Для HSE

  // 5. !!! ГЛАВНЫЙ ХАК ДЛЯ КЛОНА !!!
  //    Даем камню 10 микросекунд, чтобы он "осознал" новую частоту
  for(volatile int i = 0; i < 200; i++);

  // 6. Теперь можно выключить PLL (если она была включена)
  RCC->CR &= ~RCC_CR_PLLON;
  while((RCC->CR & RCC_CR_PLLRDY) != 0); // Ждем, пока PLL выключится физически

  // 7. Настраиваем делители шин (AHB = SYSCLK, APB1 = SYSCLK/2, APB2 = SYSCLK)
  //    Для 8 МГц ставим максимальное быстродействие:
  RCC->CFGR |= RCC_CFGR_HPRE_DIV1;   // AHB = SYSCLK / 1
  RCC->CFGR |= RCC_CFGR_PPRE1_DIV1;  // APB1 (низкоскоростная) = AHB / 1 (макс 36 МГц, у нас 8 - ОК)
  RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;  // APB2 (высокоскоростная) = AHB / 1

  // 8. ОБЯЗАТЕЛЬНО: Обновляем глобальную переменную для HAL
  SystemCoreClock = 8000000; // Мы на 8 МГц
}

// ==============================================
// ТОЧКА ВХОДА
// ==============================================
int main(void)
{
  // 1. Запрещаем прерывания, пока мы колдуем с тактами
  __disable_irq();

  // 2. Инициализируем HAL (минимально, без тактирования)
  HAL_Init();

  // 3. Настраиваем тактирование через наш хак
  SystemClock_Config_Hack();

  // 4. Настраиваем SysTick заново, так как частота изменилась
  HAL_InitTick(TICK_INT_PRIORITY);

  // 5. Разрешаем прерывания обратно
  __enable_irq();

  // 6. Инициализируем пины (это сгенерирует CubeMX в MX_GPIO_Init)
  MX_GPIO_Init();

  // ==============================================
  // ОСНОВНОЙ ЦИКЛ
  // ==============================================
  while(1)
  {
    // Вариант 1: Проверка через грубую задержку (без SysTick)
    for(volatile int i = 0; i < 2000000; i++);
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // Замени на свою ногу

    // Вариант 2: Если заработало - раскомментируй проверку SysTick
    // HAL_Delay(1000);
    // HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
  }
}

// ==============================================
// ОБРАБОТЧИК SYSYTICK (обязателен для HAL_Delay)
// ==============================================
void SysTick_Handler(void)
{
  HAL_IncTick();
}

// ==============================================
// КОСТЫЛЬ ДЛЯ HAL (чтобы не ругался на слабый символ)
// ==============================================
void Error_Handler(void)
{
  while(1);
}

если не поможет, тогда идей у ии! нет)))

p.s. не каким

предлагаю не сопротивляться и возлавить…

Какое там сопротивляться, могу лишь поворчать…

тоже занятие, только кпд низкий, но лучше чем нечего не делать)))

а зачем тогда непроверенный код от хз кого выкладывать :slight_smile: ?

P.S. Как минимум 47 строка лишняя - в HAL есть спец функция пересчета частоты.
И останавливать / запускать прерывания совершенно необязательно.
это то что сразу в глаза бросилось из косяков…

что бы ии развивался, если что не так он поправит! но это не точно…

Ты в курсе, что ИИ не имеет доступа к реальному интернету (только во время обучения) и не запоминает ничего (только в рамках сессии/чата)?

Совершенно верно, можно “на ходу” менять тактовку HSI, HSE, PLL, CSS.
И шины тоже можно)
Вопрос: на 72 МГц тестовый блинк работает (множитель + PLL) а на 8 МГц (напрямую без PLL) не работает.
Код инита генерит сам куб и ошибок там быть не должно, ибо в протеусе 8 МГц и 16 МГц работают. 72 МГц симить в проте жутко грустно т.к. он занимает только одно ядро проца!
Вот и загадка…
Кароче, есть у меня 103 оригинал с фирмовым прямоугольным кварцем на 12 МГц, на нем и попробую.
411 еще есть нульцевый в пакетике не распакованный)
и 523Н5 но там вроде 30 МГц кварц)
Буду пробовать на них, ибо оригиналы)

Нахер PLL нужен если на мультиплексор итак 8 МГц приходит?
При такой тактовке если даже использовать все возможности камня акромя USB ток потребления > 5 мА. Мне и надо меньшее потребление, на 72 МГц камень “дует на все деньги” )))

Сам “в афиге” но я разберусь, есть и камни и все остальное оборудование)))

Не верю :thinking:

Быстро не обещаю, постараюсь провести эксперимент, есть как раз поддельный 103, но в любом случае это будет не на Hal.