Witam,
już dobrych kilka godzin zastanawiam się, dlaczego timer 1 nie działa tak jak chcę. A chcę, poprzez poniżej przedstawione funkcje włączać żarówkę po odliczeniu przez timer na czas też odliczany przez timer.
Konfiguracja timera 1:
Funkcja włączająca dany kanał timera, i odliczająca daną wartość czasu
i funkcja wyłączająca dany kanał:
Obsługa przerwania
Pętla główna
Widzi ktoś jakiegoś buga? bo mi już mózg wybucha od RM0091.
Pozdrawiam
Dodano po 1 [godziny] 8 [minuty]:
Matko boska, już wiem. Wychodzi na to, że jak nie ustawiam wcześniej rejestrów CCRx, to on tam ma jakieś randomowe wartości i flaga przerwania tak czy siak jest ustawiana, tak więc od razu jak włączałem mu przerwania, to on od razu w nie wchodził. Dlatego miałem takie głupoty. Przepraszam za wstawienie śmieciowego tematu, ale może ktoś będzie miał kiedyś podobny problem i znajdzie tutaj odpowiedź. Funkcja włączająca kanał powinna wyglądać tak:
już dobrych kilka godzin zastanawiam się, dlaczego timer 1 nie działa tak jak chcę. A chcę, poprzez poniżej przedstawione funkcje włączać żarówkę po odliczeniu przez timer na czas też odliczany przez timer.
Konfiguracja timera 1:
void Tim1_config(void)
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
TIM1->CR1 |= TIM_CR1_ARPE;
TIM1->CR1 &= ~TIM_CR1_DIR;
TIM1->ARR = 65535;
TIM1->PSC = 48; // taktowanie mam 48MHz
TIM1->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_CC_IRQn);
}
Funkcja włączająca dany kanał timera, i odliczająca daną wartość czasu
void Tim1_canal_start(int us_1, int kanal)
{
long int tmp=0;
if(us_1>10000)
{
us_1=10000; //ograniczenie do 10ms
}
if (kanal==1)
{
TIM1->DIER |= TIM_DIER_CC1IE; // włączenie przerwania od 1 kanału trybu compare
tmp= TIM1->CNT;
if ((tmp+us_1)>65535)
{
TIM1->CCR1 = (tmp + us_1)%65535;
}
else
{
TIM1->CCR1 = tmp + us_1;
}
}
if (kanal==2)
{
TIM1->DIER |= TIM_DIER_CC2IE;
tmp= TIM1->CNT;
if ((tmp+us_1)>65535)
{
TIM1->CCR2 = (tmp + us_1)%65535;
}
else
{
TIM1->CCR2 = tmp + us_1;
}
}
if (kanal==3)
{
TIM1->DIER |= TIM_DIER_CC3IE;
tmp= TIM1->CNT;
if ((tmp+us_1)>65535)
{
TIM1->CCR3 = (tmp + us_1)%65535;
}
else
{
TIM1->CCR3 = tmp + us_1;
}
}
if (kanal==4)
{
TIM1->DIER |= TIM_DIER_CC4IE;
tmp= TIM1->CNT;
if ((tmp+us_1)>65535)
{
TIM1->CCR4 = (tmp + us_1)%65535;
}
TIM1->CCR4 = tmp + us_1;
}
}
i funkcja wyłączająca dany kanał:
void Tim1_canal_stop(int kanal)
{
if (kanal==1)
{
TIM1->DIER &= ~TIM_DIER_CC1IE;
}
if (kanal==2)
{
TIM1->DIER &= ~TIM_DIER_CC2IE;
}
if (kanal==3)
{
TIM1->DIER &= ~TIM_DIER_CC3IE;
}
if (kanal==4)
{
TIM1->DIER &= ~TIM_DIER_CC4IE;
}
}
Obsługa przerwania
void TIM1_CC_IRQHandler(void)
{
//Sprawdzamy który kanał
if(TIM1->SR&(TIM_SR_CC1IF))
{
TIM1->SR &= ~(TIM_SR_CC1IF);
Zarowka_on();
Tim1_canal_stop(1);
Tim1_canal_start(1000,2);
}
if(TIM1->SR&(TIM_SR_CC2IF))
{
Zarowka_off();
TIM1->SR &= ~(TIM_SR_CC2IF);
Tim1_canal_stop(2);
}
NVIC_ClearPendingIRQ(TIM1_CC_IRQn);
}
Pętla główna
while(1)
{
Tim1_canal_start(1000,1);
czekaj(1000000); // zwykły for tyle razy ile wprowadzimy do funkcji
}
Widzi ktoś jakiegoś buga? bo mi już mózg wybucha od RM0091.
Pozdrawiam
Dodano po 1 [godziny] 8 [minuty]:
Matko boska, już wiem. Wychodzi na to, że jak nie ustawiam wcześniej rejestrów CCRx, to on tam ma jakieś randomowe wartości i flaga przerwania tak czy siak jest ustawiana, tak więc od razu jak włączałem mu przerwania, to on od razu w nie wchodził. Dlatego miałem takie głupoty. Przepraszam za wstawienie śmieciowego tematu, ale może ktoś będzie miał kiedyś podobny problem i znajdzie tutaj odpowiedź. Funkcja włączająca kanał powinna wyglądać tak:
if (kanal==1)
{
TIM1->DIER |= TIM_DIER_CC1IE;
TIM1->SR &= ~(TIM_SR_CC1IF);
tmp= TIM1->CNT;
if ((tmp+us_1)>65535)
{
TIM1->CCR1 = (tmp + us_1)%65535;
}
else
{
TIM1->CCR1 = tmp + us_1;
}
}