Я пытался запрограммировать мой микроконтроллер STM32F7xx на использование DMA для передачи в UART.Происходят три вещи, и я не могу объяснить или понять, почему это происходит, и надеюсь, что кто-то может помочь мне с этой проблемой.
- В главном цикле while я печатаю три флага состояния прерывания.Эти флаги устанавливаются, если был вызван соответствующий ISR.Я добавил это, чтобы проверить, был ли вызван ISR без добавления блокирующих операторов в ISR.Однако ни одно из прерываний не вызывается.
- DMA передает только 1 последовательность из 513 байтов.Когда я изменяю цикл while в своем main, чтобы он содержал только
HAL_UART_Transmit_DMA(&handleUart4, dmxBuffer, 513);
, ничего не меняется, функция вызывается / выполняется только один раз. - В цикле while я печатаю состояние флагов ISR.После печати процессор останавливается / блокирует / выключает / выходит из цикла while.Сначала я подумал, что перегружаю AHB, используя UART для моего терминала и UART для контроллера DMA.Я отключил свой терминал и использовал светодиоды, это ничего не изменило.
В настоящее время у меня есть единственная гипотеза о том, что мой процессор каким-то образом отключил прерывания.
#include "stm32f7xx.h"
#include "mbed.h"
uint8_t dmxBuffer[513];
volatile bool irqA = false;
volatile bool irqB = false;
volatile bool irqC = false;
Serial pc(USBTX, USBRX, 115200);
UART_HandleTypeDef handleUart4;
DMA_HandleTypeDef handleDma;
void initialiseGPIO()
{
GPIO_InitTypeDef GPIO_InitStruct;
__GPIOA_CLK_ENABLE();
/**UART4 GPIO Configuration
PA0 ------> USART4_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void initialiseDMAController()
{
/* DMA controller clock enable */
__DMA1_CLK_ENABLE();
/* Peripheral DMA init*/
handleDma.Instance = DMA1_Stream4;
handleDma.Init.Channel = DMA_CHANNEL_4;
handleDma.Init.Direction = DMA_MEMORY_TO_PERIPH;
handleDma.Init.PeriphInc = DMA_PINC_DISABLE;
handleDma.Init.MemInc = DMA_MINC_ENABLE;
handleDma.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
handleDma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
handleDma.Init.Mode = DMA_NORMAL;
handleDma.Init.Priority = DMA_PRIORITY_MEDIUM;
handleDma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&handleDma);
//Define
__HAL_LINKDMA(&handleUart4,hdmatx,handleDma);
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
}
void initialiseUart()
{
__UART4_CLK_ENABLE();
handleUart4.Instance = UART4;
handleUart4.Init.BaudRate = 250000;
handleUart4.Init.WordLength = UART_WORDLENGTH_8B;
handleUart4.Init.StopBits = UART_STOPBITS_2;
handleUart4.Init.Parity = UART_PARITY_NONE;
handleUart4.Init.Mode = UART_MODE_TX;
handleUart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
handleUart4.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&handleUart4);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
}
/* This function handles DMA1 stream4 global interrupt. */
void DMA1_Stream4_IRQHandler(void)
{
irqA = true;
HAL_DMA_IRQHandler(&handleDma);
}
/* This function handles the UART4 interups */
void UART4_IRQHandler(void)
{
irqB = true;
HAL_UART_IRQHandler(&handleUart4);
}
//HAL_UART_TxCpltCallback
/* This callback function is called when the DMA successfully transmits all scheduled bytes. */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
irqC = true;
}
int main(void)
{
/* Reset of all peripherals */
HAL_Init();
//Initialise peripherals
initialiseGPIO();
initialiseDMAController();
initialiseUart();
//Fill buffer with test data
for (int x = 0; x < 100; x++)
{
dmxBuffer[x] = x;
}
//Now instruct the UART peripheral to transmit 513 bytes using the DMA controller.
HAL_UART_Transmit_DMA(&handleUart4, dmxBuffer, 513);
while(1)
{
pc.printf("irqA: %d - irqB: %d - irqC: %d\r\n", irqA, irqB, irqC);
wait_ms(100); //Wait to see if any of the interupt handlers / callback functions are called
//Check if all bytes are sent, if so, retransmit
if (irqC)
{
irqC = false;
HAL_UART_Transmit_DMA(&handleUart4, dmxBuffer, 513);
}
}
}