Strona 1 z 1

STM32F103 Timer 1 na rejestrach

: środa 16 lis 2016, 16:04
autor: StaryAnoda
Hej

Jak to zwykle ja, tym razem mam problem z Timerem1. Chciałbym go użyć to odliczania opóźnień mikro sekundowych. I w takiej konfiguracji opóźnienia mam na poziomie 20 mikro sekund.

TAKTOWANIE MAM USTAWIONE NA 8MHz z resztą sami zobaczcie:

Kod: Zaznacz cały

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
 #define SYSCLK_FREQ_HSE    HSE_VALUE
/* #define SYSCLK_FREQ_24MHz  24000000 */
#else
 #define SYSCLK_FREQ_HSE    HSE_VALUE
/* #define SYSCLK_FREQ_24MHz  24000000 */
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
/* #define SYSCLK_FREQ_72MHz  72000000 */
#endif


Kod main.c wygląda tak:

Kod: Zaznacz cały

#include "stm32f10x.h"

void delay(uint16_t time);

int main (void)
{

   RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_TIM1EN;

   TIM1 -> PSC = 8;
   TIM1 -> ARR = 65535;
   TIM1 -> CR1 = TIM_CR1_CEN;

   GPIOB -> CRL |= GPIO_CRL_MODE1_1;
   GPIOB -> CRL &= ~GPIO_CRL_CNF1_0;

   while(1)
   {
      GPIOB -> ODR |= GPIO_ODR_ODR1;
      delay(100);
      GPIOB -> ODR &= ~GPIO_ODR_ODR1;
      delay(100);
   }
}

void delay(uint16_t time)
{
   TIM1->CNT = 0;
   while (TIM1->CNT<=time);
}

Re: STM32F103 Timer 1 na rejestrach

: środa 16 lis 2016, 19:52
autor: ps19
Chcesz mieć 1 us ?

To policz sobie że z twoich 8*10^6 / (65535+1)*(8+1) wychodzi właśnie 20 us.

Re: STM32F103 Timer 1 na rejestrach

: środa 16 lis 2016, 20:14
autor: StaryAnoda
Podmieniłem taki sam efekt dalej 20 us zamiast 100

Kod: Zaznacz cały

#include "stm32f10x.h"

void delay(uint16_t time);

int main (void)
{

   RCC -> APB2ENR = RCC_APB2ENR_IOPBEN | RCC_APB2ENR_TIM1EN;

   TIM1 -> PSC = 999;
   TIM1 -> ARR = 7999;
   TIM1 -> CR1 = TIM_CR1_CEN;

   GPIOB -> CRL |= GPIO_CRL_MODE1_1;
   GPIOB -> CRL &= ~GPIO_CRL_CNF1_0;

   while(1)
   {
      GPIOB -> ODR |= GPIO_ODR_ODR1;
      delay(100);
      GPIOB -> ODR &= ~GPIO_ODR_ODR1;
      delay(100);
   }
}

void delay(uint16_t time)
{
   TIM1->CNT = 0;
   while (TIM1->CNT<=time);
}

Re: STM32F103 Timer 1 na rejestrach

: środa 16 lis 2016, 20:39
autor: ps19
Zrób to na przerwaniu (np. i++) i w funkcji delay sprawdzaj whilem czy time <= i jak wyjdzie z whila to i = 0 to powinno działać.

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 15:39
autor: StaryAnoda
Zrobiłem tak niestety efekt jest taki sam niepoprawne odmierzanie czasu

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 15:52
autor: ps19
Podrzuć cały projekt, bo nie wiem co masz namieszane w zegarach. Najlepiej w spakowany do zip`a.

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 15:58
autor: StaryAnoda
Załącznik

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 16:01
autor: ps19
Na czym robisz testy - Nucleo i jak tak to czy masz wlutowany kwarc + kondensatory ?

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 16:06
autor: StaryAnoda
Tak Nucleo F103, nic tam nie było modyfikowanie

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 16:12
autor: ps19
No właśnie, a odpalasz HSE czyli zewnętrzny kwarc, którego nie ma ;)
Nucleo posiada kwarc, ale jest on dla procka odpowiedzialnego za programator SWD, jak chcesz używać HSE to na samym dole musisz wlutować kwarc 8 Mhz oraz kondensatory 18 pF (chyba 0402). Jak chcesz osiągnąć wyższe częstotliwości z HSI to trzeba włączyć PLL. Wrzucałem Ci niedawno konfigurację HSI dla 64 Mhz (Jak chcesz 72 Mhz to kwarc) - gdzie wystarczy zmienić tylko 1/0 i ewentualnie częstotliwość w define.

Włącz HSI, czyli:

Kod: Zaznacz cały

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
 #define SYSCLK_FREQ_HSE    HSE_VALUE
/* #define SYSCLK_FREQ_24MHz  24000000 */
#else
/* #define SYSCLK_FREQ_HSE    HSI_VALUE  */
/* #define SYSCLK_FREQ_24MHz  24000000 */
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
/* #define SYSCLK_FREQ_72MHz  72000000 */
#endif

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 16:28
autor: StaryAnoda
Ok zrobiłem tak jak napisałeś problem ten sam mam wrażenie, że problemem jest init Timera

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 17:21
autor: ps19
To powinno zadziałać:

Kod: Zaznacz cały

#include "stm32f10x.h"

int timer;

__attribute__((interrupt)) void TIM4_IRQHandler(void)
{
   if (TIM4->SR & TIM_SR_UIF)
   {
      TIM4->SR = ~TIM_SR_UIF;
      timer++;
      if(timer >= 500) timer = 0;
   }
}

int main (void)
{
   RCC -> APB2ENR |= RCC_APB2ENR_IOPBEN;
   RCC -> APB1ENR |= RCC_APB1ENR_TIM4EN;

   TIM4 -> PSC = 8000;
   TIM4 -> ARR = 1000;
   TIM4 -> DIER = TIM_DIER_UIE;
   TIM4 -> CR1 = TIM_CR1_CEN;

   GPIOB -> CRL |= GPIO_CRL_MODE1_1;
   GPIOB -> CRL &= ~GPIO_CRL_CNF1_0;

   while(1)
   {
      if(timer >= 5)
      {
         GPIOB -> ODR ^= GPIO_ODR_ODR1;
         timer = 0;
      }
   }
}

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 17:44
autor: StaryAnoda
Ok dzięki dodając do zmiennej atrybut volatile i odblokowując przerwanie zadziałało dzięki

Re: STM32F103 Timer 1 na rejestrach

: czwartek 17 lis 2016, 18:17
autor: ps19
Tak zapomniałem o tym, ale dobrze że działa.