Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.94/34: Рейтинг темы: голосов - 34, средняя оценка - 4.94
bikymmir
0 / 0 / 0
Регистрация: 15.08.2013
Сообщений: 11
1

Прошу помощи с DMA на STM32F4 DISCOVERY [РЕШЕНО]

13.03.2015, 10:44. Просмотров 6442. Ответов 10
Метки нет (Все метки)

Пытаюсь разобраться с DMA + TIM, не понимаю, почему DMA не запускается. Основной смысл программы - через каждые пол секунды (отсчитывает TIM5), генерируется Update event, который запускает DMA, зажигающий светодиоды на плате.
Код
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"

#define Led_Left   GPIO_Pin_12
#define Led_Up      GPIO_Pin_13
#define Led_Right   GPIO_Pin_14
#define Led_Down   GPIO_Pin_15

//**********************************VARIABLES**********************************
uint32_t GO[] = {Led_Left, Led_Up, Led_Right, Led_Down};
int main()
{

//**********************************Initiotyze GPIO**********************************
RCC->AHB1ENR |=   RCC_AHB1ENR_GPIODIM;   //Включаем тактирование порта D
GPIOD->MODER |= GPIO_MODER_MODER12_0|   //Настройка выводов (светодиодов)
GPIO_MODER_MODER13_0|   //как выход
GPIO_MODER_MODER14_0|
GPIO_MODER_MODER15_0;

//**********************************Initiotyze TIM5**********************************
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;      //Включаем тактирование

TIM5->PSC =    16000 - 1;      //Частота счёта - 1кГц
TIM5->ARR =    500 - 1;      //UEV с частотой 2Гц(16000м/(16000*500))
TIM5->EGR |=   TIM_EGR_UG;      //Обновляем значения таймера

TIM5->DIER |=   TIM_DIER_UDE;   //Запрос DMA от UEV счётчика
TIM5->CR2 |=   TIM_CR2_MMS_1;   //UEV = TRGO

TIM5->CR1 |=   TIM_CR1_CEN;   //Включаем таймер

//**********************************Initiotyze DMA1**********************************
RCC->AHB1ENR |=      RCC_AHB1ENR_DMA1EN;   //Включаемтактирование

DMA1_Stream1->CR|=   DMA_SxCR_CHSEL_2|   //Адрес канала 6
DMA_SxCR_CHSEL_1|
DMA_SxCR_MSIZE_1|   //**Передача данных
DMA_SxCR_PSIZE_1|   //**16 бит -> 16 бит
DMA_SxCR_MINC|      //Инкремент адреса памяти
DMA_SxCR_DIR_0;      //направление: память->периферия

DMA1_Stream1->CR&=  ~DMA_SxCR_PINC;      //Не инкремент переферии

DMA1_Stream1->NDTR =   4;            //количество передающих данных

DMA1_Stream1->POR =(uint32_t) &GPIOD->ODR;//адрес переферии
DMA1_Stream1->M0AR = (uint32_t)&GO[0];      //адресс начальной памяти

DMA1_Stream1->CR|=   DMA_SxCR_EN;      //Включаем DMA;

while(1)
{

}
}
Прошу помочь определиться где ошибка.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.03.2015, 10:44
Ответы с готовыми решениями:

Таймер, ADC и DMA на STM32F4 (Discovery)
Привет всем. Надо запускать ADC1 по таймеру. По мотивам доки и форумов написал следующее -...

[решено]usart на stm32f4-discovery
портирую rtems на сабжевую платку. накидал драйвер pottyng усарта, консолька работает, prymtf в...

Любая прошивка для USB на STM32F4-discovery [Решено]
Ковыряюсь с USB на STM32. На ум приходит анекдот (ну это завсегда так): Заходит человек в...

Вопрос о сенсорных кнопках для STM32F4-Discovery [Решено]
Возникла акая задача, для контроллера STM32F4-Dyscovery не имеющего на борту снсорных кнопок, их...

Неисправность платы F4 Discovery, прошу помощи
Добрый день! В общем, сам не понял что произошло, но платка перестала работать. Выражается это в...

10
Riotmir
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 105
13.03.2015, 13:25 2
Добрый день.

