在线时间69 小时
UID3399501
注册时间2020-7-31
NXP金币0
TA的每日心情 | 无聊 2021-1-15 10:56 |
---|
签到天数: 39 天 [LV.5]常住居民I
中级会员
- 积分
- 436
- 最后登录
- 2021-10-9
|
最近使用串口DMA,因为串口接收到数据之后需要做回复和数据处理,而且两次串口指令之间的间隔非常短。所以使用了DMA,但是在使用中发现启动DMA后,去让MCU干点其他事,就会因为时间不够导致数据发送不完整。好像DMA启动之后MCU并不能释放串口发送的进程。是我的启动代码有问题吗?
/* UART user callback */
void UART_UserCallback(UART_Type *base, uart_edma_handle_t *handle, status_t status, void *userData)
{
userData = userData;
if (kStatus_UART_TxIdle == status)
{
txBufferFull = false;
txOnGoing = false;
}
if (kStatus_UART_RxIdle == status)
{
rxBufferEmpty = false;
rxOnGoing = false;
}
}
const uart_config_t UART0_config = {
.baudRate_Bps = 2500000,
.parityMode = kUART_ParityDisabled,
.txFifoWatermark = 0,
.rxFifoWatermark = 1,
.idleType = kUART_IdleTypeStartBit,
.enableTx = true,
.enableRx = true
};
void UART0_init(void) {
UART_Init(UART0_PERIPHERAL, &UART0_config, UART0_CLOCK_SOURCE);
UART_EnableInterrupts(UART0_PERIPHERAL, kUART_RxDataRegFullInterruptEnable);
NVIC_SetPriority(UART0_SERIAL_RX_TX_IRQN,0);
/* Enable interrupt UART0_RX_TX_IRQn request in the NVIC */
EnableIRQ(UART0_SERIAL_RX_TX_IRQN);
}
uart_transfer_t sendXfer;
void DMA_init(void)
{
edma_config_t config;
uart_transfer_t xfer;
uart_transfer_t receiveXfer;
/* Init DMAMUX */
DMAMUX_Init(EXAMPLE_UART_DMAMUX_BASEADDR);
/* Set channel for UART */
DMAMUX_SetSource(EXAMPLE_UART_DMAMUX_BASEADDR, UART_TX_DMA_CHANNEL, UART_TX_DMA_REQUEST);
DMAMUX_EnableChannel(EXAMPLE_UART_DMAMUX_BASEADDR, UART_TX_DMA_CHANNEL);
/* Init the EDMA module */
EDMA_GetDefaultConfig(&config);
EDMA_Init(EXAMPLE_UART_DMA_BASEADDR, &config);
EDMA_CreateHandle(&g_uartTxEdmaHandle, EXAMPLE_UART_DMA_BASEADDR, UART_TX_DMA_CHANNEL);
/* Create UART DMA handle. */
UART_TransferCreateHandleEDMA(UART0_PERIPHERAL, &g_uartEdmaHandle, NULL, NULL, &g_uartTxEdmaHandle,
&g_uartRxEdmaHandle);
/* Start to echo. */
sendXfer.data = demoRingBuffer;
sendXfer.dataSize = 11;
txOnGoing = true;
}
/*****************启动DMA************************/
void DMA_Tx(uart_edma_handle_t *handle)
{
edma_transfer_config_t xferConfig;
handle->txDataSizeAll = 11;
/* Prepare transfer. */
EDMA_PrepareTransfer(&xferConfig, demoRingBuffer, sizeof(uint8_t), (uint32_t *)(uint32_t) & (UART0_PERIPHERAL->D),
sizeof(uint8_t), sizeof(uint8_t), 11, kEDMA_MemoryToPeripheral);
/* Submit transfer. */
(void)EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig);
EDMA_StartTransfer(handle->txEdmaHandle);
/* Enable UART TX EDMA. */
UART0_PERIPHERAL->C5 |= (uint8_t)UART_C5_TDMAS_MASK;
UART0_PERIPHERAL->C2 |= (uint8_t)UART_C2_TIE_MASK;
}
*******************************************************
中断代码:
/* UART0_RX_TX_IRQn interrupt handler */
uint8_t data;
void UART0_SERIAL_RX_TX_IRQHANDLER(void) {
data = UART0_PERIPHERAL->D;
if(data == 0x1A)
{
BOARD_INITPINS_RS485EN_GPIO->PSOR = GPIO_FIT_REG(1u<<BOARD_INITPINS_RS485EN_PIN);
DMA_Tx(&g_uartEdmaHandle); //*****启动DMA
while((kUART_TransmissionCompleteFlag & UART_GetStatusFlags(UART0_PERIPHERAL) )== 0);
BOARD_INITPINS_RS485EN_GPIO->PCOR = GPIO_FIT_REG(1u<<BOARD_INITPINS_RS485EN_PIN);
// ADC_VALUE_change();//数据处理,若把此处理代码放到启动DMA后面。会造成数据发送不完整,如果放在此处,会因为处理数据时间太长而导致下一次中断得不到相应。(数据处理中太多三角函数,耗时超过8us)
}
if(data==0xAA)
{
Angle_Collection();
}
UART_ClearStatusFlags(UART0_PERIPHERAL, (uint32_t)kUART_RxDataRegFullFlag | kUART_RxOverrunFlag);
SDK_ISR_EXIT_BARRIER;
}
|
|