OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2419|回复: 9

[F103C8T6 UART DMA]用串口的DMA发数据,上电发一次就不发了,会是什么原因呢?

[复制链接]

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
发表于 2019-9-23 16:34:04 | 显示全部楼层 |阅读模式
1金钱
想着用串口DMA,每两秒发一次数据。结果是上电之后只发一次,之后就不发了,一直找不到原因。
DMA配置为从存储到外设,这里用的是串口1的DMA发送,主函数里面是每个两秒发送调用一次DMA发送。下面是串口DMA的配置
  • 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_GPIOA_CLK_ENABLE();
  •     /**USART1 GPIO Configuration
  •     PA9     ------> USART1_TX
  •     PA10     ------> USART1_RX
  •     */
  •     GPIO_InitStruct.Pin = GPIO_PIN_9;
  •     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  •     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  •     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  •     GPIO_InitStruct.Pin = GPIO_PIN_10;
  •     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  •     GPIO_InitStruct.Pull = GPIO_NOPULL;
  •     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  •     /* USART1 DMA Init */
  •     /* USART1_TX Init */
  •     hdma_usart1_tx.Instance = DMA1_Channel4;
  •     hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  •     hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  •     hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
  •     hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  •     hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  •     hdma_usart1_tx.Init.Mode = DMA_NORMAL;
  •     hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
  •     if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
  •     {
  •       Error_Handler();
  •     }
  •     __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
  •     /* USART1 interrupt Init */
  •     HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  •     HAL_NVIC_EnableIRQ(USART1_IRQn);
  •   /* USER CODE BEGIN USART1_MspInit 1 */
  •   /* USER CODE END USART1_MspInit 1 */
  •   }
  • }

主函数里面


  • while (1)
  •   {
  •     /* USER CODE END WHILE */
  •     /* USER CODE BEGIN 3 */
  •                 if(TimeCtrl1.IsTXTime)//每隔两秒发一次;
  •                 {
  •                         TimeCtrl1.IsTXTime=0;
  •                        
  •                                 MYDMA_USART_Transmit(&huart1,src,14);
  •                        
  •                 //        HAL_UART_Transmit(&huart1,src,14,0xffffffff);//测试串口是否正常用的。
  •                 }
  •   }
TimeCtrl1时间控制结构体定义

  • typedef struct
  • {
  •         unsigned char IsTXTime :1;
  •         unsigned int TimeCnt;
  • }FlagType;
  • void SysTick_Handler(void)
  • {
  •   /* USER CODE BEGIN SysTick_IRQn 0 */
  •         TimeCtrl1.TimeCnt++;
  •         if(2000==TimeCtrl1.TimeCnt)
  •         {
  •                 TimeCtrl1.IsTXTime=1;
  •                 TimeCtrl1.TimeCnt=0;
  •        
  •         }
  •   /* USER CODE END SysTick_IRQn 0 */
  •   HAL_IncTick();
  •   /* USER CODE BEGIN SysTick_IRQn 1 */
  •   /* USER CODE END SysTick_IRQn 1 */
  • }




DMA发送函数:
  • void MYDMA_USART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
  • {
  •     HAL_DMA_Start(huart->hdmatx, (u32)pData, (uint32_t)&huart->Instance->DR, Size);//¿aÆôDMA′«êä
  •     huart->Instance->CR3 |= USART_CR3_DMAT;//ê1Äü′®¿úDMA·¢Ëí
  • }       




DMA初始化函数:
  • static void MX_DMA_Init(void)
  • {
  •   /* DMA controller clock enable */
  •   __HAL_RCC_DMA1_CLK_ENABLE();
  •   /* DMA interrupt init */
  •   /* DMA1_Channel4_IRQn interrupt configuration */
  •   HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
  •   HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);


}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
 楼主| 发表于 2019-9-23 16:35:45 | 显示全部楼层
按一次复位键发一次,之后就不发了。。
回复

使用道具 举报

2

主题

582

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2690
金钱
2690
注册时间
2014-5-23
在线时间
188 小时
发表于 2019-9-23 21:32:39 | 显示全部楼层
看看是否什么标志位没有清除
回复

使用道具 举报

0

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2019-7-13
在线时间
33 小时
发表于 2019-9-24 08:51:26 | 显示全部楼层
1、首先我觉得您使用的DMA发送函数可能不对,HAL_DMA_Start()此函数是内存到内存进行数据传输时使用的函数,你可以看下源代码。想要使用串口DMA传输,建议您用HAL_UART_Transmit_DMA(),使用这个函数的时候要注意一个问题,你必须打开串口中断和DMA中断,因为在中断服务函数当中会进行一些库函数变量的恢复(比如中断标志位的清除,状态变量的复位等,具体你需要看源程序)。有问题  Q(744180121)
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10570
金钱
10570
注册时间
2017-2-18
在线时间
1913 小时
发表于 2019-9-24 12:13:08 | 显示全部楼层
回复

使用道具 举报

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
 楼主| 发表于 2019-9-25 08:36:36 | 显示全部楼层
高成 发表于 2019-9-23 16:35
按一次复位键发一次,之后就不发了。。

这个其实是根据原子哥的F429的HAL例程改得,
回复

使用道具 举报

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
 楼主| 发表于 2019-9-25 08:41:44 | 显示全部楼层
peng1554 发表于 2019-9-24 12:13
看能参考这个帖子不:
http://www.openedv.com/forum.php?mod=viewthread&tid=284146&extra=

好的,,,,,,
回复

使用道具 举报

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
 楼主| 发表于 2019-9-25 10:41:52 | 显示全部楼层
lidabenshili 发表于 2019-9-24 08:51
1、首先我觉得您使用的DMA发送函数可能不对,HAL_DMA_Start()此函数是内存到内存进行数据传输时使用的函数 ...

按你的提示去找问题果然找到原因了。从存储器到外设应该用你说的那个函数。
回复

使用道具 举报

8

主题

61

帖子

0

精华

高级会员

Rank: 4

积分
685
金钱
685
注册时间
2019-4-24
在线时间
43 小时
 楼主| 发表于 2019-9-25 11:07:23 | 显示全部楼层
peng1554 发表于 2019-9-24 12:13
看能参考这个帖子不:
http://www.openedv.com/forum.php?mod=viewthread&tid=284146&extra=

不错的帖子,
回复

使用道具 举报

2

主题

3

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2019-9-5
在线时间
12 小时
发表于 2019-11-3 01:07:45 | 显示全部楼层
发完后状态寄存器的发送完成标志要复位一下的
if(__HAL_DMA_GET_FLAG(&UART1TxDMA_Handler,DMA_FLAG_TCIF3_7))
//等待 DMA2_Steam7 传输完成
{
__HAL_DMA_CLEAR_FLAG(&UART1TxDMA_Handler,DMA_FLAG_TCIF3_7);
//清除 DMA2_Steam7 传输完成标志
HAL_UART_DMAStop(&UART1_Handler)//传输完成以后关闭串口 DMA
break;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-29 12:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表