STM32F030:RCC

Z kiwiki
Prejsť na: navigácia, hľadanie

Obsah

Reset and Clock Control

Knižnica RCC poskytuje nasledovné možnosti:

  • nastavenie interného alebo externého hodinového signálu
  • konfigurácia častí PLL, CSS a MCO
  • časovanie zberníc AHB, APB a systémovej zbernice

Definícia pojmov

PLL
Phase-Locked Loop. Fázový záves generuje výstupný signál, ktorého fáza závisí na fáze vstupného, „referenčného“, signálu. Obvod porovnáva fázu vstupného signálu s fázou signálu produkovaného oscilátorom a frekvenciu oscilátora upravuje, aby sa fázy zhodovali. Zdroj hodinového sygnálu pre systémové hodiny.
CSS
Clock security system. Bezpečnostný prvok pri práci s externým oscilátorom. Ak sa vyskytne chyba s oscilátorom HSE, potom je tento oscilátor automaticky zakázaný a je vygenerované prerušenie CSSI
CSSI
Clock Security System Interrupt. Prerušenie od CSS
MCO
Microcontroller Clock Output. Poskytuje hodinový výstup z častí SYSCLK, HSI. HSI14, LSI, HSE, LSE, PLL na pin PA8
AHB
Advanced High-performance Bus. Vysokorýchlostná zbernica na ktorú sú pripojené časti: GPIO porty, jardo MCU, FLASH, SRAM, RRC, CRC
APB
Advanced Peripheral Bus. Zbernice pre prefiférie (nižšia rýchlosť). Spája časti: časovače, USART, I2C, RTC, IWDG, SPI
HSE
High Speed External. Externý zdroj rýchleho hodinového signálu. Frekvencia: od 4 do 32 MHz
HSI
High Speed Internal. Interný zdroj rýchleho hodinového signálu. Frekvencia: 8 MHz
HSI14
High Speed Internal for ADC. Interný zdroj rýchleho hodinového signálu pre prevodník ADC. Frekvencia: 14 MHz
LSI
Low Speed Internal. Interný kryštál 40kHz. Použitie pre IDWG alebo hodiny reálneho času (RTC)
LSE
Low Speed External. 32kHz externý oscilátor hodiny reálneho času (RTC)


Schéma časovania v STM32F0

Stm32f030 clock2.png

Blok RCC s výpisom riadiacich funkcií zo štandardnej knižnice


Ako pracovať s RRC

  • Po zapnutí/resete je MCU taktované z HSI (8MHz). Všetky periférie okrem internej SRAM, FLSH a SWD sú vypnuté.
    • Pre zbernice AHB a APB nie sú definované žiadne násobiče frekvencie. Všetky periférie idú na 8MHz.
    • Všetky periférie okrem SRAM a FLASH majú vypnuté časovanie
    • všetky piny GPIO okrem pinov SWD sú v stave "vstup"

Odporúčaný postup konfigurácie hodín:

  • Konfigurácia zdroja hodín pre systémové hodiny (v prípade, že je potrebná oná frekvencia ako 8MHz),
  • Nastavenie požadovanej frekvencie pre systémové hodiny,
  • nastavenie násobičov pre zbernice AHB a APB
  • povoliť hodinový signál pre periférie, ktoré sa budú používať,
  • nastaviť zdroj hodín pre periférie, ktoré nie sú odvodené od systémových hodín: ADC, CEC, I2C, USART, RTC a IWDG

Často používané štruktúry a funkcie

void RCC_DeInit(void)
Reset nastavenia hodín
/**
  * Resetuje hodiny RCC do prednastaveného stavu:
  *     HSI: aktívne, použité ako zdroj systémových hodín
  *     HSI14, HSE, PLL: vypnuté
  *     AHB, APB násobič: nastavený na 1.
  *     CSS, MCO: vypnuté
  *     všetky prerušenia sú zakázané
  * Táto funkcia nemení nastanie: periférych hodín, LSI, LSE a RTC
  */
