Easyelectronics.ru

Электроника для всех
Текущее время: 26 ноя 2020, 21:19

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: STM32F4xx DMA1 Stream 6 channel 3
СообщениеДобавлено: 16 окт 2012, 10:20 
Здравствуйте!

Зарегистрирован: 16 окт 2012, 10:10
Сообщения: 4
Для одного из проектов протребовалось использовать DMA вместе с таймером 2.

Алгоритм работы следующий: По событию совпадения с регистром сравнения 2 происходит запуск DMA1_Stream6. DMA пересылает 640 байт переконфигурируется.

Однако всегда происходит ошибка передачи DMA, пробовал вычленять и запускать только эту часть кода - аналогичный результат, также попробовал камни разных ревизий и серий - f407 rev A, Z; f417 rev A.

Исходный код тестовой программы приведён внизу, также приложен архив с проектом (Coocox, GNU GCC).
Код:
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_dma.h"
#include "misc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"

char Buffer[640];

int main(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
   DMA_InitTypeDef DMA_InitStructure;
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   TIM_OCInitTypeDef         TIM_OCInitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;

   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_All;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_Init(GPIOD, &GPIO_InitStructure);

   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
   TIM_TimeBaseStructure.TIM_Period = 1000;
   TIM_TimeBaseStructure.TIM_Prescaler = 160;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OCInitStructure.TIM_Pulse = 500;
   TIM_OC1Init(TIM2, &TIM_OCInitStructure);

   TIM_DMACmd(TIM2, TIM_DMA_CC2, ENABLE);

   DMA_Cmd(DMA1_Stream6, DISABLE);
   DMA_DeInit(DMA1_Stream6);
   DMA_StructInit(&DMA_InitStructure);
   DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(GPIOD->ODR);
   DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned int)&Buffer;
   DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
   DMA_InitStructure.DMA_BufferSize = 640;
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
   DMA_InitStructure.DMA_Channel = DMA_Channel_3;

   DMA_Init(DMA1_Stream6, &DMA_InitStructure);
   DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_TE, ENABLE);
   DMA_Cmd(DMA1_Stream6, ENABLE);

   TIM_Cmd(TIM2, ENABLE);

   GPIO_SetBits(GPIOD, GPIO_Pin_All);
   GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14);

    while(1)
    {
       GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14);
    }
}

void DMA1_Stream6_IRQHandler(void) {
   TIM2->CR1 &= ~TIM_CR1_CEN;
   if (DMA1->HISR & DMA_HISR_TEIF6)
      GPIO_SetBits(GPIOD, GPIO_Pin_14);
   if (DMA1->HISR & DMA_HISR_TCIF6) {
      GPIO_SetBits(GPIOD, GPIO_Pin_12);
      DMA1_Stream6->M0AR = (unsigned int)&Buffer;
      DMA1_Stream6->CR |= DMA_SxCR_EN;
   }
   DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TC | DMA_IT_TE);
   TIM2->CR1 |= TIM_CR1_CEN;
}


Вложения:
Комментарий к файлу: Тестовый проект
f407-dma.7z [163.34 Кб]
Скачиваний: 151
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F4xx DMA1 Stream 6 channel 3
СообщениеДобавлено: 16 окт 2012, 11:38 
Здравствуйте!

Зарегистрирован: 16 окт 2012, 10:10
Сообщения: 4
Вот этот же пример кода (отличается только таймером и дма) Абсолютно рабочий:
Код:
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_dma.h"
#include "misc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"

char Buffer[640];

int main(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
   DMA_InitTypeDef DMA_InitStructure;
   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
   TIM_OCInitTypeDef         TIM_OCInitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;

   NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_All;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_Init(GPIOD, &GPIO_InitStructure);

   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
   TIM_TimeBaseStructure.TIM_Period = 1000;
   TIM_TimeBaseStructure.TIM_Prescaler = 1600;
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
   TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OCInitStructure.TIM_Pulse = 500;
   TIM_OC1Init(TIM1, &TIM_OCInitStructure);

   TIM_DMACmd(TIM1, TIM_DMA_CC2, ENABLE);

   DMA_Cmd(DMA2_Stream2, DISABLE);
   DMA1->LIFCR |= DMA_LIFCR_CDMEIF2 | DMA_LIFCR_CFEIF2 |
         DMA_LIFCR_CHTIF2 | DMA_LIFCR_CTCIF2 | DMA_LIFCR_CTEIF2;
   DMA_DeInit(DMA2_Stream2);
   DMA_StructInit(&DMA_InitStructure);
   DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(GPIOD->ODR);
   DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned int)&Buffer;
   DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
   DMA_InitStructure.DMA_BufferSize = 640;
   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
   DMA_InitStructure.DMA_Channel = DMA_Channel_6;

   DMA_Init(DMA2_Stream2, &DMA_InitStructure);
   DMA_ITConfig(DMA2_Stream2, DMA_IT_TC | DMA_IT_TE, ENABLE);
   DMA_Cmd(DMA2_Stream2, ENABLE);

   TIM_Cmd(TIM1, ENABLE);

   GPIO_SetBits(GPIOD, GPIO_Pin_All);
   GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14);

    while(1)
    {
       GPIO_ResetBits(GPIOD, GPIO_Pin_12 | GPIO_Pin_14);
    }
}

void DMA2_Stream2_IRQHandler(void) {
   TIM1->CR1 &= ~TIM_CR1_CEN;
   if (DMA2->LISR & DMA_LISR_TEIF2)
      GPIO_SetBits(GPIOD, GPIO_Pin_14);
   if (DMA2->LISR & DMA_LISR_TCIF2) {
      GPIO_SetBits(GPIOD, GPIO_Pin_12);
      DMA2_Stream2->M0AR = (unsigned int)&Buffer;
      DMA2_Stream2->CR |= DMA_SxCR_EN;
   }
   DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TC | DMA_IT_TE);
   TIM1->CR1 |= TIM_CR1_CEN;
}

void assert_param(unsigned int error) {
   ;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F4xx DMA1 Stream 6 channel 3
СообщениеДобавлено: 16 окт 2012, 23:08 
Заглядывает иногда

Зарегистрирован: 08 май 2012, 21:18
Сообщения: 184
Откуда: Омск
Разобрался: у DMA1 нету доступа к AHB1, где у нас и сидит GPIO.

_________________
Прежде чем спорить подумай о том что воевать можно бесконечно, а вот мир бывает крайне коротким и редким. Мой сайт про stm32 и не только - www.nis-embedded.blogspot.com


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB