你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32F769I-DISC1】测评02:调试串口1与PC通讯功能

[复制链接]
〃聪聪哥哥 发布时间:2025-3-12 21:31

由于收到的STM32f 769板卡,没有LCD的屏幕,所以这里我调试一下,STM32F769的串口输出功能,完成单片机与PC端的交互,在没有屏幕的情况下,完成数据的输出显示功能。

一:串口的相关知识:

STM32F769 是一款高性能的微控制器,属于 STMicroelectronics 的 STM32F7 系列。它集成了多个串口(USART/UART),支持多种通信协议和功能。以下是关于 STM32F769 串口的一些关键知识点: 1. 串口类型 USART (Universal Synchronous/Asynchronous Receiver/Transmitter): 支持同步和异步通信。 UART (Universal Asynchronous Receiver/Transmitter): 仅支持异步通信。 2. 主要特性 波特率: 可编程的波特率发生器,支持多种波特率。 数据帧格式: 可配置的数据位(8 或 9 位)、停止位(1、1.5 或 2 位)和校验位(无、偶校验、奇校验)。 硬件流控制: 支持 RTS(Request to Send)和 CTS(Clear to Send)信号,用于硬件流控制。 DMA 支持: 支持 DMA(直接内存访问),用于高效的数据传输。 中断: 支持多种中断源,如发送完成、接收完成、帧错误、溢出错误等。 多处理器通信: 支持多处理器通信模式。 LIN 模式: 支持 LIN(Local Interconnect Network)协议。 IrDA 模式: 支持 IrDA(Infrared Data Association)协议。 SmartCard 模式: 支持智能卡协议(ISO 7816-3)。 3. 寄存器 USART_CR1/CR2/CR3: 控制寄存器,用于配置串口的工作模式、中断使能、数据帧格式等。 USART_BRR: 波特率寄存器,用于设置波特率。 USART_SR: 状态寄存器,用于读取串口的状态(如发送完成、接收完成、错误标志等)。 USART_DR: 数据寄存器,用于发送和接收数据。 4. 波特率计算 波特率的计算公式为: Baud Rate=fCK/16×USARTDIVBaud Rate=16×USARTDIVf

其中,fCKfCK 是串口的时钟频率,USARTDIV 是波特率寄存器(USART_BRR)中的值。 5. 初始化步骤 5.1:程序开始运行时,调用 HAL_Init() 函数来重置所有外围设备, 5.2 初始化 Flash 接口和系统, 5.3 调用SystemClock_Config() 配置CPU主频为 216MHz 运行。 5.4 初始化串口的外设部分 5.5 编写串口的通讯部分

二:cube MX 软件配置的过程

2.1 :硬件连接方式::

查看一下ST-link的串口引脚,

2.png

确定一下该引脚连接到F769的何处引脚:

3.png

这里说一个避坑的经验:我们在查看的引脚对应的时候,需要看下引脚处的标识,不要去看黑色的标识,这里应该是封装的不同导致的。

2.2 为了使串口可以到达最佳的性能,这里我是用DMA与串口中断的方式接收不定长的数据,同时使能的DMA发送功能。软件配置图如下所示:

4.png

系统时钟树的配置如下所示:

5.png

这里对串口知识简单分享一下

在STM32的串口通讯模式中,我个人的理解是,阻塞方式,非阻塞方式和DMA发送,共计三种不同的的通讯方式,在HAL库中相关的函数代码如下:

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
#if defined(HAL_DMA_MODULE_ENABLED)
HAL_
StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

我在工作实际使用中,在代码量不大,要求不高的情况下,一般使用阻塞式的发送和中断方式接收,即HAL_UART_Transmit 和HAL_UART_Receive_IT的方式,实现CPU与外设的交互。 这种通讯方式比较简单,串口每接收到一个字节单片机就会进入一次串口的中断,我们在接收的过程中,只需要判断一下接收到数据的有效性,然后放入决定是否放到接收数据组。这种接收方式是最简单的,但是换来却是单片机需要频繁的进入中断,这样代码大的情况下,根据中断优先级的不同,可能会导致项目中某些程序被打断的情况出现。 使用DMA的接收方式可以实现内存与外设之间的数据直接传输,可以为CPU分担一些工作量,从而为CPU减轻负担,增加数据的传输处理速度。 这里重点的和大家分享一下串口DMA发送函数的使用技巧:

