STM32F429 usart DMA 收发
目標:
實現(xiàn)串口通過DMA收發(fā),不使用串口中斷及DMA中斷,使用1ms中斷來判斷是否發(fā)送結(jié)束或啟動發(fā)送。
初始化,使用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配置
?? ? ? //數(shù)據(jù)流選擇
? ? ? ? __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;
?? ? ? //外設數(shù)據(jù)長度:8位一個字節(jié)
?? ? ? UARTDMATX_HD.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
?? ? ? //存儲器數(shù)據(jù)長度:8位
?? ? ? UARTDMATX_HD.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
?? ? ? //外設普通模式
?? ? ? UARTDMATX_HD.Init.Mode = DMA_NORMAL;
?? ? ? //中等優(yōu)先級
?? ? ? UARTDMATX_HD.Init.Priority = DMA_PRIORITY_LOW;
?? ? ? //關(guān)閉FIFO
?? ? ? UARTDMATX_HD.Init.FIFOMode = DMA_FIFOMODE_DISABLE;?? ??? ??? ? ??
?? ? ? //FIFO閥值選擇
?? ? ? UARTDMATX_HD.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
?? ? ? //存儲器突發(fā)單次傳輸
?? ? ? UARTDMATX_HD.Init.MemBurst = DMA_MBURST_SINGLE;
?? ? ? //外設突發(fā)單次傳輸
?? ? ? UARTDMATX_HD.Init.PeriphBurst = DMA_PBURST_SINGLE;
?? ? ? //恢復默認配置
?? ? ? HAL_DMA_DeInit(&UARTDMATX_HD);?
?? ? ? //初始化DMA
?? ? ? HAL_DMA_Init(&UARTDMATX_HD);?
?? ? ? //將DMA與USART1聯(lián)系起來(發(fā)送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); ?//搶占優(yōu)先級0,子優(yōu)先級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中斷,以幀方式接收不定長數(shù)據(jù)
?? ?__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, ? ? ? ? //傳輸?shù)臄?shù)據(jù)指針
? ? ? ? ? ? ? ? ? ? ? ? uint16_t Size) ? ? ? ?//傳輸?shù)臄?shù)據(jù)量
{
? //開啟DMA傳輸
? HAL_UART_DMAStop(&huart1);
? //HAL_DMA_Start(huart1.hdmatx, (uint32_t)pData, (uint32_t)&huart1.Instance->DR, Size);
? //使能串口DMA發(fā)送,沒有對應的函數(shù)只能直接使用寄存器
?// 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);
? ? //傳輸完成以后關(guān)閉串口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;
? }
? //調(diào)用中斷處理公共函數(shù)
? 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 */
}
調(diào)用:
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 */
? }
??
??
}
發(fā)送函數(shù):
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);
?? ?}
}
接收函數(shù):
?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;
?? ?}
總結(jié)
以上是生活随笔為你收集整理的STM32F429 usart DMA 收发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LPC1768 延时函数
- 下一篇: 时间工具类(时间戳转换日期date,获取