void RCC_DeInit(void)
RCC_HSEConfig(RCC_HSE)
Konfigurácia externého hodinového signálu HSE
/**
  * Poznámky
  *    Stav HSE nemôže byť zmenený ak je používaný priamo cez PLL a systémové
       hodiny. V tomto prípade je potrebné vybrať iný zdroj pre systémové hodiny
       a potom zmeniť stav HSE.
  *    HSE je zastavené keď zariadenie vchádza do režimu STOP alebo STANDBY.
  *    Táto funkcia resetuje bit CSSON, takže ak bolo povolené CSS, je potrebné 
       ho znova povoliť po zavolaní tejto funkcie.
  * Parametre:  RCC_HSE - nový stav HSE. Môže mať hodnoty:
  *             RCC_HSE_OFF: vypne HSE oscilátor. príznak HSERDY bude 0 po 6-tich cykloch oscilátora HSE
  *             RCC_HSE_ON: zapne HSE oscilátor
  *             RCC_HSE_Bypass: HSE oscilátor bude nahradený externými hodinami
  */
void RCC_HSEConfig(uint8_t RCC_HSE)
RCC_HSICmd(NewState)
Zapne/vypne interný oscilátor HSI
/**
  * Poznámky
  *    Stav HSI nemôže byť zmenený ak je používaný priamo cez PLL a systémové
       hodiny. V tomto prípade je potrebné vybrať iný zdroj pre systémové hodiny
       a potom zmeniť stav HSI.
  *    HSI je zastavené keď zariadenie vchádza do režimu STOP alebo STANDBY.
  * parameter  NewState: nový stav HSI.
  *          Parameter môže mať hdonotu ENABLE alebo DISABLE.
  * poznámka:  keď je HSI zastavené príznak HSIRDY zmení stav na 0 po 6-tich taktoch HSI oscilátora.
  */
void RCC_HSICmd(FunctionalState NewState)
RCC_LSEConfig(RCC_LSE)
konfigurácia externého nízkofrekvenčného oscilátora LSE
/**
  * Poznámky:
  *   Po resete je LSE zakázaný, preto sa jeho stav dá meniť až po povolení.
      LSE sa povolí pomocou funkcie PWR_BackupAccessCmd(ENABLE).
  *   Po povolení LSE je potrebné počkať na príznak LSERDY, ktorý indikuje že
      hodiny LSE sú stabilné.  
  * parameter RCC_LSE: definuje nový stav LSE. Môže mať hdonoty
  *            RCC_LSE_OFF: vypne LSE oscilátor, príznka LSERDY sa vynyluje po 6-tich cykloch LSE
  *            RCC_LSE_ON: zapne LSE oscilátor
  *            RCC_LSE_Bypass: LSE oscilátor je nahradený externými hodinami
  */
void RCC_LSEConfig(uint32_t RCC_LSE)
RCC_LSICmd(NewState)
Zapne/vypne interný oscilátor LSI
/**
  * Poznámky
  *    Po povolení LSI je potrebné počkať na príznak LSIRDY, ktorý indikuje, že LSI je stabilný.
  *    LSI sa nedá zakázať ak beží IDWG
  * parameter  NewState: nový stav LSI.
  *          Parameter môže mať hdonotu ENABLE alebo DISABLE.
  * poznámka:  keď je LSI zastavené príznak LSIRDY zmení stav na 0 po 6-tich taktoch LSI oscilátora.
  */
void RCC_LSICmd(FunctionalState NewState)
RCC_PLLCmd(NewState)
zapne/vypne PLL
/**
  * Poznámky
  *    Po povolení PLL je potrebné počkať na príznak PLLRDY, ktorý indikuje, že PLL je stabilný.
  *    PLL sa nedá zakázať ak je použitý ako zdroj pre systémové hodiny.
  *    PLL je hardvérovom zakázaný keď MCU ide do stavu STOP alebo STANDBY
  * Parameter NewState: nový stav PLL. Môže mať hodnoty ENABLE alebo DISABLE
  */
