Advertisement
Guest User

Untitled

a guest
May 3rd, 2022
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.87 KB | None | 0 0
  1. #include <stdbool.h>
  2.  
  3. #include "stm32f1xx.h"
  4.  
  5.  
  6. // Прототипы используемых функций
  7. int clockInit(void);
  8. void portClockInit(void);
  9. void otherPortInit(void);
  10. void msDelay(int ms);
  11.  
  12.  
  13. int main(void)
  14. {
  15.     // Начальные инициализации оборудования STM32
  16.     clockInit();
  17.     portClockInit();
  18.     otherPortInit(); // <-- Если закомментировать этот вызов, код работает МЕДЛЕННЕЕ
  19.  
  20.  
  21.     // Инициализация порта A0
  22.     uint32_t mode;
  23.     uint32_t cnf;
  24.  
  25.     // Для начала сброс конфигурации пина в ноль
  26.     GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
  27.  
  28.     mode=0b11; // Режим выхода, с максимальной частотой 50 МГц
  29.     cnf=0b00;  // Двухтактный выход (Output push-pull)
  30.     GPIOA->CRL |= (mode << GPIO_CRL_MODE0_Pos)  | (cnf << GPIO_CRL_CNF0_Pos);
  31.  
  32.  
  33.     // Основной цикл
  34.     while (true)
  35.     {
  36.         GPIOA->BSRR = (1<<GPIO_BSRR_BS0_Pos); // Светодиод на A0 включается
  37.         msDelay(1000);
  38.         GPIOA->BRR = (1<<GPIO_BRR_BR0_Pos); // Low
  39.         msDelay(1000);
  40.     }
  41.  
  42.     return 0;    
  43. }
  44.  
  45.  
  46. // Настройка тактирования системы от внешнего кварца
  47. // через PLL на максимально возможных частотах.
  48. // Внешний кварц должен быть на 8МГц
  49. // Возвращает:
  50. //  0 - завершено успешно
  51. //  1 - не запустился кварцевый генератор
  52. //  2 - не запустился PLL
  53. // Настройка делается на 72МГц
  54. int clockInit(void)
  55. {
  56.   __IO int startUpCounter;
  57.  
  58.   ////////////////////////////////////////////////////////////
  59.   //Запускаем кварцевый генератор
  60.   ////////////////////////////////////////////////////////////
  61.  
  62.   RCC->CR |= (1<<RCC_CR_HSEON_Pos); //Запускаем генератор HSE
  63.  
  64.   //Ждем успешного запуска или окончания тайм-аута
  65.   for(startUpCounter=0; ; startUpCounter++)
  66.   {
  67.     //Если успешно запустилось, то
  68.     //выходим из цикла
  69.     if(RCC->CR & (1<<RCC_CR_HSERDY_Pos))
  70.       break;
  71.    
  72.     //Если не запустилось, то
  73.     //отключаем все, что включили
  74.     //и возвращаем ошибку
  75.     if(startUpCounter > 0x1000)
  76.     {
  77.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); //Останавливаем HSE
  78.       return 1;
  79.     }
  80.   }
  81.  
  82.   ////////////////////////////////////////////////////////////
  83.   //Настраиваем и запускаем PLL
  84.   ////////////////////////////////////////////////////////////
  85.  
  86.   //Настраиваем PLL
  87.   RCC->CFGR |= (0x07<<RCC_CFGR_PLLMULL_Pos) //PLL множитель равен 9
  88.             | (0x01<<RCC_CFGR_PLLSRC_Pos); //Тактирование PLL от HSE
  89.  
  90.  
  91.   RCC->CR |= (1<<RCC_CR_PLLON_Pos); //Запускаем PLL
  92.  
  93.   //Ждем успешного запуска или окончания тайм-аута
  94.   for(startUpCounter=0; ; startUpCounter++)
  95.   {
  96.     //Если успешно запустилось, то
  97.     //выходим из цикла
  98.     if(RCC->CR & (1<<RCC_CR_PLLRDY_Pos))
  99.       break;
  100.    
  101.     //Если по каким-то причинам не запустился PLL, то
  102.     //отключаем все, что включили
  103.     //и возвращаем ошибку
  104.     if(startUpCounter > 0x1000)
  105.     {
  106.       RCC->CR &= ~(1<<RCC_CR_HSEON_Pos); //Останавливаем HSE
  107.       RCC->CR &= ~(1<<RCC_CR_PLLON_Pos); //Останавливаем PLL
  108.       return 2;
  109.     }
  110.   }
  111.  
  112.   ////////////////////////////////////////////////////////////
  113.   //Настраиваем FLASH и делители
  114.   ////////////////////////////////////////////////////////////
  115.  
  116.   //Устанавливаем 2 цикла ожидания для Flash
  117.   //так как частота ядра у нас будет 48 MHz < SYSCLK <= 72 MHz
  118.   FLASH->ACR |= (0x02<<FLASH_ACR_LATENCY_Pos);
  119.  
  120.   //Делители
  121.   RCC->CFGR |= (0x00<<RCC_CFGR_PPRE2_Pos) //Делитель шины APB2 отключен
  122.             | (0x04<<RCC_CFGR_PPRE1_Pos) //Делитель нишы APB1 равен 2
  123.             | (0x00<<RCC_CFGR_HPRE_Pos); //Делитель AHB отключен
  124.  
  125.  
  126.   RCC->CFGR |= (0x02<<RCC_CFGR_SW_Pos); //Переключаемся на работу от PLL
  127.  
  128.   //Ждем, пока переключимся
  129.   while((RCC->CFGR & RCC_CFGR_SWS_Msk) != (0x02<<RCC_CFGR_SWS_Pos))
  130.   {
  131.   }
  132.  
  133.   //После того, как переключились на
  134.   //внешний источник такирования
  135.   //отключаем внутренний RC-генератор
  136.   //для экономии энергии
  137.   RCC->CR &= ~(1<<RCC_CR_HSION_Pos);
  138.  
  139.   //Настройка и переключение сисемы
  140.   //на внешний кварцевый генератор
  141.   //и PLL запершилось успехом.
  142.   //Выходим
  143.   return 0;
  144. }
  145.  
  146.  
  147. // Включение тактирования портов
  148. void portClockInit(void)
  149. {
  150.     // Тактирование портов GPIOA и GPIOB
  151.     RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
  152.     RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
  153. }
  154.  
  155.  
  156. // Настройка пинов A8, A9, B3, B4, B6, B7
  157. void otherPortInit(void)
  158. {
  159.     // Для начала сброс конфигурации всех используемых портов в ноль
  160.     GPIOA->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8);
  161.     GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
  162.  
  163.     GPIOB->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3);
  164.     GPIOB->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4);
  165.     GPIOB->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6);
  166.     GPIOB->CRL &= ~(GPIO_CRL_MODE7 | GPIO_CRL_CNF7);
  167.  
  168.  
  169.     uint32_t mode;
  170.     uint32_t cnf;
  171.  
  172.     mode=0b11; // Режим выхода, с максимальной частотой 50 МГц
  173.     cnf=0b00;  // Режим push-pull
  174.     GPIOA->CRH |= (mode << GPIO_CRH_MODE8_Pos) | (cnf << GPIO_CRH_CNF8_Pos);
  175.     GPIOA->CRH |= (mode << GPIO_CRH_MODE9_Pos) | (cnf << GPIO_CRH_CNF9_Pos);
  176.  
  177.     mode=0b00; // Режим входа
  178.     cnf=0b01;  // Режим плавающего входа, подтяжки нет
  179.     GPIOB->CRL |= (mode << GPIO_CRL_MODE3_Pos) | (cnf << GPIO_CRL_CNF3_Pos);
  180.     GPIOB->CRL |= (mode << GPIO_CRL_MODE4_Pos) | (cnf << GPIO_CRL_CNF4_Pos);
  181.     GPIOB->CRL |= (mode << GPIO_CRL_MODE6_Pos) | (cnf << GPIO_CRL_CNF6_Pos);
  182.     GPIOB->CRL |= (mode << GPIO_CRL_MODE7_Pos) | (cnf << GPIO_CRL_CNF7_Pos);
  183. }
  184.  
  185.  
  186. // Функция задержки
  187. void msDelay(int ms)
  188. {
  189.    while (ms-- > 0) {
  190.       volatile int x=500;
  191.       while (x-- > 0)
  192.          __asm("nop");
  193.    }
  194. }
  195.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement