我一直在尝试对STM32F7xx微控制器进行编程,以使用DMA传输到UART。正在发生三件事,我无法解释或理解为什么会发生这种情况,希望有人可以帮助我解决这个问题。
HAL_UART_Transmit_DMA(&handleUart4, dmxBuffer, 513);
时,没有任何变化,该函数仅被调用/执行一次。当前,我唯一的运行假设是我的CPU某种程度上禁用了中断。
#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);
}
}
}
答案 0 :(得分:0)
检查中断向量表
验证向量表确实包含指向您的处理函数的指针,而不是指向具有无限循环(使程序挂起)的某些通用占位符的指针。
在 entire 源代码中搜索中断处理程序函数的名称。还有其他任何对象或#define
可能会干扰函数定义或向量表条目吗?
更改处理程序的名称,包括函数定义和向量表条目。它仍然可以编译吗?否则,将extern "C"
添加到函数原型中是否有帮助?
在.map
文件中查找处理程序的地址,并在参考手册(嵌套矢量中断控制器(NVIC)/中断和异常)中的向量表中找到中断的偏移项向量)。以给定的偏移量检查编译的程序二进制文件的内容。它与.map
文件+ 1中找到的地址匹配吗?
在运行程序时检查NVIC->VTOR
处的值加上偏移量。它应该与二进制文件中的相同。如果没有,请查看VTOR
寄存器是否设置在右向量表的开头。