IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F429 usart DMA 收发 -> 正文阅读

[嵌入式]STM32F429 usart DMA 收发


目标:

实现串口通过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;
?? ?}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 12:54:59  更:2021-11-17 12:55:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:39:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码