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

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

23.09.2019, 22:09. Показов 7613. Ответов 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,929
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,929
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,929
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,929
24.09.2019, 16:21
_SayHello, скорее - продукт сортировки. Если по каким-то параметрам контроллер не дотягивает до старшей ветки, его маркируют как младшую (если все совсем плохо - выбрасывают, но это неинтересный вариант). А в младшей ветке данная периферия не предусмотрена. Или такой объем памяти. Или еще что-то. И исправления перед маркировкой тоже могут быть разные: можно физически пережечь перемычку, можно прошить в память корректирующее значение. А можно просто промолчать: если мы не говорим юзеру, что у него есть еще один таймер, то и за его функциональность отвечать не придется.
То есть ограничения накладываются на отдельные кристаллы, а не на даташит.
0
Эксперт по электронике
6836 / 3260 / 338
Регистрация: 28.10.2011
Сообщений: 12,736
Записей в блоге: 7
24.09.2019, 22:10
Цитата Сообщение от _SayHello Посмотреть сообщение
Вот у вас 8 МГц перемножилось на 16 хотя такого множителя нет
Запустите Куб, создайте проект для STM32F103C8T6 и посмотрите какие есть множители. Вас ждет сюрприз...
И в добавок картинка из даташита. Обратите внимание на умножитель.



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



Цитата Сообщение от _SayHello Посмотреть сообщение
Раскрою вам секрет: внутри контроллеров, может оставаться тестовая периферия которая нормально размечена в памяти, и даже есть хардварное исполнение.
Это я знаю, но в данном случае речь о документированных возможностях.
0
Эксперт по электронике
6836 / 3260 / 338
Регистрация: 28.10.2011
Сообщений: 12,736
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru