0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
1

Тактироание через HSE и PLL

31.01.2022, 00:47. Показов 1803. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, я новичек в программировании микроконтроллеров. Имею отладочную плату blue pill.
Изучаю stm32 давно. Программы писал с помощью куба и библиотеки HAL.
Решил попробовать библиотеку CMSIS. Нашел сайт-учебник чьим урокам следую.
Написал функции инициализации тактирования через HSE и PLL, так же написал инициализацию порта.
Но после прошивки , диод наPC13 не загорается, он загарается , когда я дотрагиваюсь в выводам пинов, на которые припаянны гребенки.А так не должно быть.
Думал, что с МК что то, но нет, накидал программу в кубе (инициализацию тактировния и порта) и в вайле прописал toggle , и прошил. Все работало, так я понял, что ошибка в коде написанном с помощью cmsis. Ниже приведены функции, в которых есть что то, что надо исправить, подскажите пожалуйста.
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
int ClockInit(void)
{
  __IO int StartUpCounter;
 
  RCC->CR |= (1<<RCC_CR_HSEON_Pos);
 
  for(StartUpCounter=0; ; StartUpCounter++)
  {
    if(RCC->CR & (1<<RCC_CR_HSERDY_Pos))
      break;
 
    if(StartUpCounter > 0x1000)
    {
      RCC->CR &= ~(1<<RCC_CR_HSEON_Pos);
      return 1;
    }
  }
 
  RCC->CFGR |= (0x07<<RCC_CFGR_PLLMULL_Pos)
            | (0x01<<RCC_CFGR_PLLSRC_Pos);
 
 
  RCC->CR |= (1<<RCC_CR_PLLON_Pos);
 
  for(StartUpCounter=0; ; StartUpCounter++)
  {
    if(RCC->CR & (1<<RCC_CR_PLLRDY_Pos))
      break;
 
    if(StartUpCounter > 0x1000)
    {
      RCC->CR &= ~(1<<RCC_CR_HSEON_Pos);
      RCC->CR &= ~(1<<RCC_CR_PLLON_Pos);
      return 2;
    }
  }
  FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos);
  RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos)
            | (0x04<<RCC_CFGR_PPRE1_Pos)
            | (0x00<<RCC_CFGR_HPRE_Pos);
 
  RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos);
 
  while((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0x02<<RCC_CFGR_SWS_Pos))
  {
  }
 
  RCC->CR &= ~(1<<RCC_CR_HSION_Pos);
 
  return 0;
 
}
 
