Timer zliczający zbocza z pinu – dioda się nie zapala

0

Witam. Mam problem z timer 1 na płytce STM32F411VET6 . Chciałem aby timer zliczał mi zbocza z pinu. Problem polega na tym, że tego nie robi, bo dioda się nie zapala.
Czy ktoś mógłby mi pomóc?
Poniżej kod programu:

#include "stm32f4xx.h"


int main (void){
//--------------- BUS --------------------------------------------------
	
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOAEN;
	RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;

//--------------- TIM1 -------------------------------------------------

	TIM1->SMCR |= TIM_SMCR_SMS_0 |
			      TIM_SMCR_SMS_1 |
				  TIM_SMCR_SMS_2 ;
	TIM1->SMCR |= TIM_SMCR_TS_0 |
				  TIM_SMCR_TS_2 ;
	TIM1->CCER |= TIM_CCER_CC1P;
	TIM1->CR1  |= TIM_CR1_CEN;
	TIM1->ARR = 10;
	TIM1->DIER = TIM_DIER_UIE;

//--------------- LED --------------------------------------------------
	GPIOD->MODER |= GPIO_MODER_MODE15_0 | GPIO_MODER_MODE14_0;
	GPIOD->OTYPER &= ~GPIO_OTYPER_OT15 | GPIO_OTYPER_OT14;
	GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED15_0 | GPIO_OSPEEDR_OSPEED14_0;
	GPIOD->PUPDR |= GPIO_PUPDR_PUPDR15_0 | GPIO_PUPDR_PUPDR14_0;

//----------------- TIM1_CH1 source ------------------------------------

	GPIOA->MODER |= GPIO_MODER_MODE8_1;
	GPIOA->OTYPER &= ~GPIO_OTYPER_OT8;
	GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8_0;
	GPIOA->PUPDR |= GPIO_PUPDR_PUPDR8_1;
	GPIOA->AFR[1] |= GPIO_AFRH_AFRH0_1;

//---------------- NVIC -----------------------------------------------

	NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);


	SysTick_Config(8000000);
	while(1);

}
__attribute__((interrupt)) void SysTick_Handler(void){
	GPIOA->ODR ^= GPIO_ODR_OD8;
	GPIOD->ODR ^= GPIO_ODR_OD15;

}
__attribute__((interrupt)) void TIM1_UP_TIM10_IRQHandler(void){
		if(TIM1->SR & TIM_SR_UIF){
			TIM1->SR = ~TIM_SR_UIF;
			GPIOD->ODR ^= GPIO_ODR_OD14;
		}
	}

0

Jest ktoś w stanie mi pomóc?

1

