硬汉嵌入式论坛

 找回密码
 立即注册
查看: 12526|回复: 6
收起左侧

[NUCLEO-H743ZI] 【STM32H743实验例程】实验13:STM32H743串口中断方式收发

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2018-4-17 01:49:51 | 显示全部楼层 |阅读模式
实验介绍
开发平台:官方STM32H743 NUCLEO板子
开发环境:MDK5.25正式版
软件版本:
(1)CMSIS软件包 V5.3.0
(2)H7的HAL库版本 V1.2.0

例程下载: 实验13:STM32H743串口中断方式.7z (1.08 MB, 下载次数: 1215)



  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: main
  4. *        功能说明: 标准c程序入口。
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main(void)
  10. {        
  11.         uint8_t ucKeyCode;                      /* 按键代码 */
  12.         
  13.         
  14.         bsp_Init(); /* 外设初始化 */
  15.   
  16.         bsp_StartAutoTimer(0, 100);        /* 启动1个100ms的自动重装的定时器 */        

  17.         HAL_UART_Receive_IT(&UartHandle, s_ucBuf, 1);        
  18.         
  19.         while (1)
  20.         {
  21.                 bsp_Idle();                         /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */

  22.                 if (bsp_CheckTimer(0))        /* 判断定时器超时时间 */
  23.                 {
  24.                         /* 每隔100ms 进来一次 */
  25.                         bsp_LedToggle(1);                        
  26.                 }
  27.                
  28.                 if(g_ucRecieveFlag == 1)
  29.                 {
  30.                         g_ucRecieveFlag = 0;
  31.                         bsp_LedToggle(3);
  32.                         
  33.                         /* 设置新的接收,并将接收到发送回去 */
  34.                         HAL_UART_Receive_IT(&UartHandle, s_ucBuf, 1);        
  35.                         HAL_UART_Transmit_IT(&UartHandle, s_ucBuf, 1);
  36.                 }
  37.                
  38.                 /* 按键滤波和检测由后台systick中断服务程序实现,我们只需要调用bsp_GetKey读取键值即可。 */
  39.                 ucKeyCode = bsp_GetKey();        /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
  40.                 if (ucKeyCode != KEY_NONE)
  41.                 {
  42.                         switch (ucKeyCode)
  43.                         {
  44.                                 case KEY_DOWN_K1:                      /* K1键按下 */
  45.                                         HAL_UART_Transmit_IT(&UartHandle, (uint8_t*)"KEY_DOWN_K1\r\n", 13);
  46.                                         bsp_LedToggle(2);
  47.                                         break;

  48.                                 case KEY_UP_K1:                            /* K1键弹起 */
  49.                                         bsp_LedToggle(2);
  50.                                         break;

  51.                                 case KEY_LONG_K1:                        /* K1长按   */
  52.                                         printf("K1按键长按\r\n");
  53.                                         break;

  54.                                 default:
  55.                                         /* 其它的键值不处理 */
  56.                                         break;
  57.                         }
  58.                 }
  59.         }
  60. }
复制代码


回复

使用道具 举报

2

主题

134

回帖

140

积分

初级会员

积分
140
发表于 2018-4-18 15:33:45 | 显示全部楼层
硬汉大哥  为什么不使用空闲中断接收呢  空闲中断可以接收不定长的数据  而且可以大大减少进入中断的次数  我使用串口的DMA空闲中断去接收数据感觉还可以  可以大大降低MCU使用率
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2018-4-18 15:36:00 | 显示全部楼层
hanzixiangel 发表于 2018-4-18 15:33
硬汉大哥  为什么不使用空闲中断接收呢  空闲中断可以接收不定长的数据  而且可以大大减少进入中断的次数   ...

H7的HAL库不支持,不愿去研究他了。平时中断方式用习惯了,挺好用也稳定。
回复

使用道具 举报

2

主题

134

回帖

140

积分

初级会员

积分
140
发表于 2018-4-18 15:55:29 | 显示全部楼层
hal库的串口中断里面确实没有写如空闲中断  但是hal库预留了接口  自己手动启用  自己写个空闲回掉函数  

以下是我的代码 F030的  增加了防溢出的功能  请硬汉大哥评断

/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)
  {
          HAL_UART_RxIdleCallback(&huart1);
  }
  /* USER CODE END USART1_IRQn 1 */
}


/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
        HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
        if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET)
        {
          HAL_UART_RxIdleCallback(&huart2);
        }
  /* USER CODE END USART2_IRQn 1 */
}


