Skocz do zawartości

Przekazywanie wartości z tablicy przez DMA do okresu timera STM32103RB


Pomocna odpowiedź

Napisano

Witam, borykam się z problemem związanym z przekazywaniem wartości przez DMA do rejestru związanego z periodem (ARR). Realizacja wygląda w taki sposób, że mam wcześniej wyliczone okresy dla timera w tablicy, która chce przekazywać lecz sposób wykonany przeze mnie nie działa. Poniżej wklejam kod programu. Za wszelką pomoc i porady z góry dziękuje

#include "stm32f10x.h"
#include "stm32f1xx_nucleo.h"
#include "stm32f10x.h"

int i =0;
u16 PWM_Buf[198];

void TIMInit(void);
void GPIOInit(void);
void DMAInit(void);
void PWMInit(void);

int main(void)
{
GPIOInit();
TIMInit();
DMAInit();
PWMInit();

for(i = 0;i<99;i++)
{
 PWM_Buf[i] = i+100;
}
for(i = 99;i>0;i--)
{
 PWM_Buf[i+98] = 100-i;
}

   while(1)
   {
   }
}
//Ustawienie Tim1
void TIMInit(void)
{
TIM_TimeBaseInitTypeDef TIMInit;

//Wlaczenie zegara dla timera 1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

//Okres
   TIMInit.TIM_Period = 1000;
   //Dzielnik sygnału taktującego
   TIMInit.TIM_Prescaler = 64000;

   TIMInit.TIM_ClockDivision = TIM_CKD_DIV1;
   TIMInit.TIM_CounterMode = TIM_CounterMode_Up;
   //Licznik powtórzen
   TIMInit.TIM_RepetitionCounter = 200;

   TIM_TimeBaseInit(TIM1, &TIMInit);
}

//Ustawienie portu I/O dla diody
void GPIOInit(void)
{
 GPIO_InitTypeDef GPIOInit;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

  GPIOInit.GPIO_Pin = GPIO_Pin_8;
  GPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIOInit.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIOInit);
}

//Konfiguracja DMA
void DMAInit(void)
{
//Adres rejestru TIM1 CCR1

DMA_InitTypeDef DMAInit;
//Wlaczenie zegara
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//Czyści wcześniejsze konfiguracje
DMA_DeInit(DMA1_Channel5);
//miejsce do którego dane zostaną skopiowane
DMAInit.DMA_PeripheralBaseAddr = (u32)&TIM1->ARR;
//Adres poczatku przesyłanych danych
DMAInit.DMA_MemoryBaseAddr = (u32)PWM_Buf;
//Kierunek przysyłania danych
DMAInit.DMA_DIR = DMA_DIR_PeripheralDST;
//Długośc bufora danych
DMAInit.DMA_BufferSize = 198;
//Wylaczenie automatycznego zwiększania adresów timera
DMAInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//Wlaczeni automatycznego zwiększania adresów po stronie pamięci
DMAInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
//Rozmiar przesyłanych danych po stronie pamięci
DMAInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
//rozmiar przesylanych danych po stronie bufora
DMAInit.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//Ciągły tryb pracy
DMAInit.DMA_Mode = DMA_Mode_Circular;
//Wysoki priorytet tego kanału
DMAInit.DMA_Priority = DMA_Priority_High;
//Wylaczona opcja transferu z pamięci do pamięci
DMAInit.DMA_M2M = DMA_M2M_Disable;

//Zapisanie konfiguracji
DMA_Init(DMA1_Channel5, &DMAInit);

//Wlaczenie kanału 5 DMA
   DMA_Cmd(DMA1_Channel5, ENABLE);
}

void PWMInit(void)
{
TIM_OCInitTypeDef  PWMInit;

//Tryb pracy kanału
   PWMInit.TIM_OCMode = TIM_OCMode_PWM1;
   PWMInit.TIM_OutputState = TIM_OutputState_Enable;
   //Czas trwania stanu wysokiego
   PWMInit.TIM_Pulse = 500;
   PWMInit.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OC1Init(TIM1, &PWMInit);

   //Wlączenie buforowania rejestrów lcznika
   TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
   //Zgłoszenie żądania DMA w momencie przepełnienia licznika
   TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
   //Wlaczenie Timera1
   TIM_Cmd(TIM1, ENABLE);
   //Wlączenie wyjścia PWM
   TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

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...