void PortInit(void)
{
    RCC->APB2ENR |= (1<<RCC_APB2ENR_IOPCEN_Pos);
    RCC->APB2ENR |= (1<<RCC_APB2ENR_IOPBEN_Pos);
    RCC->APB1ENR |= (1<<RCC_APB1ENR_TIM2EN_Pos);
 
    GPIOC->CRH &= ~(2<<GPIO_CRH_MODE13_Pos) | ~(0<<GPIO_CRH_CNF13_Pos);
    GPIOC->CRH |= (2<<GPIO_CRH_MODE13_Pos) | (0<<GPIO_CRH_CNF13_Pos);   
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.01.2022, 00:47
Ответы с готовыми решениями:

Тактирование от HSE через PLL.
Добрый день, граждане! При попытке перейти на использование внешнего кварца, словил проблему....

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

SYSCLK = HSE -> PLL = HSI помогите с тактированием при CSS
Добрый день. Подскажите пожалуйста, возможно ли решить следующую задачу, если да то как? Есть...

Проблемы с HSE
Ни как не могу запустить HSE. Вот код: ...

STM32F100 HSE
Всем привет! Возникли непонятки с запуском HSE (точнее с незапуском). Имеем код: RCC_DeInit();...

34
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 01:00 2
Цитата Сообщение от Danny1996 Посмотреть сообщение
GPIOC->CRH &= ~(2<<GPIO_CRH_MODE13_Pos) | ~(0<<GPIO_CRH_CNF13_Pos);
что ты здесь ожидаешь?
0
0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
31.01.2022, 01:06  [ТС] 3
Сначала я сбрасываю биты , которые хочу настроить,потом выставляю их.
Вы хотите сказать, надо написать так :
C
1
GPIOC->CRH &= ~((2<<GPIO_CRH_MODE13_Pos) | (0<<GPIO_CRH_CNF13_Pos));
0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 02:18 4
Цитата Сообщение от Danny1996 Посмотреть сообщение
Сначала я сбрасываю биты ,
покажи где?
давай по шагам
Цитата Сообщение от Danny1996 Посмотреть сообщение
Вы хотите сказать
что я хочу сказать абсолютно не важно, важно чтобы ты сам обнаружил ошибку
битовые операции нужно изучить а не списывать друг у друга. В последнее время то ли три то ли четыре раза вижу эти сдвиги
0
0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
31.01.2022, 07:58  [ТС] 5
Побитовое "И" и литерал инвертирования (~) используется для выключения битов &= ~
В регистре CRH , который отвечает за биты 8-15, сначала сбрасываем биты пина , который я хочу настроить , а именно CNF13_1 , CNF13_0, MODE13_0, MODE13_1
Во так я понимаю эту строчку

Добавлено через 11 минут
В этой сточке я их сбрасываю &=~ вот этой комбинацией
0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 09:27 6
Цитата Сообщение от Danny1996 Посмотреть сообщение
сначала сбрасываем биты пина
давай по шагам
Цитата Сообщение от Danny1996 Посмотреть сообщение
~(0<<GPIO_CRH_CNF13_Pos)
0 при любом сдвиге дает 0
~ 0 будет все 1 (32разряда) 0xFFFFFFFF
далее
| результат 0xFFFFFFFF
ну и последнее &
GPIOC->CRH &=0xFFFFFFFF будет GPIOC->CRH
я же сказал по шагам разбери, а не то что хотел увидеть

Добавлено через 6 минут
Цитата Сообщение от Danny1996 Посмотреть сообщение
сначала сбрасываем биты пина
для сбрасываний бита мало использовать И нужно еще подготовить маску
например нужно сбросить 2 и 3 бит
создаем маску 00001100(0xC0)инвертируем ее 11110011(0xF3)
число хххххххх(х любое число 0,1)
xxxxxxxx
&
11110011
------------
xxxx00xx
1
0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
31.01.2022, 10:22  [ТС] 7
Получается, я не сбросил биты , а установил все в 1 ?

Добавлено через 24 минуты
Так ведь 2<<GPIO_CRH_MODE13_Pos это и есть маска, 2 = 10, а define GPIO_CRH_MODE13_Pos это адрес бита и получается, что сначала маска, потом я сбрасываю биты
0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 10:37 8
Цитата Сообщение от Danny1996 Посмотреть сообщение
Так ведь 2<<GPIO_CRH_MODE13_Pos это и есть маска,
нет, для двух битов маска должна быть 3(11)
при маске 2(10) как достучишься до младшего бита
0
0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
31.01.2022, 11:51  [ТС] 9
C
1
GPIOB->CRH &= ~((0<<GPIO_CRH_CNF13_Pos) | (2<<GPIO_CRH_MODE13_Pos));
значит при такой запси будет следующее
C
1
2
3
GPIOB->CRH &= ~(00 | 10)
GPIOB->CRH &= (11 | 01)
GPIOB->CRH = (00 | 10) - конечное состояние битов
Верно ?

Добавлено через 55 минут
Не так ?
0
3819 / 2388 / 414
Регистрация: 09.09.2017
Сообщений: 10,361
31.01.2022, 11:57 10
Код
GPIOB->CRH &=~ ((0<<GPIO_CRH_CNF13_Pos) | (2<<GPIO_CRH_MODE13_Pos));
GPIOB->CRH &=~ ((0b00<<22) | (0b10 << 22));
GPIOB->CRH &=~ (0b10 << 22);
GPIOB->CRH &=~ 0b00000000 (10)000000 00000000 00000000;
GPIOB->CRH &=  0b11111111 (01)111111 11111111 11111111; //скобки и пробелы добавлены для красоты
0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 11:58 11
Цитата Сообщение от Danny1996 Посмотреть сообщение
GPIOB->CRH &= ~(00 | 10)
GPIOB->CRH &= (11 | 01)
с чего бы инверсный 0 стал 11? 32 бита инверсными, станет 0b11111111111111111111111111111111(0xFFFFFFFF)
0
3819 / 2388 / 414
Регистрация: 09.09.2017
Сообщений: 10,361
31.01.2022, 12:03 12
Цитата Сообщение от ValeryS Посмотреть сообщение
с чего бы инверсный 0 стал 11?
Вы тоже что ли скобки не видите? Сначала OR, только потом NOT и AND.
0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 12:08 13
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы тоже что ли скобки не видите?
видим и видим вот что
Цитата Сообщение от Danny1996 Посмотреть сообщение
(11 | 01)
это ТС принципиальная ошибка, думает что написал 0 инвертируется один разряд, а если 00 то два
0
0 / 0 / 0
Регистрация: 16.08.2021
Сообщений: 27
31.01.2022, 12:12  [ТС] 14
Я совсем запутался.
GPIOB->CRH - после сброса имеет состояние тридцати двух нулей.
Я хочу поменять 4 бита в этом регистре.
А именно GPIOB_CRH_CNF13_1, GPIOB_CRH_CNF13_0, GPIOB_CRH_MODE13_1, GPIOB_CRH_MODE13_0
GPIOB_CRH_CNF13_1, GPIOB_CRH_CNF13_0 это есть GPIOB_CRH_CNF13_Pos
GPIOB_CRH_MODE13_1, GPIOB_CRH_MODE13_0 Это есть GPIOB_CRH_MODE13_Pos
C
1
GPIOB->CRH &= ~((3<<GPIOB_CRH_CNF13_Pos)|(3<<GPIOB_CRH_MODE13_Pos));
Сначала выполняю побитовое ИЛИ 11 | 11 получаю 11
После сброса биты GPIOB->CRH находятся в 0, выполняю побитовые И
0000
&
0011
получаю
0000
Верно ?
0
3819 / 2388 / 414
Регистрация: 09.09.2017
Сообщений: 10,361
31.01.2022, 12:14 15
Лучший ответ Сообщение было отмечено Danny1996 как решение

Решение

Danny1996, на вашем месте я бы вообще плюнул на GPIO_CRH_CNF13_Pos и работал просто с номерами.
За режим отвечает 4 последовательных бита, то есть, скажем, для PB0 это биты 0-3, для PB1 биты 4-7и т.д. В общем виде (4*x ... 4*x+3) для младших 8 ног (CRL) и (4*(x-8) ... 4*(x-8)+3) для старших (CRH). Таким образом надо и маску накладывать из 4 битов по смещению 4*x или 4*(x-8). Чтобы не делать лишних действий, сначала наложим маску обнуления всех 4 битов, потом выставим только нужные.
C
1
2
GPIOA->CRL &=~ (0b1111 << (4*3));
GPIOA->CRL |= (0b0101 << (4*3)); //понятия не имею, какой это режим, написал первое что пришло в голову
Но после первой операции состояние ножек будет 0000, что, возможно, в каких-то ситуациях, будет небезопасно. Чтобы промежуточное состояние не возникало, вместо двух присваиваний оставим одно:
C
1
2
3
4
uint32_t temp = GPIOA->CRL;
temp &=~ (0b1111 << (4*3));
temp |= (0b0101 << (4*3));
GPIOA->CRL = temp;
Или, если записать в одну строчку и обойтись без временной переменной (для компилятора разницы не будет)
C
1
GPIOA->CRL = (GPIOA->CRL &~(0b1111<<(4*3))) | (0b0101<<(4*3));
1
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 12:14 16
Цитата Сообщение от Danny1996 Посмотреть сообщение
GPIOB->CRH - после сброса имеет состояние тридцати двух нулей.
с какого это перепугу?
почитай даташит, после сброса пины настроены в режим входа, без потягивающих резисторов
у 103 это 04 на каждый пин
0
3819 / 2388 / 414
Регистрация: 09.09.2017
Сообщений: 10,361
31.01.2022, 12:16 17
Цитата Сообщение от ValeryS Посмотреть сообщение
видим и видим вот что
(11 | 01)
А эти 11 и 01 откуда взялись? Судя по коду, из ~(00 | 10), где инверсия почему-то влезла в скобки вперед OR.
0
Маздаененавистник
429 / 583 / 77
Регистрация: 23.11.2021
Сообщений: 3,240
Записей в блоге: 4
31.01.2022, 12:17 18
Danny1996, советую макросов написать вроде таких, тогда не будет непоняток что и куда. Просто пишешь что-то вроде
C
1
2
3
4
    // Set led as opendrain output
    GPIOC->CRH = CRH(13, CNF_ODOUTPUT|MODE_SLOW);
    // USB pullup (PA15) - pushpull output
    GPIOA->CRH = CRH(15, CNF_PPOUTPUT|MODE_SLOW);
И можно все эти CRH/CRL OR'ить. Если пишешь на С++, можно вообще на constexpr'ах и шаблонах сделать проверку введенных данных на стадии сборки (у меня, понятное дело, такой проверки нет: С так не умеет).
0
3819 / 2388 / 414
Регистрация: 09.09.2017
Сообщений: 10,361
31.01.2022, 12:28 19
Цитата Сообщение от Danny1996 Посмотреть сообщение
GPIOB->CRH - после сброса имеет состояние тридцати двух нулей.
Безразлично что там сразу после сброса, вы же не можете гарантировать что этот ваш код не будет выполняться после других настроек, когда содержимое CRH будет совсем неизвестным. Сам регистр выглядит примерно так
aaaabbbb ccccdddd eeeeffff gggghhhh, где aaaa-PB15, bbbb-PB14 и т.д. Вам нужно перевести его сначала в состояние
aaaabbbb 0000dddd eeeeffff gggghhhh, а потом в
aaaabbbb CCCCdddd eeeeffff gggghhhh, где CCCC - те настройки, которые вам нужны.
И еще раз обращаю внимание, что с GPIO_CRH_CNF13_Pos можно не заморачиваться. У вас 13-я нога, то есть 4 бита начиная от 4*(13-8)=20

Добавлено через 6 минут
Цитата Сообщение от Eddy_Em Посмотреть сообщение
советую макросов написать вроде таких
Нет, ему пока надо разобраться с тем, как это работает. Человек ведь для того, надеюсь, и ушел от Куба, чтобы не зависеть от тамошней магии, а понять как делать свою. А вы ему другую магию предлагаете.

Не по теме:

А вообще, моя магия все равно удобнее:

C
1
2
3
4
#define LED B,4,1, GPIO_PP_LS //PB1, active 1, push-pull, low-speed
GPIO_config( LED );
GPO_ON( LED );
GPO_OFF( LED );
Работает как с CRH/CRL, так и с MODER/OSPEEDR, может даже под AVR когда-нибудь портирую, где вообще DDR/PORT.

0
Модератор
Эксперт по электронике
8876 / 6651 / 911
Регистрация: 14.02.2011
Сообщений: 23,413
31.01.2022, 12:30 20
Цитата Сообщение от Danny1996 Посмотреть сообщение
GPIOB->CRH - после сброса имеет состояние тридцати двух нулей.
вот тут и вспоминается locm,смотреть в отладчике нужно

Добавлено через 1 минуту
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А эти 11 и 01 откуда взялись?
а оттуда же, от непонимания бинарных операций
0
31.01.2022, 12:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.01.2022, 12:30
Помогаю со студенческими работами здесь

stm32 hsi/hse
103C8. Запускаю usart1 на hsi. Вывожу сообщение из кольцевого буфера по прерыванию. Работает....

STM32 HSE Кварцевый резонатор устойчивость
Вопрос - у всех слетает тактирование, если за выводы кварца прикоснуться пальцем? Кварц 8М гейер....

HSE запускается на повышенном напряжении (stm32f103c8t6)
Добрый день. Вопрос скорее по железу. Сделал небольшую плату на stm32f103c8t6, для своих целей....

Автоматическое определение частоты внешнего HSE
А можно ли определить какой частоты HSE подключен средствами самого контролера STM32f100? Идея...

stm32f1 stm32f4 cmsis RCC настройка как проверить работу HSE&
/* * main.c * * Created on: 20 бер. 2020 р. * Author: Ivan */ #include &quot;main.h&quot;...

Управление PLL
Здравствуйте! У меня есть pll HMC833LP6GE, но я никак не могу заставить её генерировать сигналы...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru