Skocz do zawartości

STM8S - Problem z ustawieniem taktowania timera


Chev

Pomocna odpowiedź

Dzień dobry,

Zmagam się z następującym problemem. Potrzebuję ustawić czas jednego bitu Timera4 w stm8s003f3 na 1 uS. Robiąc to w sposób standardowy, a mianowicie:

1. Ustawiając preskaler HSI oraz CPU na DIV = 1 (czyli korzystam z 16 MHz)

void clock_setup(void)
{
////////////////////////////// Configure Quartz Clock
    CLK_DeInit();
    CLK_LSICmd(ENABLE);
    CLK_HSICmd(ENABLE);
    //CLK_ClockSwitchCmd(ENABLE);
    
    CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
    CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
    
    CLK_PeripheralClockConfig (CLK_PERIPHERAL_TIMER2 , ENABLE);
    CLK_PeripheralClockConfig (CLK_PERIPHERAL_TIMER4 , ENABLE);

   // while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY) == FALSE);
//    CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
}

2. Inicjalizuję TIMER4: preskaler ustawiam na f/16, czyli wychodzi mi 1 MHz, co daje mi już 1 uS.

void TIMER4_setup(void)
{
  TIM4_DeInit();
  TIM4_TimeBaseInit(TIM4_PRESCALER_16, 0x01); // 1 uS
  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
  TIM4_Cmd(ENABLE);
}

3. Zezwalam na przerwania

void interrupt_setup(void)
{
  //EXTI_DeInit();
  //EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB, EXTI_SENSITIVITY_RISE_FALL);
  enableInterrupts();
}

4. W przerwaniu Timera4 zeruję flagę przepełnienia:

TIM4_ClearITPendingBit(TIM4_IT_UPDATE);

 

Efekty jakie doświadczam to resetowanie się układu przez wewnętrznego IWDG, a po jego wyłączeniu zakleszczenie się w jakimś miejscu. Po chwili debugowania okazuje się, że po wzięciu w komentarz enableInterrupts(); lub inicjalizacji timera4 wszystko działa elegancko. Co lepsze, po ustawieniu wartości zliczającej przez timer4 z 0x01 na 0x05 wszystko zaczyna działać prawidłowo. 

W czym leży problem? Niezależnie jaki Timer użyję (1/2/4) to zawsze jest taki sam problem. Bardzo proszę o sugestię, co tu może być nie tak, bo szczerze ja zgłupiałem.

Link do komentarza
Share on other sites

@Chev spróbowałem u siebie ustawić przerwania na stm8L w  ten sposób:


//Clock source/prescaler default HSI div/8 = 2MHz
//Enable clock to periphrals
CLK_PCKENR2 |= 1<<PCKENR2_TIM1;
//Counter clock frequency 1ms CK_CNT = CK_PSC/(PSCR + 1)
TIM1_PSCRH = 0x07;
TIM1_PSCRL = 0xCF;
//Enable TIM1
TIM1_CR1 = 1<<CEN;
// Enable tim1 update interrupts
TIM1_IER = 1<<UIE;
// tim1_ARR = 6000 1ms*6000=6s
TIM1_ARRH=0x17;
TIM1_ARRL=0x70;
//enable interrupts
rim();

W przerwaniu kasuje flagę przepełnienia UIF=0. Działa poprawnie.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.