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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.