RCC_PLLConfig(RCC_PLLSource, RCC_PLLMul)
Konfiguruje zdroj PLL a násobiť frekvencie
/**
  * Poznámka:  Funkcia môže byť použitá len keď je PLL vypnuté.
  *
  * Parameter RCC_PLLSource: špecifikuje zdroj pre PLL. Ako zdroj pre PLL je
  *             RCC_PLLSource_HSI_Div2: HSI oscilátor
  *             RCC_PLLSource_PREDIV1: blok PREDIV1
  *             RCC_PLLSource_HSI48: HSI48 oscilátor (len pre STM32F072)
  *             RCC_PLLSource_HSI: HSI hodiny (len pre STM32F072)
  * Parameter RCC_PLLMul: určuje násobič frekvencie pre PLL.
  *          Možné hodnoty: RCC_PLLMul_x kde x:[2,16] 
  */
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)

Systémová zbernica, AHB a APB zbernica

Pre systémový hodinový signál (SYSCLK) môžu byť použité viaceré zdroje: HSI, HSE alebo PLL. Hodiny pre zbernicu AHB (HCLK) sú odvodené od systémových hodín cez konfigurovateľný delič frekvencie. Tento signál je použitý pre tajtovanie CPU, pamäti a periférií namapovaných na zbernicu AHB (DMA a GPIO). Hodiny pre zbernicu APH (PCLK) sú odvodené zo signálu AHB cez delič frekvencie. Pomocou funkcie "RCC_GetClocksFreq()" je možné získať frekvencie týchto hodín.

Všetky hodiny pre periférie sú odvodené od systémových hodín (SYSCLK) okrem nasledujúcich:

  • hodiny pre ADC, ktoré sú odvodené od HSI14 alebo APB (APB podelené deličom 2 alebo 4)
  • hodiny CEC odvodené od LSE alebo HSI/244
  • hodiny pre I2C sú odvodené od HSI alebo SYSCLL
  • hodiny pre USART sú odvodené od HSI, SYSCLK, APB alebo LSE
  • hodiny pre RTC/LCD sú odvodené od LSE, LSI alebo 2MHz HSE_RTC. Frekvencia SYSCLK musí byť väčšia alebo rovná ako RTC/LCD frekvencia.
  • hodiny pre IDWG používajú vždy hodiny LSI

Maximálna ffrekvencia SYSCLK, HCLK a OCLK je 48 MHz. V závislosti od maximálnej frekvencie je pre FLASH udávaný čas čakania nasledujúce:

  • 0 < HCLK <= 24 MHz : stav čakania = 1 cyklus CPU (0WS)
  • 24 < HCLK <= 48 MHz : stav čakania = 2 cykly CPU (1WS)

Po resete je zdroj SYSCLK nastavený HSI (8MHz), 0WS, prednačítanie (prefetch) je zakázané.

Často používané štruktúry a funkcie

RCC_SYSCLKConfig(RCC_SYSCLKSource)
Konfigurácia systémových hodín SYSCLK
/**
  * Hodiny HSE sú použité ako systémové hodiny SYSCLK po reštarte,
  * zobudenia sa zo stavov STOP a STNADBY. Taktiež v prípade, že
  * zlyhá HSE.
  * Prepnutie medzi zdrojmi signálov je úspešné len vtedy ak je požadovaný
  * zdroj hodín pripravený. Pomocou funkcie RCC_GetSYSCLKSource() sa dá zistiť
  * či zmena zdroja signálu prebehla.
  * Parameter  RCC_SYSCLKSource: špecifikuje nový zdroj hodín. Možné hodnoty:
  *            RCC_SYSCLKSource_HSI
  *            RCC_SYSCLKSource_HSE
  *            RCC_SYSCLKSource_PLLCLK
  *            RCC_SYSCLKSource_HSI48 (len pre STM32F072)
  */
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
RCC_GetSYSCLKSource()
vráti zdroj hodinového signálu
/**
  * Ako návratové hodnota je kód zdroju signálu:
  *           - 0x00: zdroj hodín je HSI
  *           - 0x04: zdroj hodín je HSE
  *           - 0x08: zdroj hodín je PLL
  *           - 0x0C: zdroj hodín je HSI48
  */
