Mty 0 15 апреля Опубликовано 15 апреля · Жалоба Приветствую! Не работает DMA. Пересылка Memory->GPIO по таймеру. Идея в том, что Timer1 Channel1 по событию UpdateEvent запускает DMA передачу в порт B. Побайтно, в циклическом режиме. Таймер работает (видно по выходу осциллографом), а в порту B тишина - все пины 0 Подскажите - как запустить DMA передачу? PS: За основу брал статью https://istarik.ru/blog/stm32/139.html MX_GPIO_Init(); MX_DMA_Init(); MX_TIM1_Init(); /* USER CODE BEGIN 2 */ PrepareDMAbuffer(); // Здесь в буфер заливаются данные буфер 12900байт HAL_DMA_Start(htim1.hdma[TIM_DMA_ID_UPDATE], (uint32_t)DMAbuff, (uint32_t)&GPIOB->ODR, BUFFSIZE); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); /* Enable the TIM Update DMA request */ __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&htim1); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 15 апреля Опубликовано 15 апреля · Жалоба Флаги в регистрах DMA посмотрите, происходят ли передачи, не ли ошибок. Запись в GPIO->ODR программно работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mty 0 15 апреля Опубликовано 15 апреля · Жалоба 53 minutes ago, amaora said: Флаги в регистрах DMA посмотрите, происходят ли передачи, не ли ошибок. Запись в GPIO->ODR программно работает? Да, программно работает. Спасибо за идею с регистрами - посмотрю. А где то есть дока на функции типа HAL_DMA_Start() и макросы __HAL_TIM_ENABLE_DMA() - в какой последовательности их запускать, с примерами итд? А то вслепую тащу их из интернета, а нормальной доки нет. По исходникам смотрю - но там совсем не ясно в какой последовательности их использовать и какие из них нужны? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 76 15 апреля Опубликовано 15 апреля · Жалоба В 16.04.2024 в 03:24, Mty сказал: А где то есть дока на функции типа HAL_DMA_Start Так ищи в гугле слово "HAL_DMA_Start" там множество примеров будет. Еще примеры были в комплекте с документацией для отладочных плат STM. Скачивается на их сайте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
deni 6 16 апреля Опубликовано 16 апреля · Жалоба Стоит обратить внимание, что GPIO находятся на шине AHB1, доступ к которой имеет только DMA2. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mty 0 17 апреля Опубликовано 17 апреля · Жалоба Решено! Спасибо всем. HAL_DMA_Init(&hdma_tim1_up); HAL_DMA_Start(&hdma_tim1_up, (uint32_t)&DMAbuff, (uint32_t)&GPIOB->ODR, MAX_TICKS); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); TIM1->DIER |= (1 << 8); Одна из основных проблем была в том, что потерялся & перед &DMAbuff Кроме того переписал все попутно в регистрах. И думаю - дальше работать с регистрами, или остаться в HAL? Привожу ниже - может кому пригодится DMA2_Stream5->PAR = (uint32_t)&(GPIOB->ODR); // Set peripheral address DMA2_Stream5->M0AR = (uint32_t)&DMAbuff; // Set memory address DMA2_Stream5->NDTR = MAX_TICKS; // set number of bytes to transfer DMA2_Stream5->CR |= (6 << DMA_SxCR_CHSEL_Pos); // enable channel 6 (TIM1_UP) DMA2_Stream5->CR |= (2 << DMA_SxCR_PL_Pos); // set to high priority // FIFO should be disabled by default DMA2_Stream5->CR |= (1 << DMA_SxCR_DIR_Pos); //set memory-to-peripheral DMA2_Stream5->CR |= (1 << DMA_SxCR_MINC_Pos); //Incremement memory address // Assume PINC is 0 //Assume burst is set to single transfer DMA2_Stream5->CR |= (0 << DMA_SxCR_MSIZE_Pos); // Set memory data width to a byte DMA2_Stream5->CR |= (0 << DMA_SxCR_PSIZE_Pos); // Set peripheral data width to a byte DMA2_Stream5->CR |= (1 << DMA_SxCR_CIRC_Pos); // Set to circular mode // Assume DBM is zero DMA2_Stream5->CR |= (1 << DMA_SxCR_EN_Pos); //enable DMA TIM1->DIER |= (1 << 8); // set UDE bit (update dma request enable) HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 17 апреля Опубликовано 17 апреля · Жалоба On 4/17/2024 at 1:52 PM, Mty said: DMA2_Stream5->CR |= (6 << DMA_SxCR_CHSEL_Pos); // enable channel 6 (TIM1_UP) DMA2_Stream5->CR |= (2 << DMA_SxCR_PL_Pos); // set to high priority // FIFO should be disabled by default DMA2_Stream5->CR |= (1 << DMA_SxCR_DIR_Pos); //set memory-to-peripheral DMA2_Stream5->CR |= (1 << DMA_SxCR_MINC_Pos); //Incremement memory address // Assume PINC is 0 //Assume burst is set to single transfer DMA2_Stream5->CR |= (0 << DMA_SxCR_MSIZE_Pos); // Set memory data width to a byte DMA2_Stream5->CR |= (0 << DMA_SxCR_PSIZE_Pos); // Set peripheral data width to a byte DMA2_Stream5->CR |= (1 << DMA_SxCR_CIRC_Pos); // Set to circular mode // Assume DBM is zero DMA2_Stream5->CR |= (1 << DMA_SxCR_EN_Pos); //enable DMA Почему на запись каждого бита отдельная операция ? Почему не прописали все биты одной операцией ? Вот так DMA2_Stream5->CR = (6 << DMA_SxCR_CHSEL_Pos) | // enable channel 6 (TIM1_UP) (2 << DMA_SxCR_PL_Pos) | // set to high priority (1 << DMA_SxCR_DIR_Pos) | //set memory-to-peripheral (1 << DMA_SxCR_MINC_Pos) | //Incremement memory address (0 << DMA_SxCR_MSIZE_Pos) | // Set memory data width to a byte (0 << DMA_SxCR_PSIZE_Pos) | // Set peripheral data width to a byte (1 << DMA_SxCR_CIRC_Pos) | // Set to circular mode (1 << DMA_SxCR_EN_Pos); //enable DMA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 231 17 апреля Опубликовано 17 апреля · Жалоба 1 час назад, Mty сказал: DMA2_Stream5->CR |= (6 << DMA_SxCR_CHSEL_Pos); // enable channel 6 (TIM1_UP) DMA2_Stream5->CR |= (2 << DMA_SxCR_PL_Pos); // set to high priority ... Кошмар.... Отрубание хвоста собаки по частям. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 17 апреля Опубликовано 17 апреля · Жалоба On 4/17/2024 at 3:27 PM, jcxz said: Кошмар.... Отрубание хвоста собаки по частям. Так наоборот же. Пришивание Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Mty 0 17 апреля Опубликовано 17 апреля · Жалоба 27 minutes ago, dimka76 said: Почему на запись каждого бита отдельная операция ? Почему не прописали все биты одной операцией ? Вот так DMA2_Stream5->CR = (6 << DMA_SxCR_CHSEL_Pos) | // enable channel 6 (TIM1_UP) (2 << DMA_SxCR_PL_Pos) | // set to high priority (1 << DMA_SxCR_DIR_Pos) | //set memory-to-peripheral (1 << DMA_SxCR_MINC_Pos) | //Incremement memory address (0 << DMA_SxCR_MSIZE_Pos) | // Set memory data width to a byte (0 << DMA_SxCR_PSIZE_Pos) | // Set peripheral data width to a byte (1 << DMA_SxCR_CIRC_Pos) | // Set to circular mode (1 << DMA_SxCR_EN_Pos); //enable DMA Да, спасибо, конечно так сделаю. А для проверки ошибок DMA можно просто опрашивать флаг DMA high interrupt status register (DMA_HISR) TEIF5 без прерывания, верно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 59 17 апреля Опубликовано 17 апреля · Жалоба On 4/17/2024 at 3:53 PM, Mty said: А для проверки ошибок DMA можно просто опрашивать флаг DMA high interrupt status register (DMA_HISR) TEIF5 без прерывания, верно? Можно. Только зачем тратить на это процессорное время ? Лучше разрешить на них прерывания и обработку ошибок вести только в случае возникновения этих ошибок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться