Advertisement
Guest User

Untitled

a guest
Oct 11th, 2022
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.17 KB | None | 0 0
  1. #include <stdbool.h>
  2.  
  3. #include "stm32f1xx.h"
  4.  
  5. // Прототипы используемых функций
  6. void delayMs(int ms);
  7. int  clockInit();
  8.  
  9. int main(void)
  10. {
  11.     // Начальные инициализации оборудования STM32
  12.     clockInit();
  13.  
  14.     // Включение тактирования портов GPIOA, GPIOB, GPIOC
  15.     RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
  16.     RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
  17.     RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
  18.  
  19.     // Обязательный сброс конфигурации портов в 0
  20.     GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
  21.  
  22.     GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
  23.     GPIOC->CRH &= ~(GPIO_CRH_MODE14 | GPIO_CRH_CNF14);
  24.  
  25.     GPIOB->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3);
  26.     GPIOB->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);
  27.  
  28.     // Настройка режимов портов
  29.     uint32_t mode=0b11; // Режим выхода, с максимальной частотой 50 МГц
  30.     uint32_t cnf=0b00;  // Режим push-pull
  31.  
  32.     GPIOA->CRL |= (mode << GPIO_CRL_MODE0_Pos)  | (cnf << GPIO_CRL_CNF0_Pos);
  33.  
  34.     GPIOC->CRH |= (mode << GPIO_CRH_MODE13_Pos) | (cnf << GPIO_CRH_CNF13_Pos);
  35.     GPIOC->CRH |= (mode << GPIO_CRH_MODE14_Pos) | (cnf << GPIO_CRH_CNF14_Pos);
  36.  
  37.     GPIOB->CRL |= (mode << GPIO_CRL_MODE3_Pos) | (cnf << GPIO_CRL_CNF3_Pos);
  38.     GPIOB->CRL |= (mode << GPIO_CRL_MODE4_Pos) | (cnf << GPIO_CRL_CNF4_Pos);
  39.  
  40.  
  41.     while (true)
  42.     {
  43.         delayMs(500);
  44.         GPIOA->BSRR = (1<<GPIO_BSRR_BR0_Pos);
  45.  
  46.         GPIOC->BSRR = (1<<GPIO_BSRR_BR13_Pos);
  47.         GPIOC->BSRR = (1<<GPIO_BSRR_BR14_Pos);
  48.        
  49.         GPIOB->BSRR = (1<<GPIO_BSRR_BR3_Pos);
  50.         GPIOB->BSRR = (1<<GPIO_BSRR_BR4_Pos);
  51.  
  52.         delayMs(500);
  53.         GPIOA->BSRR = (1<<GPIO_BSRR_BS0_Pos);
  54.  
  55.         GPIOC->BSRR = (1<<GPIO_BSRR_BS13_Pos);
  56.         GPIOC->BSRR = (1<<GPIO_BSRR_BS14_Pos);
  57.  
  58.         GPIOB->BSRR = (1<<GPIO_BSRR_BS3_Pos);
  59.         GPIOB->BSRR = (1<<GPIO_BSRR_BS4_Pos);
  60.     };
  61.        
  62.     return 0;
  63. }
  64.  
  65.  
  66. // Функция задержки в микросекундах, размещается в ОЗУ
  67. __attribute__((noinline, section(".ramfunc")))
  68. void delayMs(int ms)
  69. {
  70.   uint32_t cycles = ms * F_CPU / 9 / 1000;
  71.  
  72.   __asm volatile (
  73.     "1: subs %[cycles], %[cycles], #1 \n"
  74.     "   bne 1b \n"
  75.     : [cycles] "+r"(cycles)
  76.   );
  77. }
  78.  
  79.  
  80. // Настройка тактирования системы от внешнего кварца
  81. // через PLL на максимально возможных частотах.
  82. // Внешний кварц должен быть на 8МГц
  83. // Возвращает:
  84. //  0 - завершено успешно
  85. //  1 - не запустился кварцевый генератор
  86. //  2 - не запустился PLL
  87. // Настройка делается на 72МГц
  88. int clockInit(void)
  89. {
  90.   __IO int startUpCounter;
  91.  
  92.   //////////////////////////////////
  93.   // Запускаем кварцевый генератор
  94.   //////////////////////////////////
  95.  
  96.   RCC->CR |= (1<<RCC_CR_HSEON_Pos); // Запускаем генератор HSE
  97.  
  98.   //Ждем успешного запуска или окончания тайм-аута
  99.   for(startUpCounter=0; ; startUpCounter++)
  100.   {
  101.     // Если успешно запустилось, то выходим из цикла
  102.     if(RCC->CR & (1<<RCC_CR_HSERDY_Pos))
  103.       break;
  104.    
  105.     // Если не запустилось, то отключаем все, что включили
  106.     // и возвращаем ошибку
  107.     if(startUpCounter > 0x1000)
  108.     {
  109.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); // Останавливаем HSE
  110.       return 1;
  111.     }
  112.   }
  113.  
  114.   ////////////////////////////////
  115.   // Настраиваем и запускаем PLL
  116.   ////////////////////////////////
  117.  
  118.   // Настраиваем PLL
  119.   RCC->CFGR |= (0x07<<RCC_CFGR_PLLMULL_Pos) | // PLL множитель равен 9
  120.                (0x01<<RCC_CFGR_PLLSRC_Pos);   // Тактирование PLL от HSE
  121.  
  122.  
  123.   RCC->CR |= (1<<RCC_CR_PLLON_Pos); // Запускаем PLL
  124.  
  125.   // Ждем успешного запуска или окончания тайм-аута
  126.   for(startUpCounter=0; ; startUpCounter++)
  127.   {
  128.     // Если успешно запустилось, то
  129.     // выходим из цикла
  130.     if(RCC->CR & (1<<RCC_CR_PLLRDY_Pos))
  131.       break;
  132.    
  133.     // Если по каким-то причинам не запустился PLL, то
  134.     // отключаем все, что включили
  135.     // и возвращаем ошибку
  136.     if(startUpCounter > 0x1000)
  137.     {
  138.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); // Останавливаем HSE
  139.       RCC->CR &= ~(1<<RCC_CR_PLLON_Pos); // Останавливаем PLL
  140.       return 2;
  141.     }
  142.   }
  143.  
  144.   /////////////////////////////////
  145.   // Настраиваем FLASH и делители
  146.   /////////////////////////////////
  147.  
  148.   // Устанавливаем 2 цикла ожидания для Flash
  149.   // так как частота ядра у нас будет 48 MHz < SYSCLK <= 72 MHz
  150.   FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos);
  151.  
  152.   // Делители
  153.   RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos) | // Делитель шины APB2 отключен
  154.                (0x04<<RCC_CFGR_PPRE1_Pos) | // Делитель нишы APB1 равен 2
  155.                (0x00<<RCC_CFGR_HPRE_Pos);   // Делитель AHB отключен
  156.  
  157.  
  158.   RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos); // Переключаемся на работу от PLL
  159.  
  160.   // Ждем, пока переключимся
  161.   while((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0x02<<RCC_CFGR_SWS_Pos))
  162.   {
  163.   }
  164.  
  165.   // После того, как переключились на
  166.   // внешний источник такирования
  167.   // отключаем внутренний RC-генератор
  168.   // для экономии энергии
  169.   RCC->CR &= ~(1<<RCC_CR_HSION_Pos);
  170.  
  171.   // Здесь настройка и переключение сисемы на внешний
  172.   // кварцевый генератор и PLL запершилось успехом.
  173.  
  174.   //Выходим
  175.   return 0;
  176. }
  177.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement