Acest curs explorează întreruperile și timerele, componente esențiale pentru controlul eficient al hardware-ului într-un sistem embedded.
O întrerupere este un semnal hardware sau software care întrerupe execuția normală a programului pentru a executa o rutină specifică (ISR - Interrupt Service Routine). Acest mecanism permite procesorului să reacționeze rapid la evenimente externe.
- Întreruperi hardware: Generate de periferice (ex: apăsarea unui buton, sosirea unui caracter pe UART).
- Întreruperi software: Declanșate de program (ex: întreruperi software pentru switching de task-uri într-un RTOS).
- Întreruperi mascabile și nemascabile: Unele întreruperi pot fi dezactivate (mascabile), altele sunt critice și nu pot fi oprite (ex: reset hardware).
Exemplu de întrerupere declanșată la apăsarea unui buton pe un microcontroler ARM Cortex-M:
void EXTI0_IRQHandler(void) {
if (EXTI->PR & (1 << 0)) { // Verifică dacă întreruperea pe pinul 0 este activă
// Cod executat la întrerupere
EXTI->PR |= (1 << 0); // Confirmă întreruperea
}
}
void init_interrupt_gpio(void) {
// Configurare GPIO ca intrare
// Activare întrerupere externă pe GPIO0
}
Timerele sunt module hardware care permit contorizarea timpului sau generarea de semnale periodice. Sunt esențiale pentru sarcini precum generarea PWM, măsurarea timpului sau declanșarea acțiunilor periodice.
- Timere pe 8/16/32 de biți: Diferența constă în precizia și domeniul de măsurare.
- Timere simple: Contorizează și declanșează o întrerupere la un anumit număr.
- Timere PWM (Pulse Width Modulation): Generare de semnale cu ciclu de funcționare variabil.
- Timere de watchdog: Resetează sistemul în caz de blocare.
Exemplu de configurare a unui timer pe un microcontroler STM32 pentru generarea unei întreruperi la fiecare 1ms:
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) { // Verificare flag update
TIM2->SR &= ~TIM_SR_UIF; // Resetare flag
// Cod executat la fiecare 1ms
}
}
void init_timer(void) {
// Configurare timer cu prescaler și frecvență de întrerupere
TIM2->PSC = 7999;
TIM2->ARR = 1000;
TIM2->DIER |= TIM_DIER_UIE;
TIM2->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM2_IRQn);
}
PWM (Pulse Width Modulation) este utilizat pentru controlul motoarelor, reglarea intensității LED-urilor și alte aplicații. Se obține variind ciclul de funcționare al unui semnal dreptunghiular.
void init_pwm(void) {
// Configurare Timer în mod PWM
TIM3->PSC = 7999;
TIM3->ARR = 1000;
TIM3->CCR1 = 500; // 50% duty cycle
TIM3->CCMR1 |= (6 << TIM_CCMR1_OC1M_Pos); // PWM Mode 1
TIM3->CCER |= TIM_CCER_CC1E;
TIM3->CR1 |= TIM_CR1_CEN;
}
Timerele pot fi utilizate pentru a genera întreruperi periodice, iar întreruperile pot fi folosite pentru a reacționa la evenimente în timp real. De exemplu, un timer poate declanșa o întrerupere pentru a citi un senzor la fiecare 10ms.