Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/29: Рейтинг темы: голосов - 29, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 14

PLL выдает не ту частоту, что требуется (STM32F103C8T6)

23.09.2019, 22:09. Показов 7471. Ответов 45
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Все здравствуйте.
Дело в следующем.
На вышеупомянутом МК настраиваю тактирование от кварца 4.608МГц (Специальная частота кварца для работы с UART)
USART1->BRR рассчитывается как 4608000/9600 = 480.
В цикле просто через определенный промежуток времени отправляю символ "M". При таких настройках все отлично работает.

Но как только я пытаюсь затактировать МК через PLL, происходит что-то странное. При умножении PLL на 10 частота становиться не 46.080МГц как ожидается, а примерно 41.76МГц.
Выяснил я это следующим путем. При переключении на PLL в терминал вместо "М" побежали кракозяблы. Подключив осциллограф, выяснил, что стартовый бит, вместо положенных при 9600 бод 104 микросекунды, длится 116 микросекунд. Начал уменьшать постепенно USART1->BRR до тех пор, пока на осциллографе первый бит опять не стал 104мкс и в порт не пошли нормальные данные. Остановился на USART1->BRR = 4350. Умножив на 9600 получил частоту МК 41.76МГц.

Я понимаю, что это моя ошибка где-то, потому что на МК STM32f030f4 та же самая картина.
Прошу, подскажите в какую сторону рыть.

Код:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "stm32f10x.h"
 
 
void init_HS_Ext(void)              //настройка тактирования от внешнего кварца
{
    FLASH->ACR |= FLASH_ACR_LATENCY;
    RCC->CR|=RCC_CR_HSEON;
    while (!(RCC->CR & RCC_CR_HSERDY));
    //RCC->CFGR |= RCC_CFGR_PLLXTPRE_HSE;                       //Пределитель PLL на 1, то есть без изменений.
    //RCC->CFGR |= RCC_CFGR_PLLMULL10;                          //PLL умножаем на 10
    //RCC->CR|=RCC_CR_PLLON;                                                //Включить PLL 
    //while (!(RCC->CR & RCC_CR_PLLRDY));                       //и подождать, пока она стабилизируется
    RCC->CFGR &=~RCC_CFGR_SW;                                           //сброс переключателя SW, на всякий случай.
    RCC->CFGR |= RCC_CFGR_SW_HSE;                                   //Переключить на HSE (pll)
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;                            //AHB prescaler
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;                           //APB1 prescaler
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;                           //APB2 prescaler 
}
 
 void UART1_Init(void)
{
            RCC->APB2ENR    |= RCC_APB2ENR_USART1EN;    //Включаем тактирование на USART1
            USART1->BRR = 480;                                      //устанавливаем битрейт для 9600 //1920
            RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;         //подаем тактирование на порт А, при инициализации UART2 этого делать уже не надо
            GPIOA->CRH |= GPIO_CRH_MODE9;                       //Выход с максимальной частотой 50Мгц*/
    GPIOA->CRH |= GPIO_CRH_CNF9_1;         // Tx CNF - 10: Альтернативная фукция, выход, подтяжка
     /*Rx,Tx setup GPIOA->CRH = 0x000004B0*/
            GPIOA->CRH &= ~(GPIO_CRH_CNF9_0);
 
            GPIOA->CRH &= ~(GPIO_CRH_MODE10);  // Rx Mode 00 Вход (reset state)
            GPIOA->CRH |= GPIO_CRH_CNF10_0;    // Rx CNF  01 Висит в воздухе (reset state)
     
            USART1->CR1  |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_IDLEIE; // TX ON, RX ON
            USART1->CR2 = 0;
            USART1->CR3 = 0;
            NVIC_EnableIRQ (USART1_IRQn);                       //разрешить прерывания от USART1
            __enable_irq ();                                                //разрешить глобальные прерывания
}
 
void GPIO_Init (void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
    GPIOC->CRH |= GPIO_CRH_MODE15_1;
    GPIOC->CRH &=~(GPIO_CRH_CNF15_0 | GPIO_CRH_CNF15_1);        //CNF[01]
}   
 
 
 
