目标:
实现串口通过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) {
? /* USER CODE BEGIN USART1_Init 0 */
? /* USER CODE END USART1_Init 0 */
? /* USER CODE BEGIN USART1_Init 1 */
? /* USER CODE END USART1_Init 1 */ ? 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; ? } ? /* USER CODE BEGIN USART1_Init 2 */ ? 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<g_tUart[0].wTxdWrPtr) ?? ??? ?{ ?? ??? ??? ?_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) {
? /* USER CODE BEGIN TIM10_Init 0 */
? /* USER CODE END TIM10_Init 0 */
? /* USER CODE BEGIN TIM10_Init 1 */
? /* USER CODE END TIM10_Init 1 */ ? 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(); ? } ? /* USER CODE BEGIN TIM10_Init 2 */ ? HAL_TIM_Base_Start_IT(&htim10); ? g_systemdata.count_250us=0;
? /* USER CODE END TIM10_Init 2 */
}
调用:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { ? ?
?? ?/* USER CODE BEGIN Callback 1 */ ?? ?if (htim->Instance == TIM10) ?//250ms ?? ?{ ? ? ? ?? ?? ??? ?GetUart1Rxdprt(); ? ? ? ?? ?? ?}
?? ?/* USER CODE END Callback 1 */ }
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)
? { ? /* USER CODE BEGIN USART1_MspInit 0 */
? /* USER CODE END USART1_MspInit 0 */ ? ? /* Peripheral clock enable */ ? ? __HAL_RCC_USART1_CLK_ENABLE(); ?? ? ? __HAL_RCC_GPIOB_CLK_ENABLE(); ? ? /**USART1 GPIO Configuration ? ? ? ? PB6 ? ? ------> USART1_TX ? ? PB7 ? ? ------> USART1_RX? ? ? */ ? ? 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);
? ? /* USART1 interrupt Init */ ? ?// HAL_NVIC_SetPriority(USART1_IRQn, 9, 5); ? ?// HAL_NVIC_EnableIRQ(USART1_IRQn); ? /* USER CODE BEGIN USART1_MspInit 1 */
? /* USER CODE END USART1_MspInit 1 */ ? } ??
??
}
发送函数:
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<maxlen;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; ?? ?}
|