Я, конечно, сам начинающий, но без открытия даташита вижу следующее:

1. вместо пачки инклудов нужен только один, от контроллера, который у Вас на плате (лежит в Dryvers/CMSIS/Device/ST/Include/ )
2. когда заработает, включит оно только один светодиод (LED_DOWN) и только один раз т.к. пишет в ODR, а не BSRR и следующее значение будет вытирать предыдущее.
3. при втором срабатывании DMA начнёт гнать значения из следующей области (указатель на память не восстанавливается после срабатывания)

Заглянув в даташит

1. Вы пытаетесь сработать от update_event, а это канал 6 стрим 0 или 6 а не стрим 1.

ЗЫ: Сам пробовал давно и уже забыл.
0
bikymmir
0 / 0 / 0
Регистрация: 15.08.2013
Сообщений: 11
13.03.2015, 23:12 3
Цитата Сообщение от Riotmyr
Добрый день.

Я, конечно, сам начинающий, но без открытия даташита вижу следующее:

1. вместо пачки инклудов нужен только один, от контроллера, который у Вас на плате (лежит в Dryvers/CMSIS/Device/ST/Include/ )
2. когда заработает, включит оно только один светодиод (LED_DOWN) и только один раз т.к. пишет в ODR, а не BSRR и следующее значение будет вытирать предыдущее.
3. при втором срабатывании DMA начнёт гнать значения из следующей области (указатель на память не восстанавливается после срабатывания)

Заглянув в даташит

1. Вы пытаетесь сработать от update_event, а это канал 6 стрим 0 или 6 а не стрим 1.

ЗЫ: Сам пробовал давно и уже забыл.
Трудности перевода, понял 2 и 3, спасибо за пояснения.

А при замене на Stream0 и Stream6 DMA не запускается всё равно.
0
TomityWotf
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 553
14.03.2015, 05:19 4
Код
TIM5->DIER |=   TIM_DIER_UDE;   //Запрос DMA от UEV счётчика
А не TDE бит надо здесь включать?
0
14.03.2015, 05:19
bikymmir
0 / 0 / 0
Регистрация: 15.08.2013
Сообщений: 11
14.03.2015, 12:20 5
Цитата Сообщение от TomityWotf
Код:
TIM5->DIER |= TIM_DIER_UDE; //Запрос DMA от UEV счётчика
А не TDE бит надо здесь включать?

Если нужно запускать DMA от триггера таймера, то этот. Мне же нужно запускать его от переполнения - Update Ivimt.
0
Riotmir
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 105
14.03.2015, 17:49 6
Попробовал на NUCTIO 401RE. DMA срабатывает, но вываливается с TEIF. Любопытно...
Код
Код
#include "stm32f401xe.h"

volatile uint16_t data = 0xffff;

void SystemInit(void) {
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_DMA1EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;

GPIOA->MODER |= GPIO_MODER_MODER5_0;

TIM5->PSC = 16000 - 1;
TIM5->ARR = 1000 - 1;

TIM5->DIER |= TIM_DIER_UDE;
TIM5->CR1 |= TIM_CR1_CEN;

DMA1_Stream6->CR = DMA_SxCR_DIR_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2
| DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0;
DMA1_Stream6->NDTR = 1;
DMA1_Stream6->M0AR = (uint32_t) &recv;
DMA1_Stream6->POR = (uint32_t) &GPIOA->ODR;
DMA1_Stream6->CR |= DMA_SxCR_EN;
}

