LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

Obsługa programowanego detektora napięcia PVD

PVD (Programmable Voltage Detector) jest wewnętrznym blokiem sprzętowym w mikrokontrloerach STM32 mającym za zadanie monitorowanie wartości napięcia zasilania. Progi, po których przekroczeniu generowane będzie przerwanie, mogą być programowane przez użytkownika w szerokich granicach.

Komparator analogowy zastosowany w PVD ma histerezę równą 100 mV. Programowany detektor poziomu napięcia jest wewnętrznie połączony z przerwaniem EXTI16, które może być generowane w chwili, gdy napięcie będzie mniejsze, większe lub różne od podanej wartości.

 

Rys. 1. Przykładowy sposób zaprogramowania PVD

Rys. 1. Przykładowy sposób zaprogramowania PVD

Na rys. 1 przedstawiono sytuację, w której układ PVD został skonfigurowany do generowania przy napięciu różnym od podanej wartości. Za dobre napięcie zasilania w tym przykładzie jest uznawane napięcie o wartości powyżej 3 V, natomiast próg PVD został ustalony na 2,8 V. Na rysunku pokazano również, w jaki sposób działa 100 mV histereza. Czarne punkty wskazują miejsca wygenerowania przerwania.
Napięcie progu wyzwalania może być programowane w granicach od 2,2 V do 2,9 V, z krokiem co 0,1 V. Tak szeroki zakres pozwala na dobór parametru stosownie do wymagań aplikacji. Napięcie ustala się wywołując funkcję PWR_PVDLevelConfig() z odpowiednim parametrem. Przykładowo, jeśli projektowane urządzenie wymaga generowania przerwania po przekroczeniu napięcia 2,8 V, to należy w programie umieścić linijkę:

PWR_PVDLevelConfig(PWR_PVDLevel_2V8);

Oczywiście nie należy zapominać o wcześniejszym włączeniu programowanego detektora poziomu napięcia wywołując funkcję PWR_PVDCmd() z argumentem ENABLE.
Układ monitorujący może zwracać wartość napięcia zasilającego, jednak tego typu funkcja nie została zaimplementowana w bibliotekach firmy STMicroelectronics i do tego celu należ napisać własną, której przykład przedstawiono na list. 1.

List. 1. Przykładowa funkcja zwracająca wartość napięcia zasilającego

u8 PWR_PVDGetLevel(void) 
{ 
  u8 temp_val = 0; 
  temp_val = (u8) ((PWR->CR >> 5) & 0x07); 
  return temp_val; 
} 

Nieco zawiłe działanie na wartości wpisywanej do zmiennej temp_val jest podyktowane pozycją bitów PLS2:0 ustawiających próg napięcia w rejestrze kontrolnym PWR_CR (rys. 2). Zajmują one pozycje 5…7, dlatego należy wykonać operację pięciokrotnego przesunięcia bitowego w prawo. Następnie w tym przykładzie zerowane są wszystkie bity oprócz trzech najmłodszych a wynik rzutowany na 8–bitowy typ bez znaku.

 

Rys. 2. Lokalizacja bitów PLS2...0 w rejestrze PWR_CR

Rys. 2. Lokalizacja bitów PLS2…0 w rejestrze PWR_CR

Funkcję wykorzystano w przykładzie programu zmieniającym stan wyprowadzeń zależnie od wartości napięcia. Został on podzielony na dwie części: program główny i funkcję obsługi przerwania od PVD. Zadaniem pierwszej jest wstępna konfiguracja PVD i jego przerwania. Stosowny fragment programu przedstawiono na list. 2.

List. 2. Wstępna konfiguracja PVD i jego przerwania

int main(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
  
    RCC_Conf();    
    NVIC_Conf();
    GPIO_Conf();
    // Wybranie grupy priorytetów
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
    // Konfiguracja i wlaczenie przerwania
    NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
  
    // Bedzie generowane przerwanie na zboczu opadajacym na EXTI_Line16
    EXTI_InitStructure.EXTI_Line = EXTI_Line16;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
   
    while(1);
}

W pierwszej kolejności konfigurowany jest NVIC tak, aby był przygotowany na przyjęcie i obsługę przerwania z kanału 16. Następnie ustawiane są parametry samego przerwania. Tutaj ważny jest wybór zbocza, przy którym będzie ono generowane. Przedstawiony przykład działa w oparciu o reakcję na zejście napięcia zasilającego poniżej danego progu. W związku z tym przerwanie musi być generowane na zboczu opadającym. Po wykonaniu czynności konfiguracyjnych, mikrokontroler przechodzi do nieskończonej pętli while() i oczekuje na nadejście przerwania od programowanego detektora poziomu napięcia.

List. 3. Funkcja obsługi przerwania od PVD

void PVD_IRQHandler(void)
{
     if(EXTI_GetITStatus(EXTI_Line16) != RESET)
     {
        u8 level = 0;
        level = PWR_PVDGetLevel();     // Odczytanie, ktory 
                                // prog zostal przekroczony

        switch level
        {
            case 1:        // poziom 2,2V
                GPIO_SetBits(GPIOB, GPIO_Pin_15);
              break;
            case 2:        // poziom 2,3V
                PWR_PVDLevelConfig(PWR_PVDLevel_2V2);
                GPIO_SetBits(GPIOB, GPIO_Pin_14);                
              break;
            case 3:        // poziom 2,4V
                PWR_PVDLevelConfig(PWR_PVDLevel_2V3);
                GPIO_SetBits(GPIOB, GPIO_Pin_13);
              break;
            case 4:        // poziom 2,5V
                PWR_PVDLevelConfig(PWR_PVDLevel_2V4);
                GPIO_SetBits(GPIOB, GPIO_Pin_12);
              break;            
            case 5:         // poziom 2,6V
                
                PWR_PVDLevelConfig(PWR_PVDLevel_2V5);                
                GPIO_SetBits(GPIOB, GPIO_Pin_11);            
              break;            
            case 6:   // poziom 2,7V                  
                PWR_PVDLevelConfig(PWR_PVDLevel_2V6);                
                GPIO_SetBits(GPIOB, GPIO_Pin_10);            
              break;            
            case 7:   // poziom 2,8V                
                PWR_PVDLevelConfig(PWR_PVDLevel_2V7);                
                GPIO_SetBits(GPIOB, GPIO_Pin_9);            
              break;            
            case 8:   // poziom 2,9V                
                PWR_PVDLevelConfig(PWR_PVDLevel_2V8);                
                GPIO_SetBits(GPIOB, GPIO_Pin_8);            
              break;
        }        
        // Wyczysc flage przerwania
        
        EXTI_ClearITPendingBit(EXTI_Line16);
   }
}

Drugim blokiem prezentowanej aplikacji jest funkcja obsługi przerwania od PVD – PVD_IRQHandler(). Pokazano ją na list. 3. Wykonuje ona sprawdzenie źródła przerwania oraz za pomocą wcześniej opisywanej funkcji, odczytuje wartość napięcia. W tym przykładzie, po przekroczeniu każdego z progów ustalany jest stan wysoki kolejnego wyprowadzenia mikrokontrolera i ustawiany kolejny próg napięcia.

Pewne wątpliwości może budzić sposób realizacji tego przykładu na płytce ewaluacyjnej STM3210B – EVAL/A, która ma już wmontowany na stałe stabilizator napięcia 3,3 V. Można to w łatwy sposób obejść. Wystarczy po zaprogramowaniu mikrokontrolera odłączyć źródło napięcia zasilania i wpiąć się z zewnętrznym napięciem o wartości około 3 V na wyjście stabilizatora 3,3 V zyskując w ten sposób możliwość jego regulacji. W trakcie zmniejszania napięcia zasilania na kolejnych wyprowadzeniach portu GPIOB, od PB8 zaczynając, będą pojawiać się stany wysokie.