В микроконтроллерах STM32 система тактирования является довольно навороченной вещью, в сравнении с какими-нибудь AVR-ками. В этой статье я расскажу о выводе MCO, через который можно вывести внутренний тактовый сигнал микроконтроллера за его пределы для тактирования каких-либо внешних периферийных устройств. Предыдущая статья здесь, все статьи цикла можно посмотреть тут: https://dimoon.ru/category/obuchalka/stm32f1.
MCO относится к системе RCC, о которой я рассказывал тут и тут. Ну что, поехали! Приведу часть блок-схемы, на которой изображен MCO:
Рис. 1. Источники тактирования вывода MCO
Тактовый сигнал на вывод MCO может подаваться от SYSCLK, генераторов HSE и HSI, и от сигнала PLL поделенного пополам. В stm32f103c8 вывод MCO подключен к порту PA8, и перед использованием вывода в этом режиме его нужно настроить в режим альтернативной функции. Выбор источника сигнала производится с помощью битов MCO в регистре RCC_CFGR:
Рис. 2. Биты MCO в регистре RCC_CFGR
MCO — подача тактового сигнала на MCO-пин микроконтроллера.
- 0xx: Функция отключена
- 100: Выбран System clock (SYSCLK)
- 101: Выбран сигнал с HSI
- 110: Выбран сигнал с HSE
- 111: Выбран сигнал с PLL, который поделен на 2
Так, вроде все понятно: включаем тактирование GPIOA, настраиваем PA8 в режим альтернативной функции и в регистре RCC_CFGR выбираем источник тактового сигнала, который будет выводиться наружу. Пойдем реализовывать 😉 Код функции инициализации MCO очень простой, поэтому приведу его сразу весь:
//Настройка вывода тактового сигнала //через MCO-пин //sourse - источник тактирования // 0 - отключено // 4 - SYSCLK // 5 - HSI // 6 - HSE // 7 - PLL/2 void MCO_Init(int sourse) { if(sourse != 0 && !(sourse >= 4 && sourse <= 7)) return; RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //Включаем тактирование порта PA //Настраиваем порт в режим альтернативной функции GPIOA->CRH &= ~(GPIO_CRH_MODE8_Msk | GPIO_CRH_CNF8_Msk); //Сбрасываем биты в ноль GPIOA->CRH |= (0x03 << GPIO_CRH_MODE8_Pos) | (0x02 << GPIO_CRH_CNF8_Pos); //устанавливаем нужные биты RCC->CFGR &= ~(RCC_CFGR_MCO_Msk); //Сначала устанавливаем все в ноль RCC->CFGR |= (sourse<<RCC_CFGR_MCO_Pos); //Устанавливаем источник тактирования }
Стоит отметить, что в этом примере PA8 настроен на максимальную частоту 50 МГц, и выходной сигнал не должен превышать эту частоту, то есть если SYSCLK у нас 72 МГц, то этот сигнал нельзя использовать для вывода через PA8. Но мы все-таки попробуем это сделать и посмотрим, что получится 😉
Проверка:
void main() { ClockInit(); // 0 - отключено // 4 - SYSCLK // 5 - HSI // 6 - HSE // 7 - PLL/2 MCO_Init(6); for(;;) { } }
ClockInit() — инициализация системы тактирования, см. Программирование STM32. Часть 4: Настройка RCC. В функции инициализации ClockInit() я только убрал строчку в конце с отключением внутреннего RC-генератора HSI, все остальное так же. Далее, MCO_Init(6) мы настраиваем MCO на вывод тактового сигнала от HSE-генератора. Вот осциллограмма:
Рис. 3. MCO настроен на HSE
Осцилл показывает частоту 8 МГц. Далее, от HSI-генератора (MCO_Init(5)):
Рис. 4. MCO настроен на HSI
Тут у нас должно быть 8 МГц, по факту 8.065. Причем это значение заметно плывет при изменении температуры микроконтроллера. Поехали далее: PLL/2:
Рис. 5. MCO настроен на PLL/2
Тут должен быть меандр с частотой 36 МГц, по факту видим ломаный синус с этой частотой. Мой осцилл уже не вытягивает такие частоты, ибо полоса пропускания у него 50 МГц. Ну и напоследок: подключаем MCO к SYSCLK, частота которого 72 МГц:
Рис. 6. MCO настроен на PLL/2
Тут полный ахтунг, но свои 72 МГц выдает 🙂 К сожалению, о форме сигнала на PA8 судить сложно, так как частота измеряемого сигнала превышает частоту пропускания осцилла. Надо как-нибудь поиграться с настройкой порта и посмотреть, насколько сильно влияют значения битов MODE в регистре GPIOx_CRy на форму выходного сигнала порта. А на этом пока все, продолжение следует!
Все статьи цикла тут: https://dimoon.ru/category/obuchalka/stm32f1
Продолжение: https://dimoon.ru/obuchalka/stm32f1/programmirovanie-stm32-chast-8-dma.html
Стаття виявилась корисною для мене як дізнався я швидко і просто налштувати MCO pin на stm32f103.
Дякую )