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

【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分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版