int main(void)
{
    
    init_HS_Ext();
    GPIO_Init();
    UART1_Init();
    int i;
    while(1)
    {
    GPIOC->BSRR |= GPIO_BSRR_BS15;
    USART1->DR = 'M';
    for(i=0; i<0x40000; i++);
    GPIOC->BRR |= GPIO_BRR_BR15;
    for(i=0; i<0x40000; i++);
    }
    
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.09.2019, 22:09
Ответы с готовыми решениями:

STM32F103C8T6 BluePill тактирование HSE от PLL
Всем привет! Столкнулся с проблемой, что, например, если обвязать переключение на HSE, PLL проверками, то не проходит проверку лишь...

Программа выдает не совсем то,что требуется, почему?
Вот сама программа. Нужно, чтобы созданная матрица возводилась в квадрат, но возводится только первая строчка, почему ? (После кода...

Оперативная память выдаёт частоту 1066
Память Patriot Viper 3 16 ГБ Мать Asrock 970m Pro3, вставил в A2,B2 как по мануалу. Показывает в CPU-z 558 МГц При выполнении...

45
8 / 8 / 0
Регистрация: 09.02.2019
Сообщений: 36
23.09.2019, 23:08
Рабочий код в качестве примера:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void SysClock_Config (void)              // System Clock Configuration for 16 MHz.
{
  RCC_Reset();                 // Сброс конфиг. модуля RCC до состояния по умолчанию.
  RCC -> CFGR |= RCC_CFGR_HPRE_Div1;     // Предделитель AHB (системной частоты).
  RCC -> CFGR |= RCC_CFGR_PPRE1_Div1;    // Предделитель APB1 PCLK1 = 16 MHz.
  RCC -> CFGR |= RCC_CFGR_PLLSRC_HSE;    // Вход для PLL: HSI или HSE.
  RCC -> CFGR |= RCC_CFGR_PLLXTPRE_Div1; // Делитель HSE для PLL (8 MHz).
  RCC -> CFGR &= RCC_CFGR_PLLMUL_Mul2;   // Множитель PLL: HSE*2 = 16 MHz.
  
  RCC -> CR |= RCC_CR_HSEON;             // Включить внешний кварцевый резонатор.
  while (!(RCC -> CR & RCC_CR_HSERDY));  // Ждать готовность генератора.
  
  RCC -> CR |= RCC_CR_PLLON;             // Включить PLL.
  while (!(RCC -> CR & RCC_CR_PLLRDY));  // Ждать готовность PLL.
  
  RCC -> CFGR |= RCC_CFGR_SW_PLL;        // Сделать источник PLL системным.
  RCC -> CR &= ~RCC_CR_HSION;            // Выключить внутренний генератор.
  
  RCC -> AHBENR  |= RCC_AHBENR_SRAMEN;   // Вкл. тактирование памяти.
  RCC -> APB2ENR |= RCC_APB2ENR_TIM1EN;  //| RCC_APB2ENR_USART1EN);
  RCC -> APB1ENR |= (RCC_APB1ENR_BKPEN | //RCC_APB1ENR_PWREN | RCC_APB1ENR_SPI2EN |
                     RCC_APB1ENR_TIM4EN | RCC_APB1ENR_TIM3EN | //RCC_APB1ENR_I2C2EN |
                     RCC_APB1ENR_TIM2EN);
}
0
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 14
23.09.2019, 23:31  [ТС]
Хм, Вы знаете, какой-то неоднозначный результат с Вашим кодом. Дело в том, что у меня в цикле еще диодик мигает вместе с отправкой символа, так, для наглядности. Так вот с Вашим кодом диодик стал мигать чаще, но время первого бита так и не изменилось - 116 мкс при рассчитанном USART1->BRR = 4800.
0
 Аватар для shepard127
16 / 16 / 1
Регистрация: 20.10.2013
Сообщений: 81
24.09.2019, 09:43
Добрый день! Для начала проверте частоту на выводе MCO(прикладываю скриншот). Подключите осцилограф к выводу PA8(предварительно настройте его на вывод тактирования). Данный вывод можно настроить на вывод как входящего та тактирования, так и для отображения тактирования после PLL. Таким образом вы сможете проверить частоту тактирования от кварца, и после PLL

Я смотрю вы используете прямое обращение к регистрам. В таком случае для более быстрого решения вашей проблемы, рекомендую собрать проект в CubeMx, затем скопировать часть инициализации тактирования
Миниатюры
PLL выдает не ту частоту, что требуется (STM32F103C8T6)   PLL выдает не ту частоту, что требуется (STM32F103C8T6)  
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,916
24.09.2019, 10:08
Вот пример для stm32f103c8t6 для максимальной частоты (72 МГц) от внешнего кварца 8 МГц (уж какой установлен на моей платке).
Вложения
Тип файла: rar F103_uart.rar (7.1 Кб, 15 просмотров)
1
8 / 8 / 0
Регистрация: 09.02.2019
Сообщений: 36
24.09.2019, 10:50
Цитата Сообщение от Bodisey Посмотреть сообщение
Вы знаете, какой-то неоднозначный результат с Вашим кодом
Попробуйте на другом кристалле.
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
24.09.2019, 11:25
Bodisey, Открываем RM, страницу 135. И видим:

Откуда вы взяли множитель 10 - непонятно.
У меня например даже дефайна такого нет в файле stm32f10x.h

Если ваш кварц умножить на 9 (максимальный множитель) то частота составит 41,472 МГц, что вполне близко к вашей.
1
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
24.09.2019, 11:27
0
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 14
24.09.2019, 11:29  [ТС]
Всем спасибо за советы, сейчас буду подключать, пробовать.
0
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 14
24.09.2019, 11:43  [ТС]
_SayHello, согласен, в RM действительно максимальный множитель 9, хотя в моих дефайнайх, в отличии от ваших, множитель доходит до 16.
Миниатюры
PLL выдает не ту частоту, что требуется (STM32F103C8T6)  
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
24.09.2019, 12:03
Bodisey, эталон - RM, в библиотеках часто бывают ошибки. Говорю как разработчик этих самых библиотек, только для других контроллеров

Добавлено через 16 минут
Цитата Сообщение от Bodisey Посмотреть сообщение
ласен, в RM действительно максимальный множитель 9, хотя в моих дефайнайх, в отличии от ваших, множитель доходит до 16.
И кстати это скорее всего не ошибка. Если подниметесь чуть повыше, там скорее всего будет elif типа такого:
C
1
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
а у вас контроллер
C
1
STM32F10X_MD
В начале файла надо было сделать вот так:
C
1
2
3
4
5
6
7
8
9
10
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
  /* #define STM32F10X_LD */     /*!< STM32F10X_LD: STM32 Low density devices */
  /* #define STM32F10X_LD_VL */  /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
  #define STM32F10X_MD      /*!< STM32F10X_MD: STM32 Medium density devices */
  /* #define STM32F10X_MD_VL */  /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
  /* #define STM32F10X_HD */     /*!< STM32F10X_HD: STM32 High density devices */
  /* #define STM32F10X_HD_VL */  /*!< STM32F10X_HD_VL: STM32 High density value line devices */
  /* #define STM32F10X_XL */     /*!< STM32F10X_XL: STM32 XL-density devices */
  /* #define STM32F10X_CL */     /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif
Либо в настройках проекта дефайн задать. Тогда бы и ошибки подобной не было.
0
0 / 0 / 0
Регистрация: 22.06.2017
Сообщений: 14
24.09.2019, 13:02  [ТС]
Как указал _SayHello, поменял множитель на 9, пересчитал USART1->BRR, и ЮАРТ нормально заработал. И даже первый бит, насколько я могу судить на своем карманном осциллографе, длится 104 мкс. Точнее уже посмотрю на работе, на взрослом осцилле. На этом пока всем спасибо!
Миниатюры
PLL выдает не ту частоту, что требуется (STM32F103C8T6)  
0
24.09.2019, 14:04

Не по теме:

Цитата Сообщение от _SayHello Посмотреть сообщение
Bodisey, эталон - RM, в библиотеках часто бывают ошибки.
Тогда как объясните что на кварце 8 МГц, можно получить 128 МГц на выходе умножителя и МК на этой частоте работает?

0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,916
24.09.2019, 14:13
locm, что за камень и что за код?
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
24.09.2019, 14:19
locm, а что тут объяснять? в RM написано что множители выше 9 - reserved. То что вы записали reserved значение просто вызывает undefined behavior который может зависеть от партии к партии. Вот у вас 8 МГц перемножилось на 16 хотя такого множителя нет, а у ТСа даже при задании reserved значения все равно множитель 9 остался.
Раскрою вам секрет: внутри контроллеров, может оставаться тестовая периферия которая нормально размечена в памяти, и даже есть хардварное исполнение. Возможно в следующей ревизии она пропадет, может нет. Может частично работать. Можете поискать, может какойнибудь лишний USART найдете, там где он не заявлен. Хотя в старших моделях он есть в определенной области памяти.
Я с таким часто встречаюсь, и хардварщики разрабатывающие саму микросхему, тоже любят отлаживать и изменения могут быть достаточно частыми. Тем не менее по моему опыту, самым первым для пользователя обновляется именно RM.

Добавлено через 3 минуты
А вообще в МК обычно много reseved областей, можете пописать туда чего-нибудь, может чего интересного найдете)
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,916
24.09.2019, 15:08
_SayHello, только хорошо бы не "чего-нибудь куда-нибудь", а для начала посмотреть старшие контроллеры семейства, что там должно лежать.
...
А потом, когда эйфория от своей офигенности испарится, перестать полагаться на недокументированные возможности.
Но в качестве развлечения - почему бы и нет.
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
24.09.2019, 15:13
COKPOWEHEU, Да это собственно не призыв особо к действию. Действительно, отправлять в релиз девайс основанный на недокументированных свойствах - такое себе предприятие.
Просто можно иметь ввиду, что "хардварная" отладка, не программная, никто из за удаления одного модуля не будет бежать вносить изменения в топологию. Просто зарезервят в памяти адреса и в RM напишут reserved. Если изменений наберется большая пачка, возможно это и совсем выпилят, а может и нет.
0
 Аватар для COKPOWEHEU
4083 / 2681 / 432
Регистрация: 09.09.2017
Сообщений: 11,916
24.09.2019, 16:21
_SayHello, скорее - продукт сортировки. Если по каким-то параметрам контроллер не дотягивает до старшей ветки, его маркируют как младшую (если все совсем плохо - выбрасывают, но это неинтересный вариант). А в младшей ветке данная периферия не предусмотрена. Или такой объем памяти. Или еще что-то. И исправления перед маркировкой тоже могут быть разные: можно физически пережечь перемычку, можно прошить в память корректирующее значение. А можно просто промолчать: если мы не говорим юзеру, что у него есть еще один таймер, то и за его функциональность отвечать не придется.
То есть ограничения накладываются на отдельные кристаллы, а не на даташит.
0
Эксперт по электронике
6583 / 3210 / 335
Регистрация: 28.10.2011
Сообщений: 12,531
Записей в блоге: 7
24.09.2019, 22:10
Цитата Сообщение от _SayHello Посмотреть сообщение
Вот у вас 8 МГц перемножилось на 16 хотя такого множителя нет
Запустите Куб, создайте проект для STM32F103C8T6 и посмотрите какие есть множители. Вас ждет сюрприз...
И в добавок картинка из даташита. Обратите внимание на умножитель.



И еще одна, на сей раз из RM.



Цитата Сообщение от _SayHello Посмотреть сообщение
Раскрою вам секрет: внутри контроллеров, может оставаться тестовая периферия которая нормально размечена в памяти, и даже есть хардварное исполнение.
Это я знаю, но в данном случае речь о документированных возможностях.
0
Эксперт по электронике
6583 / 3210 / 335
Регистрация: 28.10.2011
Сообщений: 12,531
Записей в блоге: 7
24.09.2019, 22:25
Цитата Сообщение от _SayHello Посмотреть сообщение
Открываем RM, страницу 135. И видим:
И видим что это для Connectivity line devices, т. е. STM32F105xx and STM32F107xx. Посмотрите 45 страницу RM.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
locm, что за камень и что за код?
STM32F103C8T6. Код это функция SetSysClockTo72 из system_stm32f10x.c в которой RCC_CFGR_PLLMULL9 заменен на RCC_CFGR_PLLMULL16.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.09.2019, 22:25
Помогаю со студенческими работами здесь

Выход USB 6 В и более. Или что то с STM32f103c8t6
Доброго времени суток всем кто читает это сообщение. Друзья. Коллеги. Нужно ваше мнение по поводу следующей ситуации. Для...

Что не так с шаблоном функции. Выдает: "для индекса требуется массив или тип указателя"
#include &lt;iostream&gt; using namespace std; template &lt;typename T&gt; void zapolnenie(T i, T a, T arr) { for (i = 0; i &lt; a; i++) { ...

Видеокарта выдает большую частоту чем заявлено производителем
Видеокарта выдает большую частоту чем заявлено производителем. С чем это может быть связанно? Стоит ли обратиться в магазин?

Что делать, если не получается подключиться к STM32F103C8T6 с Linux, ST-LINK v2?
Всем привет. В общем, мучаюсь, не получается ни прочитать, ни записать, ни обнулить прошивку на STM32F103C8T6 (blue pill) Сама плата...

Ga-7vt600 rz-c s-t a atlon xp 2200+ : в биосе выдает частоту в 2,3 мгц, а в виндовс 1,8
подскажите почему в биосе выдает чястату в 2,3 мгц в в виндовс 1,8 и как ето все можно паригулировать и почему в биосе все даные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru