21ic问答首页 - 外部与我50微秒通讯一次,串口时间来不急怎么办
外部与我50微秒通讯一次,串口时间来不急怎么办
要求外部与我50微秒通讯一次,串口2.5M,
使用485,需要切换方向角
我接收用串口空闲中断+DMA接收不定长数据包,
发送直接在中断中轮询发送数据,能够正常通讯,但是进行其他操作时间就不充足了,必须要用DMA去发送,
但是我用DMA启动时需要时间,然后我发送完数据后就来不及接收数据了,有没有大佬帮忙看看我设置有什么问题吗
发送是轮询代码
void USARTy_IRQHandler(void)
{
uint16_t clear;
if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
{
/* 切换到发送模式 */
GPIO_SetBits(CHALF_PORT, CHALF_PIN);
uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
TxCounter1 =0;
/*
* 数据处理
*/
while (TxCounter1 < length)
{
/* Send one byte from USARTy to USARTz */
USART_SendData(USARTy, TxBuffer[TxCounter1++]);
/* Loop until USARTy DAT register is empty */
while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
{
}
}
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
clear = USARTy->STS;
clear = USARTy->DAT;
USART_ConfigInt(USARTy, USART_INT_IDLEF, DISABLE);
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
}
}
发送是DMA代码
void USARTy_IRQHandler(void)
{
uint16_t clear;
if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
{
/* 切换到发送模式 */
GPIO_SetBits(CHALF_PORT, CHALF_PIN);
USARTy_Rx_Done = 1;
uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
/*
* 数据处理
*/
clear = USARTy->STS;
clear = USARTy->DAT;
DMA_EnableChannel(USARTy_Tx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Tx_DMA_Channel, length);
DMA_EnableChannel(USARTy_Tx_DMA_Channel, ENABLE);
}
}
void DMA_Channel3_4_IRQHandler(void)
{
if(DMA_GetIntStatus(USARTy_Tx_DMA_INT, DMA) != RESET)
{
USARTy_Tx_Done = 1;
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
DMA_ClrIntPendingBit(USARTy_Tx_DMA_INT, DMA);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
}
}
其他配置
void RS485_Init(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
DMA_Configuration();
USART_InitStructure.BaudRate = 2500000;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
/* Configure USARTy and USARTz */
USART_Init(USARTy, &USART_InitStructure);
USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
/* Enable USARTy DMA Rx and TX request */
USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);
/* Enable USARTy RX DMA1 Channel */
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
/* Enable the USARTy and USARTz */
USART_Enable(USARTy, ENABLE);
}
void RCC_Configuration(void)
{
/* DMA clock enable */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
/* Enable GPIO clock */
RCC_EnableAPB2PeriphClk(USARTy_GPIO_CLK, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
/* Enable USARTy Clock */
USARTy_APBxClkCmd(USARTy_CLK, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitType GPIO_InitStructure;
/* Initialize GPIO_InitStructure */
GPIO_InitStruct(&GPIO_InitStructure);
//dir
GPIO_InitStructure.Pin = CHALF_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
GPIO_InitPeripheral(CHALF_PORT, &GPIO_InitStructure);
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTy_TxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.GPIO_Alternate = USARTy_Tx_GPIO_AF;
GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);
/* Configure USARTx Rx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTy_RxPin;
GPIO_InitStructure.GPIO_Alternate = USARTy_Rx_GPIO_AF;
GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitType NVIC_InitStructure;
/* Enable the USARTy_Rx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USARTy_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USARTy_Tx DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USARTy_Tx_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DMA_Configuration(void)
{
DMA_InitType DMA_InitStructure;
/* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
DMA_DeInit(USARTy_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
DMA_InitStructure.MemAddr = (uint32_t)TxBuffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = TxBufferSize;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
DMA_RequestRemap(USARTy_Tx_DMA_REMAP, DMA, USARTy_Tx_DMA_Channel, ENABLE);
/* USARTy RX DMA Channel (triggered by USARTy Rx event) Config */
DMA_DeInit(USARTy_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
DMA_InitStructure.MemAddr = (uint32_t)RxBuffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = RxBufferSize;
DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
DMA_RequestRemap(USARTy_Rx_DMA_REMAP, DMA, USARTy_Rx_DMA_Channel, ENABLE);
}
使用485,需要切换方向角
我接收用串口空闲中断+DMA接收不定长数据包,
发送直接在中断中轮询发送数据,能够正常通讯,但是进行其他操作时间就不充足了,必须要用DMA去发送,
但是我用DMA启动时需要时间,然后我发送完数据后就来不及接收数据了,有没有大佬帮忙看看我设置有什么问题吗
发送是轮询代码
void USARTy_IRQHandler(void)
{
uint16_t clear;
if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
{
/* 切换到发送模式 */
GPIO_SetBits(CHALF_PORT, CHALF_PIN);
uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
TxCounter1 =0;
/*
* 数据处理
*/
while (TxCounter1 < length)
{
/* Send one byte from USARTy to USARTz */
USART_SendData(USARTy, TxBuffer[TxCounter1++]);
/* Loop until USARTy DAT register is empty */
while (USART_GetFlagStatus(USARTy, USART_FLAG_TXDE) == RESET)
{
}
}
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
clear = USARTy->STS;
clear = USARTy->DAT;
USART_ConfigInt(USARTy, USART_INT_IDLEF, DISABLE);
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
}
}
发送是DMA代码
void USARTy_IRQHandler(void)
{
uint16_t clear;
if(USART_GetIntStatus(USARTy, USART_INT_IDLEF)!= RESET )
{
/* 切换到发送模式 */
GPIO_SetBits(CHALF_PORT, CHALF_PIN);
USARTy_Rx_Done = 1;
uint16_t length = RxBufferSize - USARTy_Rx_DMA_Channel->TXNUM;
/*
* 数据处理
*/
clear = USARTy->STS;
clear = USARTy->DAT;
DMA_EnableChannel(USARTy_Tx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Tx_DMA_Channel, length);
DMA_EnableChannel(USARTy_Tx_DMA_Channel, ENABLE);
}
}
void DMA_Channel3_4_IRQHandler(void)
{
if(DMA_GetIntStatus(USARTy_Tx_DMA_INT, DMA) != RESET)
{
USARTy_Tx_Done = 1;
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
DMA_ClrIntPendingBit(USARTy_Tx_DMA_INT, DMA);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
DMA_SetCurrDataCounter(USARTy_Rx_DMA_Channel, 6);
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
}
}
其他配置
void RS485_Init(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
DMA_Configuration();
USART_InitStructure.BaudRate = 2500000;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
/* Configure USARTy and USARTz */
USART_Init(USARTy, &USART_InitStructure);
USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE);
/* Enable USARTy DMA Rx and TX request */
USART_EnableDMA(USARTy, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);
/* Enable USARTy RX DMA1 Channel */
DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
/* Enable the USARTy and USARTz */
USART_Enable(USARTy, ENABLE);
}
void RCC_Configuration(void)
{
/* DMA clock enable */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
/* Enable GPIO clock */
RCC_EnableAPB2PeriphClk(USARTy_GPIO_CLK, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
/* Enable USARTy Clock */
USARTy_APBxClkCmd(USARTy_CLK, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitType GPIO_InitStructure;
/* Initialize GPIO_InitStructure */
GPIO_InitStruct(&GPIO_InitStructure);
//dir
GPIO_InitStructure.Pin = CHALF_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_HIGH;
GPIO_InitPeripheral(CHALF_PORT, &GPIO_InitStructure);
GPIO_ResetBits(CHALF_PORT, CHALF_PIN);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTy_TxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.GPIO_Alternate = USARTy_Tx_GPIO_AF;
GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);
/* Configure USARTx Rx as alternate function push-pull */
GPIO_InitStructure.Pin = USARTy_RxPin;
GPIO_InitStructure.GPIO_Alternate = USARTy_Rx_GPIO_AF;
GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
NVIC_InitType NVIC_InitStructure;
/* Enable the USARTy_Rx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USARTy_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USARTy_Tx DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USARTy_Tx_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void DMA_Configuration(void)
{
DMA_InitType DMA_InitStructure;
/* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
DMA_DeInit(USARTy_Tx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
DMA_InitStructure.MemAddr = (uint32_t)TxBuffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
DMA_InitStructure.BufSize = TxBufferSize;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
DMA_RequestRemap(USARTy_Tx_DMA_REMAP, DMA, USARTy_Tx_DMA_Channel, ENABLE);
/* USARTy RX DMA Channel (triggered by USARTy Rx event) Config */
DMA_DeInit(USARTy_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr = USARTy_DAT_Base;
DMA_InitStructure.MemAddr = (uint32_t)RxBuffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = RxBufferSize;
DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
DMA_RequestRemap(USARTy_Rx_DMA_REMAP, DMA, USARTy_Rx_DMA_Channel, ENABLE);
}
赞0
2、切换方向脚会产生毛刺
3、可以将所有的库函数操作变成直接操作寄存器
评论
2025-03-27
您需要登录后才可以回复 登录 | 注册