目标:
实现串口通过DMA收发,不使用串口中断及DMA中断,使用1ms中断来判断是否发送结束或启动发送。
初始化,使用usart1:
1、UART_HandleTypeDef huart1;
typedef struct
{
UINT16 wRxdRdPtr;
UINT16 wRxdWrPtr;
UINT16 wTxdRdPtr;
UINT16 wTxdWrPtr;
BYTE byRxdBuff[2048];
BYTE byTxdBuff[2048];
UART_HandleTypeDef *phandle;
UINT32 dwRamScan2;
}tagCOMM;
tagCOMM g_tUart[1];
int uart0wRxdWrPtr;
int uart0delay=0;
int uart0rxdflag=0;
int uart0txdflag=0;
TIM_HandleTypeDef htim10;
int HY_USART1_UART_Init(int bps,int cs,int databits,int stopbits)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = bps;
huart1.Init.WordLength = databits;
huart1.Init.StopBits = stopbits;
huart1.Init.Parity = cs;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
return -1;
}
g_tUart[0].phandle = &huart1;
return 0;
}
void MYDMA_Config(void)
{
//Tx DMA配置
//数据流选择
__HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能
UARTDMATX_HD.Instance = DMA2_Stream7;
//通道选择
UARTDMATX_HD.Init.Channel = DMA_CHANNEL_4;
//存储器到外设
UARTDMATX_HD.Init.Direction = DMA_MEMORY_TO_PERIPH;
//外设非增量模式,UART只有一个DR寄存器,地址不能变化
UARTDMATX_HD.Init.PeriphInc = DMA_PINC_DISABLE;
//存储器增量模式
UARTDMATX_HD.Init.MemInc = DMA_MINC_ENABLE;
//外设数据长度:8位一个字节
UARTDMATX_HD.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
//存储器数据长度:8位
UARTDMATX_HD.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
//外设普通模式
UARTDMATX_HD.Init.Mode = DMA_NORMAL;
//中等优先级
UARTDMATX_HD.Init.Priority = DMA_PRIORITY_LOW;
//关闭FIFO
UARTDMATX_HD.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
//FIFO阀值选择
UARTDMATX_HD.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
//存储器突发单次传输
UARTDMATX_HD.Init.MemBurst = DMA_MBURST_SINGLE;
//外设突发单次传输
UARTDMATX_HD.Init.PeriphBurst = DMA_PBURST_SINGLE;
//恢复默认配置
HAL_DMA_DeInit(&UARTDMATX_HD);
//初始化DMA
HAL_DMA_Init(&UARTDMATX_HD);
//将DMA与USART1联系起来(发送DMA)
__HAL_linkDMA(&huart1, hdmatx, UARTDMATX_HD);
//Rx DMA配置
UARTDMARX_HD.Instance = DMA2_Stream2;
UARTDMARX_HD.Init.Channel = DMA_CHANNEL_4;
UARTDMARX_HD.Init.Direction = DMA_PERIPH_TO_MEMORY;
UARTDMARX_HD.Init.PeriphInc = DMA_PINC_DISABLE;
UARTDMARX_HD.Init.MemInc = DMA_MINC_ENABLE;
UARTDMARX_HD.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
UARTDMARX_HD.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
UARTDMARX_HD.Init.Mode = DMA_CIRCULAR;
UARTDMARX_HD.Init.Priority = DMA_PRIORITY_LOW;
UARTDMARX_HD.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_DeInit(&UARTDMARX_HD);
HAL_DMA_Init(&UARTDMARX_HD);
__HAL_linkDMA(&huart1, hdmarx, UARTDMARX_HD);
// HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); //抢占优先级0,子优先级0
// HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中断通道
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 3, 2);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
memset(&g_tUart[0],0,sizeof(g_tUart[0]));
// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 3, 1);
// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
// __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //开启IDLE中断,以帧方式接收不定长数据
__HAL_DMA_ENABLE_IT(&UARTDMATX_HD, DMA_IT_TC); //开启DMA传输完成中断
// __HAL_DMA_ENABLE_IT(&UARTDMARX_HD, DMA_IT_TC);
HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
}
void _BSP_UARRxinit(void)
{
if(uart0delay++>5000)
{
uart0delay=0;
HAL_UART_DMAStop(&huart1);
g_tUart[0].wRxdRdPtr=g_tUart[0].wRxdWrPtr=0;
g_tUart[0].wTxdRdPtr=g_tUart[0].wTxdWrPtr=0;
HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
}
if((uart0delay%500)==0)
{
if(g_tUart[0].wTxdRdPtr
_BSP_UARTxTransmit( g_tUart[0].byTxdBuff+g_tUart[0].wTxdRdPtr, g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
g_tUart[0].wTxdRdPtr += (g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
}
}
}
void _BSP_UARTxTransmit(uint8_t *pData, //传输的数据指针
uint16_t Size) //传输的数据量
{
//开启DMA传输
HAL_UART_DMAStop(&huart1);
//HAL_DMA_Start(huart1.hdmatx, (uint32_t)pData, (uint32_t)&huart1.Instance->DR, Size);
//使能串口DMA发送,没有对应的函数只能直接使用寄存器
// huart1.Instance->CR3 |= USART_CR3_DMAT;
g_tUart[0].wRxdRdPtr=g_tUart[0].wRxdWrPtr=0;
HAL_UART_Receive_DMA(&huart1, g_tUart[0].byRxdBuff, 1024);
HAL_UART_Transmit_DMA(&huart1, pData, Size);
uart0delay=0;
uart0txdflag=0x55;
}
void DMA2_Stream7_IRQHandler(void)
{
//DMA2_Steam7传输完成
if(__HAL_DMA_GET_FLAG(&UARTDMATX_HD, DMA_FLAG_TCIF3_7))
{
//清除DMA2_Steam7传输完成标志
__HAL_DMA_CLEAR_FLAG(&UARTDMATX_HD, DMA_FLAG_TCIF3_7);
//传输完成以后关闭串口DMA
// HAL_UART_DMAStop(&huart1);
// __HAL_DMA_ENABLE_IT(&UARTDMATX_HD, DMA_IT_TC);
if(g_tUart[0].wTxdRdPtr>=g_tUart[0].wTxdWrPtr)
g_tUart[0].wTxdWrPtr=g_tUart[0].wTxdRdPtr=0;
uart0txdflag=0;
}
//调用中断处理公共函数
HAL_DMA_IRQHandler(&UARTDMATX_HD);
}
static void MX_TIM10_Init(void)
{
htim10.Instance = TIM10;
htim10.Init.Prescaler =17999 ;
htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
htim10.Init.Period = 10-1;
htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim10.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_base_Init(&htim10) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_base_Start_IT(&htim10);
g_systemdata.count_250us=0;
}
调用:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM10) //250ms
{
GetUart1Rxdprt();
}
}
void GetUart1Rxdprt(void)
{
g_tUart[0].wRxdWrPtr= 1024-UARTDMARX_HD.Instance->NDTR;
COM0rxd();
_BSP_UARRxinit();
}
void COM0rxd(void)
{
if(uart0wRxdWrPtr!=g_tUart[0].wRxdWrPtr)
{
uart0wRxdWrPtr=g_tUart[0].wRxdWrPtr;
if((uart0wRxdWrPtr!=0)&&(uart0wRxdWrPtr<1024))
{
g_byRxdbuf[0]=g_tUart[0].byRxdBuff[uart0wRxdWrPtr-1];
if(g_tUart[0].wRxdWrPtr<4)
{
if((g_byRxdbuf[0]==0xfe))
g_tCOMMCMD[0].cmdflag=0;
}
if(g_tCOMMCMD[0].cmdflag==0)
{
g_tCOMMCMD[0].rxddata=g_byRxdbuf[0];
g_tCOMMCMD[0].rxddelay=10;
}
else
uart0rxdflag=0x55;
if(uart0wRxdWrPtr>10)
g_tCOMMCMD[0].cmdflag=0;
}
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// HAL_NVIC_SetPriority(USART1_IRQn, 9, 5);
// HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
发送函数:
void HY_Uart1_SendData(uint8_t *pbyBuf, uint32_t dwLen)
{
int num=0;
if(g_tUart[num].wTxdWrPtr>2000)
g_tUart[num].wTxdWrPtr=0;
if(g_tUart[num].wTxdRdPtr>2000)
g_tUart[num].wTxdRdPtr=0;
if(g_tCOMMCMD[num].cmdflag!=0x55)
g_tUart[num].wTxdWrPtr=g_tUart[num].wTxdRdPtr=0;
if(g_tUart[0].wTxdWrPtr+dwLen<2000)
{
memcpy(g_tUart[0].byTxdBuff+g_tUart[0].wTxdWrPtr, pbyBuf, dwLen);
g_tUart[0].wTxdWrPtr += dwLen;
}
if(g_tUart[0].wTxdRdPtr == 0)
{
_BSP_UARTxTransmit( g_tUart[0].byTxdBuff+g_tUart[0].wTxdRdPtr, g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
g_tUart[0].wTxdRdPtr += (g_tUart[0].wTxdWrPtr-g_tUart[0].wTxdRdPtr);
}
}
接收函数:
int ComRead(BYTE* rxdbuf,int maxlen)
{
int dwLen=0;
int i;
int port;
dwLen=0;
if(g_tUart[0].wRxdRdPtr==g_tUart[0].wRxdWrPtr)
return dwLen;
for(i=0;i
rxdbuf[i]=g_tUart[0].byRxdBuff[g_tUart[0].wRxdRdPtr++];
if(g_tUart[0].wRxdRdPtr>=1023)
g_tUart[0].wRxdRdPtr=0;
if(g_tUart[0].wRxdRdPtr==g_tUart[0].wRxdWrPtr)
{
dwLen=i+1;
return dwLen;
}
}
return maxlen;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)