/*********************************************************************************************************
**  @FunctionName               HAL_UART_RxCpltCallback
**  @Description                串口接收完成中断回调函数
**  @InputParam                 huart:     串口句柄
**  @OutputParam                NONE
**  @ReturnValue                NONE
**
*********************************************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        uint8_t i = 0;
        uint8_t len = 0;

        if(huart->Instance == USART1)
        {

                len = UART1_REV_LEN - huart->hdmarx->Instance->CNDTR;

                for(i=0; i<len; i++)
                {
                        Uart1_RevData.UartRevData[Usart1_RevLen+i] = Usart1RxBuffer[i];
                }
                Usart1_RevLen += len;
                HAL_UART_Receive_DMA(huart, Usart1RxBuffer, UART1_REV_LEN);

        }
        if(huart->Instance == USART2)
        {
                len = UART2_REV_LEN - huart->hdmarx->Instance->CNDTR;
                for(i=0; i<len; i++)
                {
                        Uart2_RevData.UartRevData[Usart2_RevLen+i] = Usart2RxBuffer[i];
                }
                Usart2_RevLen += len;
                HAL_UART_Receive_DMA(huart, Usart2RxBuffer, UART2_REV_LEN);
        }
}

/*********************************************************************************************************
**  @FunctionName               HAL_UART_RxIdleCallback
**  @Description                串口空闲中断回调函数
**  @InputParam                 huart:     串口句柄
**  @OutputParam                NONE
**  @ReturnValue                NONE
**
*********************************************************************************************************/
void HAL_UART_RxIdleCallback(UART_HandleTypeDef *huart)
{
        uint8_t i = 0;
        uint8_t len = 0;
        if(huart->Instance == USART1)
        {
                __HAL_UART_CLEAR_IDLEFLAG(huart);
                HAL_UART_DMAStop(huart);
                len = UART1_REV_LEN - huart->hdmarx->Instance->CNDTR;
                for(i=0; i<len; i++)
                {
                        Uart1_RevData.UartRevData[Usart1_RevLen+i] = Usart1RxBuffer[i];
                }
//                memcpy(&Uart1_RevData.UartRevData[Usart_RevLen], Usart1RxBuffer, len);
                Usart1_RevLen += len;
                Uart1_RevData.UartRevLen = Usart1_RevLen;
                if(osMessagePut(Queue_Usart1RevHandle, (uint32_t)&Uart1_RevData, 0) != osOK)
                {
                        printf("Q Send Err\r\n");
                }
//                printf("idle rev len:%d\r\n", len);
                Usart1_RevLen = 0;
                HAL_UART_Receive_DMA(huart, Usart1RxBuffer, UART1_REV_LEN);
        }
        if(huart->Instance ==  USART2)
        {
//                printf("uart2 idle it\r\n");
                __HAL_UART_CLEAR_IDLEFLAG(huart);
                HAL_UART_DMAStop(huart);
                len = UART2_REV_LEN - huart->hdmarx->Instance->CNDTR;
                for(i=0; i<len; i++)
                {
                        Uart2_RevData.UartRevData[Usart2_RevLen+i] = Usart2RxBuffer[i];
                }
                Usart2_RevLen += len;
                Uart2_RevData.UartRevLen = Usart2_RevLen;
                if(osMessagePut(Queue_Usart2RevHandle, (uint32_t)&Uart2_RevData, 0) != osOK)
                {
                        printf("Q Send Err\r\n");
                }
                Usart2_RevLen = 0;
                HAL_UART_Receive_DMA(huart, Usart2RxBuffer, UART2_REV_LEN);
        }
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2018-4-18 16:08:46 | 显示全部楼层
hanzixiangel 发表于 2018-4-18 15:55
hal库的串口中断里面确实没有写如空闲中断  但是hal库预留了接口  自己手动启用  自己写个空闲回掉函数  
...

非常感谢提供的代码

现在搞下串口主要是熟悉下他们的HAL库工作套路,后面ADC,DAC是我想搞的
回复

使用道具 举报

2

主题

134

回帖

140

积分

初级会员

积分
140
发表于 2018-4-18 16:12:13 | 显示全部楼层
eric2013 发表于 2018-4-18 16:08
非常感谢提供的代码

现在搞下串口主要是熟悉下他们的HAL库工作套路,后面ADC,DAC是我想搞的

搞过F429hal库的DMA ADC多通道采集  循环模式  效果还不错
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
 楼主| 发表于 2018-4-18 16:14:46 | 显示全部楼层
hanzixiangel 发表于 2018-4-18 16:12
搞过F429hal库的DMA ADC多通道采集  循环模式  效果还不错

F429的已经在我们V6开发板的二代示波器里面搞的比较透彻了,不过我们只用标准库。现在主要是看下H7的16位ADC的性能。

http://www.armbbs.cn/forum.ph ... 5785&extra=page%3D1
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 07:49 , Processed in 0.193366 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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