Laboratorium 1 – system zegarów, porty wejścia/wyjścia

Transkrypt

Laboratorium 1 – system zegarów, porty wejścia/wyjścia
M. Suchenek
MARM
Laboratorium 1 – system zegarów, porty wejścia/wyjścia
Celem laboratorium jest zapoznanie się ze środowiskiem uruchomieniowym Keil
µVision, w tym konfiguracja środowiska, systemu zegarów, portów wejścia/wyjścia.
Strukturę systemu zegarów mikrokontrolera STM32F411 przedstawia diagram:
1
1. Konfigurację systemu zegarów
Konfigurację systemu zegarów należy rozpocząć od inicjalizacji wartości domyślnych
dla systemu zegarów funkcją:
void RCC_DeInit(void)
Ustawia ona:
• HSI – włączone
• HSE, PLL – wyłączone
• wyjścia MOC1-2 – wyłączone,
nie zmienia ustawień dla LSE i LSI.
Następnie wybrać należy odpowiednie źródła zegara dla mikrokontrolera, to jest
przynajmniej jeden z zegarów: HSE, HSI, LSE, LSI.
Konfiguracja zewnętrznego źródła zegara HSE:
RCC_HSEConfig(uint32_t RCC_HSE)
parametry wejściowe:
• RCC_HSE_ON/RCC_HSE_OFF – włącza/wyłącza zewnętrzny oscylator
• RCC_HSE_Bypass – pozwala podać zewnętrzny zegar na wejście HSE
Funkcja czeka na włączenie zegara HSE
ErrorStatus RCC_WaitForHSEStartUp(void), funkcja zwraca:
• SUCCESS – oscylator HSE jest stabilny i gotowy
• ERROR – nie jest gotowy
Włączenie/wyłączenie szybkiego wbudowanego zegara HSI:
void RCC_HSICmd(FunctionalState NewState), parametr wejściowy przyjmuje
wartości: ENABLE bądź DISABLE
kalibracja wewnętrznego źródła zegara:
void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue) – dopuszczalne
wartości: 0 – 0x1F
Konfiguracja zewnętrznego wolnego zegara LSE:
void RCC_LSEConfig(uint8_t RCC_LSE), parametry wejściowe:
• RCC_LSE_ON – włącza źródło jako oscylator
• RCC_LSE_OFF – wyłącza
• RCC_LSE_Bypass – pozwala podać zewnętrzny zegar na wejście LSE
Włączenie/wyłączenie wewnętrznego oscylatora LSI:
void RCC_LSICmd(FunctionalState NewState), parametry wejściowe funkcji ENABLE
lub DISABLE
Oprócz włączenia zegara należy skonfigurować odpowiednio multiplekser „System
clock mux”, który określa źródło zegara dla mikrokontrolera:
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
• RCC_SYSCLKSource_HSI – wewnętrzny zegar szybki HSI
• RCC_SYSCLKSource_HSE – zewnętrzny zegar szybki HSE
• RCC_SYSCLKSource_PLLCLK – zegar z pętli fazowej PLL
2
Do sprawdzenia poprawności konfiguracji systemu zegarów można skorzystać z funkcji
sprawdzającej źródło zegara:
uint8_t RCC_GetSYSCLKSource(void), funkcja zwraca:
• 0x00 - HSI used as system clock
• 0x04 - HSE used as system clock
• 0x08 - PLL used as system clock
sprawdzającej częstotliwość pracy zegara głównego:
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
sprawdzającej gotowość zegara bądź oscylatora do pracy:
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
• RCC_FLAG_HSIRDY: gotowość zegara HSI
• RCC_FLAG_HSERDY: gotowość zegara HSE
• RCC_FLAG_PLLRDY: gotowość pętli fazowej PLL
• RCC_FLAG_PLLI2SRDY: PLLI2S
• RCC_FLAG_PLLSAIRDY: PLLSAI
• RCC_FLAG_LSERDY: gotowość zegara LSE
• RCC_FLAG_LSIRDY: gotowość zegara LSI
oraz przyczynę wyzerowania mikrokontrolera:
• RCC_FLAG_BORRST: POR/PDR bądź BOR reset
• RCC_FLAG_PINRST: poprzez pin reset
• RCC_FLAG_PORRST: POR/PDR reset
• RCC_FLAG_SFTRST: Software reset
• RCC_FLAG_IWDGRST: reset poprzez niezależny watchdog
• RCC_FLAG_WWDGRST: reset poprzez watchdog okienkowy
• RCC_FLAG_LPWRRST: Low Power reset
Funkcja zwracane FlagStatus, która może przyjąć wartość SET lub RESET
Konfiguracja pętli fazowej PLL:
void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN,
uint32_t PLLP, uint32_t PLLQ)
RCC_PLLSource – określa źródło zegara dla pętli fazowej:
• RCC_PLLSource_HSI
• RCC_PLLSource_HSE
PLLM - dzielnik częstotliwości dla VCO: ustawiany w zakresie 0-63
PLLN - mnożnik częstotliwości dla VCO: ustawiany w zakresie 192 - 432
PLLP - dzielnik częstotliwości dla zegara mikrokontrolera SYSCLK (2,4,6,8)
PLLQ - dzielnik zegara dla układów: OTG FS, SDIO i RNG 4-15
Uwaga: VCO pętli fazowej może pracować w zakresie częstotliwości od 192 do
432 MHz
Włączenie pętli fazowej:
void RCC_PLLCmd(FunctionalState NewState)
NewState może przyjąć wartości określone jako ENABLE bądź DISABLE
3
Konfiguracja zegarów dla magistral AHB, APB1, APB2:
konfiguracja zegarów dla magistrali AHB (HCLK)
void RCC_HCLKConfig(uint32_t 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
konfiguracja wolnych zegarów dla magistrali APB1 (PCLK1)
void RCC_PCLK1Config(uint32_t RCC_HCLK)
• RCC_HCLK_Div1: APB1 clock = HCLK
• RCC_HCLK_Div2: APB1 clock = HCLK/2
• RCC_HCLK_Div4: APB1 clock = HCLK/4
• RCC_HCLK_Div8: APB1 clock = HCLK/8
• RCC_HCLK_Div16: APB1 clock = HCLK/16
konfiguracja szybkich zegarów dla magistrali APB2 (PCLK2)
void RCC_PCLK2Config(uint32_t RCC_HCLK)
• RCC_HCLK_Div1: APB2 clock = HCLK
• RCC_HCLK_Div2: APB2 clock = HCLK/2
• RCC_HCLK_Div4: APB2 clock = HCLK/4
• RCC_HCLK_Div8: APB2 clock = HCLK/8
• RCC_HCLK_Div16: APB2 clock = HCLK/16
4
2. Konfiguracja portów wejścia/wyjścia
Konfigurację portów wejściowych bądź wyjściowych należy rozpocząć od włączenia
zegara dla poszczególnych portów, które mają być używane. Porty podłączone są do
magistrali AHB1, stąd należy skorzystać z funkcji:
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState
NewState)
gdzie:
RCC_AHB1Periph – określa port
NewState – stan ENABLE bądź DISABLE, włącza bądź wyłącza port
np. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE)
Kolejnym etapem jest powołanie oraz uzupełnienie struktury odpowiedzialnej za
konfigurację portu zdefiniowaną w pliku stm32f4xx_gpio.h:
typedef struct
{
uint32_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
GPIOOType_TypeDef GPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;
} GPIO_InitTypeDef;
Do inicjalizacji struktury można użyć funkcji:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
Zapis do portu 16 bitów:
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
np. GPIO_Write(GPIOA, 0xffff);
Zapis do pojedynczego wyprowadzenia mikrokontrolera:
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
np. GPIO_WriteBit(GPIOA, GPIO_Pin_1, 0);
bądź alternatywna funkcja ustawiająca wartość logiczną „1” na wyjściu:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
np. GPIO_SetBits(GPIOF, GPIO_Pin_6)
bądź kilka wyprowadzeń z portu:
GPIO_SetBits(GPIOF, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9)
bądź alternatywna funkcja ustawiająca wartość logiczną „0” na wyjściu:
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
np. GPIO_ResetBits(GPIOF, GPIO_Pin_6)
bądź kilka wyprowadzeń z portu:
np. GPIO_ResetBits(GPIOF, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9)
Można także bezpośrednio ustawiać wartości rejestrów ustawiającą wartość
wyprowadzeń w stan logiczny „1”:
np. GPIOA->BSRR = GPIO_Pin_10; // GPIOA.10 = 1
5
bądź ustawiającą wartość wyprowadzeń w stan logiczny „0”:
np. GPIOA->BRR = GPIO_Pin_10; // GPIOA.10 = 0
Odczyt ustawionej wartości portu wyjściowego:
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
np. readValue = GPIO_ReadOutputData(GPIOC);
Odczyt pojedynczego pinu portu wyjściowego:
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
np. readValue = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0)
Odczyt portu wejściowego, 16 bitów:
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
np. portVal = GPIO_ReadInputdata(GPIOA);
Odczyt stanu pojedynczego wyprowadzenia:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
np.
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) == 0)
{
…
}
6
3. Opis zestawu laboratoryjnego
Do portów płytki uruchomieniowej, podłączone są:
PA5 - zielona dioda LED, oznaczona jako LD2
PC13 – przycisk niebieski oznaczony jako USER
Złącze USB do
programowania i
diagnostyki
USER
LD2
Zdjęcie płytki uruchomieniowej z mikrokontrolerem STM32F411.
7