(一)函数功能是CPU以DAM模式发送 *pData指针指向的数据中固定长度的数据,并同时设置和使能DMA中断。 我们从代码中不难发现,DMA中断函数最终使用的居然是串口的中断函数。 进入到HAL_UART_Transmit_DMA这个函数中可以看到,它将DMA传输完成、半完成、错误的回调函数分别定向到了串口DMA传输完成、半完成、错误的回调函数 我们在DMA的函数中发现 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma),打开函数功能的内部其实就是串口的发送完成中断函数 HAL_UART_TxCpltCallback(huart);可见即使使用DMA的发送方式,最后还是需要串口的发送完成中断函数相联系。

(二)串口的DMA接收

HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

(三)串口DMA的停止函数

HAL_UART_DMAStop(huart);

我们在进入DMA中断中,需要关闭该函数,这个时候DMA中就不能打开DMA的接收,需要等待数据处理完毕,在进行DMA的接收

(四)查询DMA中有效的数据个数

__HAL_DMA_GET_COUNTER(&hdma_usart2_rx)  

在宏定义中我们不难发现,其实就是读取CNDTR寄存器内的数值。这个寄存器存储的是DMA传输的剩余传输数量。在接收数据时,用定义的最大传输数量减去这个剩余数量就是已经接收的数据个数。在发送数据时,用定义的最大传输数量减去这个剩余数量就是已经发送的数据个数。

三:编写代码如下所示:

3.1 在串口初始化钟使能串口接收功能:

  /* USER CODE BEGIN USART1_Init 2 */
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);    //IDLE interrupt

    //��DMA���գ�ָ�����ջ������ͽ��մ�С
    HAL_UART_Receive_DMA(&huart1, (uint8_t *)&RecBuffer1, reclength1);
  /* USER CODE END USART1_Init 2 */

3.2 编写空闲中断的函数处理部分:

基本编写步骤:

1:首先需要清楚空闲中断标志,以便再次进入该串口空闲中断,

2:停止DMA的接收,防止计算长度时候出错

3:计算一下DMA数据中有效数据

4:将有效数据拷贝至其他的定义的数据内,以便程序处理

5:将接收完一包有效数据的标志位置位,同时需要再次开启DMA接收,

void UsartReceive_IDLE(UART_HandleTypeDef *huart) 
{
    //???????????????��?
  if((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET)) 
    {

             if(huart->Instance == USART1)
                {
                    /* 1.?????? */
                    __HAL_UART_CLEAR_IDLEFLAG(huart);   //??????��??
                    /* 2.???DMA */
                    HAL_UART_DMAStop(huart);            //????DMA?????????
                    /* 3.??????????????????? */
                    usart1_rx_len = reclength1 - (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)); //??????????????????????��?????????????
                    memcpy(Usart1_DEAL_RX_Buf, RecBuffer1, usart1_rx_len);
                    usart1_flag = 1;
                    /* 4.?????��????DMA???? */
                    HAL_UART_Receive_DMA(&huart1, (uint8_t *)&RecBuffer1, reclength1);
                }
}

四:实物验证:

        if(usart1_flag == 1)
        {
            usart1_flag = 0 ;
            HAL_UART_Transmit(&huart1,Usart1_DEAL_RX_Buf,usart1_rx_len,100);
            printf("Hello STM32! Hello congcong! Hello STM32f769!\r\n");
        }

6.png

如上图所示:电脑发送固定字节,串口接收到一组数据后,将数据原路返回,同时使用printf函数发送数据。

串口使用DMA加空闲中断接收数据,原路返回功能,同时使用printf函数输出数据功能,调试完毕,接下来可以对其他外设调试。

收藏 评论0 发布时间:2025-3-12 21:31

举报

0个回答

所属标签

ST中文论坛活动

即日起开启活动话题入口,之后的活动统一都放在此处,欢迎大家的加入!


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版