DMA

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

Ответить
Paul125
Сообщения: 15
Зарегистрирован: 11 май 2022, 17:02
Предприятие: ООО НПП ЭКРА

DMA

Сообщение Paul125 »

Добрый день!
Оправляю данный в UART, DMA выполнил передачу, данные ушли, вызвалось прерывание и МК застрял в нем.
Как сбросить флаг прерывания DMA?
В описании не увидел регистр сброса.
Аватара пользователя
wertaswood
Сообщения: 5
Зарегистрирован: 06 сен 2021, 12:30
Предприятие: SELFCOMPANY

Re: DMA

Сообщение wertaswood »

Вы делали через

Код: Выделить всё

Энвик_EnableIRQ(DMA_Stream0_IRQn);
?
Paul125
Сообщения: 15
Зарегистрирован: 11 май 2022, 17:02
Предприятие: ООО НПП ЭКРА

Re: DMA

Сообщение Paul125 »

Да, через него.
Мб и не стоило полный код примера приводить, но вот так.
Зависает в прерывании... не понимаю почему.

Код: Выделить всё

#include "niietcm4.h"
#include "system_K1921VK01T.h"
#include "K1921VK01T.h"

#define SYSTEM_CLK 	72000000
#define SPEED_UART3 	115200

// общее количество байт на пересылку
#define RS485_TX_BUFFER_SIZE	20

// килобайт управляющих структур DMA
#if defined (__CMCPPARM__)
#pragma data_alignment=1024
#endif
DMA_ConfigData_TypeDef DMA_CONFIGDATA __ALIGNED(1024);

uint8_t uart3_tx_arr[RS485_TX_BUFFER_SIZE] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
		0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14 };

void GPIO_Ph_Init() {
	// настройка LED
	GPIO_Init_TypeDef GPIO_InitStruct;
	GPIO_StructInit(&GPIO_InitStruct);
	GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
	GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15 | GPIO_Pin_15;
	GPIO_Init(NT_GPIOC, &GPIO_InitStruct);
	GPIO_Init(NT_GPIOD, &GPIO_InitStruct);

	// настройка UART 3
	// rx
	GPIO_StructInit(&GPIO_InitStruct);
	GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_1;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_Init(NT_GPIOF, &GPIO_InitStruct);
	// tx
	GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
	GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
	GPIO_Init(NT_GPIOF, &GPIO_InitStruct);

}

void PeriphInit() {
	RCC_PLLAutoConfig(RCC_PLLRef_XI_OSC, SYSTEM_CLK);

	// настройка тактирования и сброса UART
	RCC_UARTClkSel(NT_UART3, RCC_UARTClk_SYSCLK);
	RCC_UARTClkCmd(NT_UART3, ENABLE);
	RCC_PeriphRstCmd(RCC_PeriphRst_UART3, ENABLE);

	// настройка блоков UART
	UART_Init_TypeDef UART_InitStruct;
	UART_StructInit(&UART_InitStruct);
	UART_InitStruct.UART_BaudRate = SPEED_UART3;
	UART_InitStruct.UART_ClkFreq = SYSTEM_CLK;
	UART_InitStruct.UART_DataWidth = UART_DataWidth_8;
	UART_InitStruct.UART_FIFOEn = DISABLE;
	UART_InitStruct.UART_FIFOLevelRx = UART_FIFOLevel_1_2;
	UART_InitStruct.UART_FIFOLevelTx = UART_FIFOLevel_1_2;
	UART_InitStruct.UART_ParityBit = UART_ParityBit_Even;
	UART_InitStruct.UART_StopBit = UART_StopBit_1;
	UART_InitStruct.UART_RxEn = ENABLE;
	UART_InitStruct.UART_TxEn = ENABLE;

	UART_Init(NT_UART3, &UART_InitStruct);
	UART_Cmd(NT_UART3, ENABLE);

	// ================== Инициализация DMA ========================== //
	// Базовый указатель
	DMA_BasePtrConfig((uint32_t) (&DMA_CONFIGDATA));

	// Инициализация контроллера DMA
	DMA_Init_TypeDef DMA_InitStruct;
	DMA_StructInit(&DMA_InitStruct);
	DMA_InitStruct.DMA_Channel = DMA_Channel_UART3_TX;
	DMA_InitStruct.DMA_ChannelEnable = ENABLE;
	DMA_Init(&DMA_InitStruct);
	DMA_MasterEnableCmd(ENABLE);

	/* Энвик init */
	Энвик_EnableIRQ(DMA_Stream3_IRQn);
}

/**
 * @brief	Определение DMA на отправку.
 * @param1	source - адрес конца ячейки источника данных //&uart3_tx_arr[RS485_BUFFER_SIZE - 1]
 * @param2	val - количество передач
 * @retval	0 = OK
 */
void DMA_UART_SEND(NT_UART_TypeDef *UARTx, uint8_t *source, uint32_t val) {
	UART_DMACmd(UARTx, UART_Dir_Tx, DISABLE);
	/* переинициализация канала DMA3 - UART3 TX */
	uint32_t UARTCh, DMACh;

	if (UARTx == NT_UART0) {UARTCh = DMA_Channel_0; DMACh = 0;}
	if (UARTx == NT_UART1) {UARTCh = DMA_Channel_1; DMACh = 1;}
	if (UARTx == NT_UART2) {UARTCh = DMA_Channel_2; DMACh = 2;}
	else{	UARTCh = DMA_Channel_3; DMACh = 3;}

	DMA_ChannelInit_TypeDef DMA_ChannelInitStruct;
	DMA_ChannelStructInit(&DMA_ChannelInitStruct);
	DMA_ChannelInitStruct.DMA_SrcDataSize = DMA_DataSize_8;
	DMA_ChannelInitStruct.DMA_DstDataSize = DMA_DataSize_8;
	DMA_ChannelInitStruct.DMA_TransfersTotal = val;
	DMA_ChannelInitStruct.DMA_Mode = DMA_Mode_Basic;
	DMA_ChannelInitStruct.DMA_SrcDataInc = DMA_DataInc_8;
	DMA_ChannelInitStruct.DMA_DstDataInc = DMA_DataInc_Disable;
	DMA_ChannelInitStruct.DMA_ArbitrationRate = DMA_ArbitrationRate_1;
	DMA_ChannelInitStruct.DMA_SrcDataEndPtr = source;
	DMA_ChannelInitStruct.DMA_DstDataEndPtr = (uint8_t*) (&UARTx->DR);
	DMA_ChannelInit(&DMA_CONFIGDATA.PRM_DATA.CH[DMACh], &DMA_ChannelInitStruct);
	DMA_ChannelEnableCmd(UARTCh, ENABLE);
	UART_DMACmd(UARTx, UART_Dir_Tx, ENABLE);
}

uint8_t irq = 0;

int main() {
	GPIO_Ph_Init();
	PeriphInit();
	DMA_UART_SEND(NT_UART3, &uart3_tx_arr[RS485_TX_BUFFER_SIZE - 1], RS485_TX_BUFFER_SIZE);

	while (1) {
		if(irq){

			// ждем пока передача завершится
			while ((uint32_t) (UART_FlagStatus(NT_UART3, UART_Flag_TxFIFOFull)));
			while (!(uint32_t) (UART_FlagStatus(NT_UART3, UART_Flag_TxFIFOEmpty)));
			while ((uint32_t) (UART_FlagStatus(NT_UART3, UART_Flag_Busy)));

			DMA_UART_SEND(NT_UART3, &uart3_tx_arr[RS485_TX_BUFFER_SIZE - 1], RS485_TX_BUFFER_SIZE);

			GPIO_ToggleBits(NT_GPIOC, GPIO_Pin_13);
			for (uint32_t i = 0; i < 15000000; i++);
			irq=0;
		}
	}
}
void DMA_Stream3_IRQHandler() {
	irq=1;
}
Аватара пользователя
wertaswood
Сообщения: 5
Зарегистрирован: 06 сен 2021, 12:30
Предприятие: SELFCOMPANY

Re: DMA

Сообщение wertaswood »

проверить у меня сейчас нет возможности, но есть ощущение, что необходимо читать DMA_Channel_3 в прерывании, а не просто единицу присваивать
Ответить

Вернуться в «32-разрядные микроконтроллеры»