uint8_t RCC_GetSYSCLKSource(void)
RCC_HCLKConfig(RCC_SYSCLK)
Konfigurácia hodín AHB (HCLK)
/**
  * Parameter RCC_SYSCLK: definuje delič pre frekvenciu AHB. Hodnoty parametra RCC_SYSCLK:
  *            RCC_SYSCLK_Div1:   AHB clock = SYSCLK
  *            RCC_SYSCLK_Div2:   AHB clock = SYSCLK/2
  *            RCC_SYSCLK_Div4:   AHB clock = SYSCLK/4
  *            RCC_SYSCLK_Div8:   AHB clock = SYSCLK/8
  *            RCC_SYSCLK_Div16:  AHB clock = SYSCLK/16
  *            RCC_SYSCLK_Div64:  AHB clock = SYSCLK/64
  *            RCC_SYSCLK_Div128: AHB clock = SYSCLK/128
  *            RCC_SYSCLK_Div256: AHB clock = SYSCLK/256
  *            RCC_SYSCLK_Div512: AHB clock = SYSCLK/512
  */
void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
RCC_PCLKConfig(RCC_HCLK)
Konfigurácia hodín APB (PCLK)
/**
  * Parameter RCC_HCLK: definuje delič pre frekvenciu APB:
  *            RCC_HCLK_Div1: APB clock = HCLK
  *            RCC_HCLK_Div2: APB clock = HCLK/2
  *            RCC_HCLK_Div4: APB clock = HCLK/4
  *            RCC_HCLK_Div8: APB clock = HCLK/8
  *            RCC_HCLK_Div16: APB clock = HCLK/16
  */
void RCC_PCLKConfig(uint32_t RCC_HCLK)

Konfigurácia časovačov periférií

  • po reštarte zariadenia, alebo zobudenia zo stavu STANDBY sú všetky hodiny periférií v stave OFF okrem internej SRAM, FLASH a SWD. Pred použitím zvolenej periférie je potrebné povoliť hodinový signál v danej periférii. Toto sa urobí pomocou funkcie RCC_AHBPeriphClockCmd(), RCC_APB2PeriphClockCmd() alebo RCC_APB1PeriphClockCmd().
  • pre resetovanie konfigurácie časovania periférie sa použijú funkcie: RCC_AHBPeriphResetCmd(), RCC_APB2PeriphResetCmd() alebo RCC_APB1PeriphResetCmd()

Často používané štruktúry a funkcie

RCC_AHBPeriphClockCmd(RCC_AHBPeriph, NewState): povoľuje/zakazuje taktovanie periférií na AHB

/**
  * Parameter RCC_AHBPeriph: definuje AHB perifériu, s ktorou sa bude pracovať:
  *             RCC_AHBPeriph_GPIOA
  *             RCC_AHBPeriph_GPIOB
  *             RCC_AHBPeriph_GPIOC
  *             RCC_AHBPeriph_GPIOD
  *             RCC_AHBPeriph_GPIOE (len pre STM32F072)
  *             RCC_AHBPeriph_GPIOF
  *             RCC_AHBPeriph_TS
  *             RCC_AHBPeriph_CRC
  *             RCC_AHBPeriph_FLITF: funguje le v prípade, keď je FLASH v režime "power down"
  *             RCC_AHBPeriph_SRAM
  *             RCC_AHBPeriph_DMA1
  * Parameter NewState: definuje stav hodín pre vybranú perifériu
  *          možné hodnoty: ENABLE, DISABLE.
  */
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
RCC_APB2PeriphClockCmd(RCC_APB2Periph, NewState)
povoľuje/zakazuje taktovanie periférií na APB (APB2)
/**
  * Parameter RCC_APB2Periph: definuje APB2 perifériu, s ktorou sa bude pracovať: 
  *             RCC_APB2Periph_SYSCFG
  *             RCC_APB2Periph_ADC1
  *             RCC_APB2Periph_TIM1
  *             RCC_APB2Periph_SPI1
  *             RCC_APB2Periph_USART1
  *             RCC_APB2Periph_TIM15
  *             RCC_APB2Periph_TIM16
  *             RCC_APB2Periph_TIM17
  *             RCC_APB2Periph_DBGMCU
  * Parameter NewState: definuje stav hodín pre vybranú perifériu
  *          možné hodnoty: ENABLE, DISABLE.
  */
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
RCC_APB1PeriphClockCmd(RCC_APB1Periph,NewState)
povoľuje/zakazuje taktovanie periférií na APB (APB1)
/**
  * Parameter RCC_APB1Periph: definuje APB1 perifériu, s ktorou sa bude pracovať: 
  *           RCC_APB1Periph_TIM2 (len pre STM32F051 a STM32F072)
  *           RCC_APB1Periph_TIM3
  *           RCC_APB1Periph_TIM6
  *           RCC_APB1Periph_TIM14
  *           RCC_APB1Periph_WWDG
  *           RCC_APB1Periph_SPI2
  *           RCC_APB1Periph_USART2
  *           RCC_APB1Periph_I2C1
  *           RCC_APB1Periph_I2C2
  *           RCC_APB1Periph_PWR
  *           RCC_APB1Periph_DAC (len pre STM32F051 a STM32F072)
  *           RCC_APB1Periph_CEC (len pre STM32F051, STM32F042, STM32F072)
  * Parameter NewState: definuje stav hodín pre vybranú perifériu
  *          možné hodnoty: ENABLE, DISABLE.
  */
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)