1. Sprawdzałeś, czy następuje wejście do przerwania?
2. Jeśli następuje to upewnij się, że ustawiłeś pin i szynę zgodnie z dokumentacją (STM'y cechują się rozbudowaną erratą).
3. Jeśli nie wchodzi do żadnego przerwania to sprawdź ustawienia zegara, może problem jest w częstotliwości pod jaką chcesz działać a działasz na innej?

1

UEV przypadkiem nie musisz też załączyć? Piszę z pamięci, ale to nie jest tak, że update interrupt jest opcjonalną reakcją na update event?

0
alagner napisał(a):

UEV przypadkiem nie musisz też załączyć? Piszę z pamięci, ale to nie jest tak, że update interrupt jest opcjonalną reakcją na update event?

UEV jest włączony przez:

TIM1->DIER = TIM_DIER_UIE;
Bartosz36 napisał(a):

1. Sprawdzałeś, czy następuje wejście do przerwania?
2. Jeśli następuje to upewnij się, że ustawiłeś pin i szynę zgodnie z dokumentacją (STM'y cechują się rozbudowaną erratą).
3. Jeśli nie wchodzi do żadnego przerwania to sprawdź ustawienia zegara, może problem jest w częstotliwości pod jaką chcesz działać a działasz na innej?

  1. Zaraz sprawdzę.
  2. Pin i szyna na pewno są dobrze ustawione.
  3. Nie rozumiem pytania.
1

UEV to nie UIE, chyba, że RM jasno podaje, że to jeżeli masz UIE to nie potrzebujesz UEV, ale szukając na szybko tego nie zauważyłem.

EDIT tu w oparciu o StdPeriph co prawda, ale na rejestrach będzie analogicznie. Zwróć uwagę, że włączają update event niezależnie od przerwania. https://visualgdb.com/tutorials/arm/stm32/timers/

0

Wcześniej zliczałem update event TIM1, które były do niego wysyłane za pomocą TIM2 i w obu wszystko działało razem z przerwaniami od eventów i miganiem LEDów. Teraz kompletnie nie wiem co jest nie tak. RM czytałem już wielokrotnie i nie byłem w stanie nic znaleźć.

1

Ale w sensie że włączenie UEV Ci teraz pomogło? Bo bodajże w SMCR jest bit o nazwie UEV. Przerwanie != zdarzenie.

0

Nie. Miałem na myśli, że używałem:

TIM1->DIER = TIM_DIER_UIE;

Tak jak było opisane w RM: Using one timer as prescaler for another timer.

2

Podpowiedź: timer stoi. Sprawdzałem jtagiem, TIM1->CNT jest ciągle równe 0. Nie masz czegoś pomieszanego w portach?
Na dzień dobry bym ten input timer'a zwarł z diodą sterowaną z systick'a zamiast machać nim osobno przez ODR.

0
alagner napisał(a):

Podpowiedź: timer stoi. Sprawdzałem jtagiem, TIM1->CNT jest ciągle równe 0. Nie masz czegoś pomieszanego w portach?
Na dzień dobry bym ten input timer'a zwarł z diodą sterowaną z systick'a zamiast machać nim osobno przez ODR.

Zwarłem i nic to nie zmieniło oprócz tego, że dioda od SysTicka nie miga. Porty powinny być ok bo sprawdzałem w Datasheet'cie i TIMx_CH1(tu TIM1) jest połączony z portem PA8.
Na schemacie blokowym licznika syngał wchodzi właśnie przez TIM1_CH1, potem detektor zbocza i jest sygnał TI1FP1, który jest ok bo napisałem

TIM1->SMCR |= TIM_SMCR_TS_0 | TIM_SMCR_TS_2;

Tak jak jest napisane w RM.

Jak sprawdzić wartość rejestru?

0

Dobra. Problem rozwiązany..
Napisałem

GPIOA->AFR[1] |= GPIO_AFRH_AFRH0_1

a powinno być:

GPIOA->AFR[1] |= GPIO_AFRH_AFRH0_0

Muszę powiedzieć, że się zdenerwowałem, ale chociaż teraz mogę zająć się kolejnymi rzeczami.

1

Literówka, która się kompiluje ale powoduje buga...najgorzej ;) Też takich często szukałem po pół dnia :P
Co do podglądu rejestru... możliwości masz kilka.
Opcja
a. konfigurujesz uart i rejestr sobie wysyłasz po stosownej przejściówce. Mając debugger to może się zdawać prymitywne, ale często w pracy się go jednak nie ma i trzeba bazować tylko na logach
b. przekierować stdout do konsoli debuggera. Z tym może być trochę zabawy, zależnie jak masz ustawione kompilator i linker, czy masz zaimplementowane syscallsy itd. Tym niemniej warto wiedzieć, że da się to zrobić. Google: RDI monitor, semihosting.
c. wersja hardkor: wpisujesz w gdb p *((uint32_t*) 0x4001000 + 0x24) gdzie pierwsze to peripheral base wyjęte z datasheetowego memory map, drugie to register offset.
d. instalujesz plugin do Eclipse'a EmbSysRegView i masz graficzny podgląd z klikalnymi poszczególnymi bitami.

I pamiętaj, jeżeli odczyt rejestru wywołuje jakiś skutek uboczny (np. odczyt bufora UARTu może zgłosić przerwanie "read done" albo spowodować wyzerowanie bufora), to generalnie czego byś nie zrobił, ten efekt nastąpi. Przy zerowanych buforach efekt jest podwójnie paskudny, bo może się okazać, że debuger pokaże od razu jego wartość "pustą".

EDIT: nie wiem jakiego używasz środowiska. Wcześniej pisałem Eclipse, bo zawsze używałem tego w zestawie z GCC, jedynie wczoraj rzeźbiłem wg opcji C bo nie mam na tym kompie niczego postawionego, a konfiguracja nieco trwa. A jest to o tyle ważne, że nie wiem jak zachowa się opcja b. w przypadku Keila np.

0

Ok. Sprawdzę sobie semihosting i ten plugin do Eclipse, bo akurat tego środowiska używam.
Dzięki za pomoc. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1