Advertisement
Guest User

Untitled

a guest
Sep 21st, 2022
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.33 KB | None | 0 0
  1. #include <stdbool.h>
  2.  
  3. #include "stm32f1xx.h"
  4.  
  5.  
  6. // Настраиваем тактирование системы от внешнего кварца
  7. // через PLL на максимально возможных частотах.
  8. // Внешний кварц должен быть на 8МГц
  9. // Возвращает:
  10. //  0 - завершено успешно
  11. //  1 - не запустился кварцевый генератор
  12. //  2 - не запустился PLL
  13. // Настройка делается на 72МГц
  14. int ClockInit(void)
  15. {
  16.   __IO int StartUpCounter;
  17.  
  18.   ////////////////////////////////////////////////////////////
  19.   //Запускаем кварцевый генератор
  20.   ////////////////////////////////////////////////////////////
  21.  
  22.   RCC->CR |= (1<<RCC_CR_HSEON_Pos); //Запускаем генератор HSE
  23.  
  24.   //Ждем успешного запуска или окончания тайм-аута
  25.   for(StartUpCounter=0; ; StartUpCounter++)
  26.   {
  27.     //Если успешно запустилось, то
  28.     //выходим из цикла
  29.     if(RCC->CR & (1<<RCC_CR_HSERDY_Pos))
  30.       break;
  31.    
  32.     //Если не запустилось, то
  33.     //отключаем все, что включили
  34.     //и возвращаем ошибку
  35.     if(StartUpCounter > 0x1000)
  36.     {
  37.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); //Останавливаем HSE
  38.       return 1;
  39.     }
  40.   }
  41.  
  42.   ////////////////////////////////////////////////////////////
  43.   //Настраиваем и запускаем PLL
  44.   ////////////////////////////////////////////////////////////
  45.  
  46.   //Настраиваем PLL
  47.   RCC->CFGR |= (0x07<<RCC_CFGR_PLLMULL_Pos) //PLL множитель равен 9
  48.             | (0x01<<RCC_CFGR_PLLSRC_Pos); //Тактирование PLL от HSE
  49.  
  50.  
  51.   RCC->CR |= (1<<RCC_CR_PLLON_Pos); //Запускаем PLL
  52.  
  53.   //Ждем успешного запуска или окончания тайм-аута
  54.   for(StartUpCounter=0; ; StartUpCounter++)
  55.   {
  56.     //Если успешно запустилось, то
  57.     //выходим из цикла
  58.     if(RCC->CR & (1<<RCC_CR_PLLRDY_Pos))
  59.       break;
  60.    
  61.     //Если по каким-то причинам не запустился PLL, то
  62.     //отключаем все, что включили
  63.     //и возвращаем ошибку
  64.     if(StartUpCounter > 0x1000)
  65.     {
  66.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); //Останавливаем HSE
  67.       RCC->CR &= ~(1<<RCC_CR_PLLON_Pos); //Останавливаем PLL
  68.       return 2;
  69.     }
  70.   }
  71.  
  72.   ////////////////////////////////////////////////////////////
  73.   //Настраиваем FLASH и делители
  74.   ////////////////////////////////////////////////////////////
  75.  
  76.   //Устанавливаем 2 цикла ожидания для Flash
  77.   //так как частота ядра у нас будет 48 MHz < SYSCLK <= 72 MHz
  78.   FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos);
  79.  
  80.   //Делители
  81.   RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos) //Делитель шины APB2 отключен
  82.             | (0x04<<RCC_CFGR_PPRE1_Pos) //Делитель нишы APB1 равен 2
  83.             | (0x00<<RCC_CFGR_HPRE_Pos); //Делитель AHB отключен
  84.  
  85.  
  86.   RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos); //Переключаемся на работу от PLL
  87.  
  88.   //Ждем, пока переключимся
  89.   while((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0x02<<RCC_CFGR_SWS_Pos))
  90.   {
  91.   }
  92.  
  93.   //После того, как переключились на
  94.   //внешний источник такирования
  95.   //отключаем внутренний RC-генератор
  96.   //для экономии энергии
  97.   RCC->CR &= ~(1<<RCC_CR_HSION_Pos);
  98.  
  99.   //Настройка и переклбючение сисемы
  100.   //на внешний кварцевый генератор
  101.   //и PLL запершилось успехом.
  102.   //Выходим
  103.   return 0;
  104. }
  105.  
  106.  
  107. void delayMs(int ms)
  108. {
  109.    while (ms-- > 0) {
  110.       volatile int x=500;
  111.       while (x-- > 0)
  112.          __asm("nop");
  113.    }
  114. }
  115.  
  116.  
  117. //Alternates blue and green LEDs quickly
  118. int main(void)
  119. {
  120.     ClockInit();
  121.  
  122.     //Включение тактирования портов GPIOA/GPIOB/GPIOC
  123.     RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
  124.     RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
  125.     RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
  126.  
  127.     const uint32_t mode=0b11; // Режим выхода, с максимальной частотой 50 МГц
  128.     const uint32_t cnf=0b00;  // 00 - Двухтактный выход (Output push-pull)
  129.  
  130.     // A0
  131.     // Сброс конфигурации порта
  132.     GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
  133.     GPIOA->CRL |= (mode << GPIO_CRL_MODE0_Pos)  | (cnf << GPIO_CRL_CNF0_Pos);
  134.  
  135.     // C13
  136.     // Сброс конфигурации порта
  137.     GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
  138.     GPIOC->CRH |= (mode << GPIO_CRH_MODE13_Pos) | (cnf << GPIO_CRH_CNF13_Pos);
  139.  
  140.  
  141.     while (true)
  142.     {
  143.         delayMs(5500);
  144.         GPIOA->BSRR = (1<<GPIO_BSRR_BS0_Pos);  // Hi A0
  145.         GPIOC->BSRR = (1<<GPIO_BSRR_BS13_Pos); // Hi C13
  146.  
  147.         delayMs(5500);
  148.         GPIOA->BRR = (1<<GPIO_BSRR_BS0_Pos);  // Low A0
  149.         GPIOC->BRR = (1<<GPIO_BSRR_BS13_Pos); // Low C13
  150.     }
  151.  
  152.     return 0;
  153. }
  154.  
  155.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement