Добрый день!
Оправляю данный в UART, DMA выполнил передачу, данные ушли, вызвалось прерывание и МК застрял в нем.
Как сбросить флаг прерывания DMA?
В описании не увидел регистр сброса.
DMA
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
- wertaswood
- Сообщения: 5
- Зарегистрирован: 06 сен 2021, 12:30
- Предприятие: SELFCOMPANY
Re: DMA
Вы делали через ?
Код: Выделить всё
Энвик_EnableIRQ(DMA_Stream0_IRQn);
Re: DMA
Да, через него.
Мб и не стоило полный код примера приводить, но вот так.
Зависает в прерывании... не понимаю почему.
Мб и не стоило полный код примера приводить, но вот так.
Зависает в прерывании... не понимаю почему.
Код: Выделить всё
#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
проверить у меня сейчас нет возможности, но есть ощущение, что необходимо читать DMA_Channel_3 в прерывании, а не просто единицу присваивать