Príklady

Maximálna frekvencia

Zadanie: nakonfigurujte MCU na max. frekvenciu 48MHz

Riešenie: Toto nastavenie dosiahneme pomocou funkcie RCC_SYSCLKConfig. Program bude v pravidelných intervaloch posielať na sériový port informáciu o hodnote SYSCLK.

Vzorový výstup zo sériového terminála:

f1=....
výstup v hex formáte:
46 31 3D 02 dc 60 00

Tento text sa stále opakuje. Dôležité sú posledné 4 znaky: 02 dc 60 00. Prevodom do desiatkovej sústavy získame 48 000 000.

#include "stm32f0xx.h"
 
void delay (int a);
void system_init(void);
void sendData(char d);
void sendFreqInfo();
void RRC_Configuration();
void GPIO_Configuration(void);
void USART_Configuration(void);
 
int main(void){
    system_init();
 
    while (1){
        sendFreqInfo();
        delay(1600000);
    }
}
 
void system_init(void){
    RRC_Configuration();
    GPIO_Configuration();
    USART_Configuration();
}
 
void RRC_Configuration(){
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
 
    RCC_HSEConfig(RCC_HSE_OFF);
    RCC_DeInit();
    // HSI/2 = 4 Mhz * 12 = 48 MHz
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
    // PLL je po resete zakazane, povolime ho
    RCC_PLLCmd(ENABLE);
    // nastav PLL sko systemove hodiny
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    // je potrebne zavolat po zmene konfguracie hodin!!!
    SystemCoreClockUpdate();
 
}
 
void GPIO_Configuration(void){
    GPIO_InitTypeDef   GPIO_InitStructure;
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); // USART1 TX
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
}
 
void USART_Configuration(void){
    USART_InitTypeDef USART_InitStructur;
    USART_InitStructur.USART_BaudRate = 9600;
    USART_InitStructur.USART_WordLength = USART_WordLength_9b;
    USART_InitStructur.USART_StopBits = USART_StopBits_1;
    USART_InitStructur.USART_Parity = USART_Parity_Even;
    USART_InitStructur.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructur.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructur);
    USART_Cmd(USART1,ENABLE);
}
 
void sendData(char d){
    USART_SendData(USART1, d);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
}
 
void sendFreqInfo(){
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
 
    sendData('F');
    sendData('1');
    sendData('=');
    sendData(RCC_Clocks.SYSCLK_Frequency>>24);
    sendData(RCC_Clocks.SYSCLK_Frequency>>16 & 0x00FF);
    sendData(RCC_Clocks.SYSCLK_Frequency>>8 &  0x0000FF);
    sendData(RCC_Clocks.SYSCLK_Frequency &     0x000000FF);
}
void delay (int a){
    volatile int i,j=0;
    for (i=0 ; i < a ; i++){
        j++;
    }
    return;
}
Osobné nástroje
Menné priestory

Varianty
Operácie
Navigácia
Rýchle linky
Nástroje
Tlačiť/exportovať