int main(void) {
while (1) {
if (DMA1->HISR & DMA_HISR_TEIF6)
GPIOA->BSRR = GPIO_BSRR_BS_5;
__NOP();
}
}
0
Riotmir
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 105
14.03.2015, 22:53 7
Чегой-то покурил я мануал ещё раз и закралось у меня сомнение, что dma1 может в gpio писать. У него доступа к ahb1 нет.
Проверил идею, при замене GPIOA->ODR на USORT2->DR всё жизнерадостно запахало.... похоже не судьба.
0
Riotmir
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 105
16.03.2015, 10:48 8
Подтверждения или альтернативных идей/мнений/результатов так и не появилось? Мне же тоже любопытно, так это или нет. :)
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
16.03.2015, 17:40 9
Не ты первый. DMA2 спасет ...
0
Riotmir
0 / 0 / 0
Регистрация: 25.12.2014
Сообщений: 105
16.03.2015, 19:18 10
Спасибо. Значит я правильно понял RM :)
0
bikymmir
0 / 0 / 0
Регистрация: 15.08.2013
Сообщений: 11
16.03.2015, 20:51 11
Цитата Сообщение от Riotmyr
Чегой-то покурил я мануал ещё раз и закралось у меня сомнение, что dma1 может в gpio писать. У него доступа к ahb1 нет.
Проверил идею, при замене GPIOA->ODR на USORT2->DR всё жизнерадостно запахало.... похоже не судьба.
Всем спасибо за внимание - и действительно, DMA1 не имеет доступа к AHB1... Страница 217 (RM0090).
В данном случае нужно использовать DMA2.
Оставлю рабочий код здесь... Программа по-очереди зажигает светодиоды на плате
Код
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"

#include "delay.h"
#include "lcd_1604.h"

//**********************************************
//****************Defymition of LED*************
//**********************************************

#define LED_Port      GPIOD               //Leds port
#define Led_Left      GPIO_Pin_12
#define Led_Up         GPIO_Pin_13
#define Led_Right      GPIO_Pin_14
#define Led_Down      GPIO_Pin_15

#define Led_Port_Out   RCC_AHB1ENR_GPIODIM

#define Led_Left_MODER   GPIO_MODER_MODER12_0
#define Led_Up_MODER   GPIO_MODER_MODER13_0
#define Led_Right_MODER   GPIO_MODER_MODER14_0
#define Led_Down_MODER   GPIO_MODER_MODER15_0

//**********************************************
//***************VARIABLES**********************
//**********************************************
long int data[] = {Led_Left, Led_Down, Led_Right, Led_Up};

int main()
{
//***********************************************
//*****************GPIO_Init*********************
//***********************************************
RCC->AHB1ENR |=      Led_Port_Out;
LED_Port->MODER =    Led_Left_MODER|      //Leds like OUT
Led_Up_MODER|
Led_Right_MODER|
Led_Down_MODER;

//***********************************************
//*****************TYM1_Init*********************
//***********************************************
RCC->APB2ENR |=   RCC_APB2ENR_TYM1EN;
TYM1->PSC =    16000 - 1;      //Ftim1 = 1kHz
TYM1->ARR =    1000 - 1;      //Rollover every second
TYM1->EGR |=   TIM_EGR_UG;      //Update PSC omd EGR
TYM1->DIER |=   TIM_DIER_UDE;   //UE generates DMA request
TYM1->CR1  |=   TIM_CR1_CEN;   //Enable TYM1

//***********************************************
//*****************DMA2_Init*********************
//***********************************************
RCC->AHB1ENR |=   RCC_AHB1ENR_DMA2EN;
DMA2_Stream5->CR |=   DMA_SxCR_CHSEL_1|   //Channel6
DMA_SxCR_CHSEL_2|
DMA_SxCR_MSIZE|      //Memory data size = 32 bit
DMA_SxCR_PSIZE|      //Peripheral data size = 32 bit
DMA_SxCR_DIR_0|      //Memory to peripheral
DMA_SxCR_MINC|      //Memory ymsrement
DMA_SxCR_CIRC;
DMA2_Stream5->POR = &GPIOD->ODR;      //Adress of Peripheral
DMA2_Stream5->M0AR= &data[0];         //Adress of Memory
DMA2_Stream5->NDTR = 4;               //4 transaction

DMA2_Stream5->CR |=   DMA_SxCR_EN;      //Lets make a magic

while(1)
{

}
}
0
16.03.2015, 20:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.03.2015, 20:51

Stm32F4 + Ethernet. Прошу помощи
Доброго времени суток. Прошу помощи форумчан в организации соединения PC и МК (Плата:...

Непонятка с таймерами, прошу помощи (решено)
Всем привет! Прошу сильно не пинать, поскольку только начинаю разбираться. Есть у меня плата...

stm32f4 таймеры, непонятный баг. прошу помощи
плата stm32f4discovery. программирую таймеры 2-5 для частотомера-генератора от 10 Гц до 500 кГц...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru