OpenEdv-开源电子网

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

MDK5.14的DMA发送完成回调函数

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2015-5-9
在线时间
1 小时
发表于 2015-5-9 19:43:10 | 显示全部楼层 |阅读模式
5金钱
本人在用STM32F103RE的UART4做485的半双工通信中,因为要每次DMA发送指定的字节数后马上转为接收状态,所以需要用到DMA发送完成回调函数。可是我就是无法让程序调用回调函数。请问怎么打开接收完成中断。
(注:接收完成回调函数是可以进入的。)
本人刚使用不久的MDK5.14,很不熟练,也没用过以前的库函数(见笑了),望指教。谢谢


void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==UART4)
  {
  /* USER CODE BEGIN UART4_MspInit 0 */

  /* USER CODE END UART4_MspInit 0 */
    /* Peripheral clock enable */
    __UART4_CLK_ENABLE();
 
    /**UART4 GPIO Configuration   
    PC10     ------> UART4_TX
    PC11     ------> UART4_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* Peripheral DMA init*/
 
    hdma_uart4_rx.Instance = DMA2_Channel3;
    hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_uart4_rx.Init.Mode = DMA_NORMAL;
    hdma_uart4_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
    HAL_DMA_Init(&hdma_uart4_rx);

    __HAL_LINKDMA(huart,hdmarx,hdma_uart4_rx);

    hdma_uart4_tx.Instance = DMA2_Channel5;
    hdma_uart4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_uart4_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_uart4_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_uart4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_uart4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_uart4_tx.Init.Mode = DMA_NORMAL;
    hdma_uart4_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
    HAL_DMA_Init(&hdma_uart4_tx);

    __HAL_LINKDMA(huart,hdmatx,hdma_uart4_tx);

  /* USER CODE BEGIN UART4_MspInit 1 */

  /* USER CODE END UART4_MspInit 1 */
  }
  else if(huart->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */

  /* USER CODE END USART2_MspInit 0 */
    /* Peripheral clock enable */
    __USART2_CLK_ENABLE();
 
    /**USART2 GPIO Configuration   
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral DMA init*/
 
    hdma_usart2_rx.Instance = DMA1_Channel6;
    hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
    hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
    HAL_DMA_Init(&hdma_usart2_rx);

    __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);

    hdma_usart2_tx.Instance = DMA1_Channel7;
    hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart2_tx.Init.Mode = DMA_NORMAL;
    hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
    HAL_DMA_Init(&hdma_usart2_tx);

    __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);

  /* USER CODE BEGIN USART2_MspInit 1 */

  /* USER CODE END USART2_MspInit 1 */
  }
}

void MX_UART4_Init(void)
{

  huart4.Instance = UART4;
  huart4.Init.BaudRate = 115200;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart4);

}
/* USART2 init function */

void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);

}




下面的程序,是我写的。。刚学MDK5.14,不好意思


/************************************************************************************
打开串口初始化后发送数据
------------------------------------------------------------------------------------*/
void UartSendToExtModule(void)  //打开串口初始化后发送数据
{
  ExtModuleTxBUF[0] =0x90;  //组织发送的数据
  ExtModuleTxBUF[1] =0xab;
  ExtModuleTxBUF[2] =0xcd;
  ExtModuleTxBUF[3] =0xef;
 
 
  HAL_GPIO_WritePin(Uart_ExtModule_DE, GPIO_PIN_SET);  //置485为发送模式
 
  HAL_NVIC_SetPriority(DMA2_Channel3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Channel3_IRQn);
  MX_UART4_Init();
  HAL_UART_Transmit_DMA(&huart4, (uint8_t*)ExtModuleTxBUF, ExtModule_TXSIZE);
}
/************************************************************************************
打开串口初始化接收数据
------------------------------------------------------------------------------------*/
void UartRcvFromExtModule(void)  //打开串口初始化接收数据
{
 
  HAL_GPIO_WritePin(Uart_ExtModule_DE, GPIO_PIN_RESET);  //置485为接收模式
 
  HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
  MX_UART4_Init();
  HAL_UART_Receive_DMA(&huart4, (uint8_t*)ExtModuleRxBUF, ExtModule_RXSIZE);
}

/************************************************************************************
串口发送完成回调函数
------------------------------------------------------------------------------------*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{

  if(huart->Instance == USART2 )
  { 

  }  
  else if(huart->Instance == UART4 )
  { //外部输入输出模块发送结束。
   
   UartRcvFromExtModule();    //打开串口初始化接收数据(从外部的输入输出模块)
   
  } 
  
 
 
 
}


最佳答案

查看完整内容[请看2#楼]

问题好像解决了。。 只有在循环模式下,才会调用void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) 将 hdma_uart4_tx.Init.Mode = DMA_NORMAL; 改为 hdma_uart4_tx.Init.Mode = DMA_CIRCULAR; 就好了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2015-5-9
在线时间
1 小时
 楼主| 发表于 2015-5-9 19:43:11 | 显示全部楼层
问题好像解决了。。

只有在循环模式下,才会调用void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

将 hdma_uart4_tx.Init.Mode = DMA_NORMAL;
改为
hdma_uart4_tx.Init.Mode = DMA_CIRCULAR;
就好了
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2015-5-9
在线时间
1 小时
 楼主| 发表于 2015-5-9 20:17:22 | 显示全部楼层
再说明一下:
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)

这个回调函数可以被调用。但这好像是发送一半的回调函数吧?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-5-9 22:26:50 | 显示全部楼层
帮顶。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

10

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1080
金钱
1080
注册时间
2019-7-5
在线时间
105 小时
发表于 2020-8-28 18:28:28 | 显示全部楼层
在用485,先mark~
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 20:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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