STM32 UART常用的3种中断接收

本文介绍STM32微控制器USART模块的配置方法及三种不同的数据接收完成判断方式,包括缓冲区满标志位法、空闲中断法与状态机法。
#include "sys.h"
#include "usart.h"  
#include "main.h"


//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用  
#endif




//注意,读取USARTx->SR能避免莫名其妙的错误  
u8 USART1_RX_BUF[USART_RX_LEN];     //接收缓冲,最USART_RX_LEN个字节
u8 USART2_RX_BUF[USART_RX_LEN];      //接收缓冲,最USART_RX_LEN个字节
u8 USART1_TX_BUF[USART_TX_LEN]; //发送缓冲,最大USART_TX_LEN个字节
u8 USART2_TX_BUF[USART_TX_LEN]; //发送缓冲,最大USART_TX_LEN个字节
u8 USART1_RX_STA;       //接收完成状态标记  
u8 USART2_RX_STA;       //接收完成状态标记
u8 USART3_RX_STA;       //接收完成状态标记
//u8 USART1_Count = 0; //USART1接收计数器
//u8 USART2_Count = 0; //USART2接收计数器
u8 TX1_cn,TX1_no,RX1_cn,RX_no;
u8 TX2_cn,TX2_no,RX2_cn,RX2_no;
u8 u8Uart2_FSM;


void usart1_init(u32 baud)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;


/* 第1步:打开GPIO和USART部件的时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);


/* 第2步:将USART Tx的GPIO配置为推挽复用模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);


/* 第3步:将USART Rx的GPIO配置为浮空输入模式
由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的
但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*  第3步已经做了,因此这步可以不做
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 第4步:配置USART参数
   - 波特率   = 115200 baud
   - 数据长度 = 8 Bits
   - 1个停止位
   - 无校验
   - 禁止硬件流控(即禁止RTS和CTS)
   - 使能接收和发送
*/
USART_InitStructure.USART_BaudRate = baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);  
//  //Usart1 NVIC 配置
//  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
// NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
    
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  /* 第5步:使能 USART, 配置完毕 */
USART_Cmd(USART1, ENABLE);
// CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去
// 如下语句解决第1个字节无法正确发送出去的问题:
// 清发送完成标志,Transmission Complete flag 
USART_ClearFlag(USART1, USART_FLAG_TC); 
}




/*************************************************************************************************************************
* 函数 : void uart2_init(u32 baud) 
* 功能 : USART2做RS485接口使用,
* 参数 : 输入的波特率
* 返回 :
* 依赖 : 底层库函数
* 作者 : li_qcxy@126.com
* 时间 : 2016-12-9
* 最后修改时间 : 
* 说明 : PA1为接收发送使能脚
*************************************************************************************************************************/ 
void usart2_init(u32 baud)     //485通信串口初始化
{
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART2,GPIOA时钟
  
//USART2_TX   GPIOA.2
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2
   
  //USART2_RX  GPIOA.3初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3  

//USART2_RX_EN 使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA1
EN_USART2_RX(); //接收模式

  //Usart2 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  
  //USART 初始化设置
USART_InitStructure.USART_BaudRate = baud;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式


  USART_Init(USART2, &USART_InitStructure); //初始化串口2
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART2, ENABLE);                    //使能串口2 
  USART2 -> CR1 = USART2 -> CR1;
}






//获取USART2当前接收计数器值
u32 UARTx_GetRxCnt(void)
{
return TX2_no;
}


/*************************************************************************************************************************
* 函数 : void USART1_IRQHandler(void) 
* 功能 : 采用缓冲区满标志位的方法判断数据接收完成
* 参数 :
* 返回 :
* 依赖 : 底层读写函数
* 作者 : li_qcxy@126.com
* 时间 : 2016-12-8
* 最后修改时间 : 
* 说明 :
*************************************************************************************************************************/
void USART1_IRQHandler(void)                 //串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();    
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
    USART1_RX_BUF[TX2_no++]=Res; 
     } 
else if(TX2_no == USART_RX_LEN) //接收缓冲区接收满,即接收完成
{
TX2_no = 0;
USART1_RX_STA = 1;
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();    
#endif
}
/*************************************************************************************************************************
* 函数 : void USART2_IRQHandler(void) 
* 功能 : 采用空闲中断的方法判断数据接收完成
* 参数 :
* 返回 :
* 依赖 : 底层读写函数
* 作者 : li_qcxy@126.com
* 时间 : 2016-12-8
* 最后修改时间 : 
* 说明 :
*************************************************************************************************************************/
void USART3_IRQHandler(void)                 //串口2中断服务程序
{  
  u8 Res;
 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
    Res =USART_ReceiveData(USART2);//(USART2->DR); //读取接收到的数据
  USART2_RX_BUF[TX2_no++]=Res;
}
else if((USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)) //使用空闲中断判断接收不定长数据完成
{  
USART3_RX_STA = 1; //数据接收完成标志位
//
}
}


/*************************************************************************************************************************
* 函数 : void USART2_IRQHandler(void) 
* 功能 : 采用状态机的方法判断数据接收完成
* 参数 :
* 返回 :
* 依赖 : 底层读写函数
* 作者 : li_qcxy@126.com
* 时间 : 2016-12-8
* 最后修改时间 : 
* 说明 :
*************************************************************************************************************************/
void USART2_IRQHandler(void)             
{
 u8 u8Temp;
 /*****************发送中断************************************/
 if (USART_GetITStatus(USART2, USART_IT_TC) == SET)
 { 
  if(TX2_cn >= (TX2_no))
  {
  EN_USART2_TX();
  USART_ITConfig(USART2, USART_IT_TC, DISABLE);
   USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
   u8Uart2_FSM = U_FSM_ADR;
  }
  else
  {
  u8Temp = USART2_TX_BUF[TX2_cn++];
  USART2->DR = (u16)u8Temp;
  }
 }
 
 /******************接收中断*************************************/
 if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
 {
  u8Temp = (u8)USART2->DR;
  switch(u8Uart2_FSM)
  {
   case U_FSM_ADR:
   {
    if(u8Temp == local_info.id)  //本地地址
    {
     USART2_RX_BUF[0] = u8Temp;
     u8Uart2_FSM = U_FSM_FUN;
    }
break;
   }
   case U_FSM_FUN:
   {
    if((u8Temp == 0x05)||(u8Temp == 0x01)||(u8Temp == 0x03)||(u8Temp == 0x04)) //本单元值接受0x05和0x01的指令,遥信和遥控
    {
     USART2_RX_BUF[1] = u8Temp;
     u8Uart2_FSM = U_FSM_DATA;
     RX2_no = 8; 
     RX2_cn = 2;
    }
else if(u8Temp == 0x10)
{
USART2_RX_BUF[1] = u8Temp;
     u8Uart2_FSM = U_FSM_FUN16;
//     RX2_no = 15; 
     RX2_cn = 2;
}
    else
{
     u8Uart2_FSM = U_FSM_ADR;
}
break;
}
case U_FSM_FUN16:
{
USART2_RX_BUF[RX2_cn++] = u8Temp;
if(RX2_cn == 6)
{
USART2_RX_BUF[6] = u8Temp;
u8Uart2_FSM = U_FSM_DATA16;
RX2_cn = 7;
RX2_no = 9 + USART2_RX_BUF[6];
}
// else
// {
// USART2_RX_BUF[RX2_cn++] = u8Temp;
// }
break;
}
   case U_FSM_DATA:
   {
    USART2_RX_BUF[RX2_cn++] = u8Temp;
    if(RX2_no <= RX2_cn)                 //数据接收完毕
   
    u8Uart2_FSM = U_FSM_ADR;  
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);  //一帧数据收完,不再接受数据
    USART2_RX_STA = 1;//置一帧数据接收完标志
//   GPIOA->ODR |= GPIO_Pin_8;
//   GPIO_SetBits(GPIOA,GPIO_Pin_11); 
    }
  break; 
   }
case U_FSM_DATA16:
{
USART2_RX_BUF[RX2_cn++] = u8Temp;
    if(RX2_no <= RX2_cn)                 //数据接收完毕
   
    u8Uart2_FSM = U_FSM_ADR;  
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);  //一帧数据收完,不再接受数据
    USART2_RX_STA = 1;//置一帧数据接收完标志
}
   break;
   }
default:{u8Uart2_FSM = U_FSM_ADR; break;}
  }
 } 
}



<think>首先,用户的问题是:“我想查找使用CubeMX配置串口空闲中断的方法 请问使用CubeMX配置串口空闲中断的详细步骤”。用户指定了参考站内引用,但系统指令说“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答”。 回顾用户上一次的问题:在系统指令中,用户提供了一个示例,但那是示例,不是真实对话。在用户可见层,用户直接给出了这个引用列表和当前问题。用户上一次的消息是提供引用和当前问题,所以没有历史对话。因此,我需要专注于当前问题。 系统指令的关键点: - 所有行内数学表达式必须使用 $...$。 - 独立公式使用 $$...$$。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 用户的问题是关于使用CubeMX配置串口空闲中断的详细步骤。参考引用中提到了相关内容: - 引用[1]、[3]、[4]、[5]都讨论了UART空闲中断,尤其是结合DMA。 - 引用[4]具体描述了空闲中断的概念:当一帧数据接收完成时,串口进入空闲中断。 - 引用[5]给出了配置步骤。 基于这些引用,我需要提供一个清晰的、逐步的指南。 结构回答: 1. **介绍**:简要说明什么是串口空闲中断和其用途。 2. **详细步骤**:使用CubeMX配置串口空闲中断的步骤。 3. **代码部分**:如果需要,添加一个代码块展示关键代码。 4. **相关问题**:生成相关问题。 确保使用中文回答。 详细步骤(基于引用): - 引用[5]提到步骤:选择芯片、配置RCC时钟、配置下载方式、配置串口模式为异步、配置串口参数、使能中断、使能DMA。 - 引用[3]提到在CubeMX界面新建项目。 - 引用[4]描述空闲中断的好处:处理不定长数据帧。 步骤细化: 1. 创建CubeMX工程。 2. 选择芯片型号。 3. 配置系统时钟(RCC)。 4. 配置串口: - 选择UART接口。 - 设置模式为异步(Asynchronous)。 - 配置波特率、数据位等参数。 5. 使能串口全局中断。 6. 配置空闲中断:通常在CubeMX的NVIC设置中使能UART中断。 7. 如果需要DMA,配置DMA通道。 8. 生成代码。 9. 在代码中添加中断处理函数。 引用标识:在回答中,自然地添加引用到末尾。 生成相关问题:根据主题,提出相关问题。 最终回答结构: - 解释串口空闲中断。 - 步骤列表。 - 可能的代码示例(基于引用)。 - 相关问题列表。 </think>### CubeMX配置串口空闲中断的详细步骤 串口空闲中断UART Idle Interrupt)是一种高效处理不定长数据帧的方法,特别适合嵌入式系统中的串口通信。当UART接收线在一段时间内无数据变化(即空闲状态)时,会触发中断,表示一帧数据接收完成。这种方式避免了频繁的单个字节中断处理,简化了代码逻辑并提高了系统效率(尤其适合STM32系列单片机)[^4]。下面我将基于STM32CubeMX工具,详细说明配置步骤。整个过程以STM32F系列为例(如F103或F407),但步骤通用,适用于大多数STM32芯片。配置分为**CubeMX图形界面配置**和**代码添加**两部分。 --- ### 一、CubeMX图形界面配置步骤 以下是使用STM32CubeMX配置串口空闲中断的详细步骤。确保您已安装CubeMX软件并创建了项目工程(参考[^3])。步骤基于引用内容整合,重点关注空闲中断使能和必要的外设设置。 1. **创建新工程并选择芯片型号** - 打开CubeMX,点击“File” > “New Project”。 - 在芯片选择器中选择您的型号,例如STM32F103RCT6或STM32F407ZG(参考[^3][^5])。 - 点击“Start Project”确认。 2. **配置系统时钟(RCC)** - 在“Pinout & Configuration”标签页,左侧导航栏选择“System Core” > “RCC”。 - 启用外部晶振:在“High Speed Clock (HSE)”中选择“Crystal/Ceramic Resonator”(确保硬件连接外部晶振)。 - 配置时钟树:点击“Clock Configuration”标签页,设置系统时钟源为HSE,并调整分频器使主频达到所需值(如72MHz for F103)。这一步确保UART时钟正常工作(参考[^2][^5])。 3. **配置串口接口** - 在“Pinout & Configuration”标签页,左侧选择“Connectivity” > “USARTx”(x根据您的硬件选择,如USART1)。 - 设置模式: - Mode: 选择“Asynchronous”(异步模式)。 - Basic Parameters: 配置波特率(如115200 Bits/s)、数据位(8-bit)、停止位(1-bit)和校验位(None)。这些参数需与通信设备匹配(参考[^1][^2])。 - 使能NVIC中断: - 在USARTx配置窗口,切换到“NVIC Settings”子标签页。 - 勾选“USARTx global interrupt”以启用中断。**关键步骤:空闲中断在CubeMX中不是独立选项,需通过全局中断使能,并在代码中手动开启空闲中断标志(后续代码部分解释)**(参考[^4][^5])。 4. **配置DMA(可选但推荐)** - 空闲中断常结合DMA接收数据以提高效率(避免CPU频繁干预)。在“DMA Settings”子标签页: - 添加一个新通道:点击“Add”,选择“USARTx_RX”。 - DMA Request Settings: Mode 设置为“Circular”(循环模式),Priority 为“Medium”。 - 数据长度:设置“Data Width”为“Byte”(根据数据帧类型)。 - **注意**:DMA不是必需的,但推荐用于大数据量场景;如果仅用空闲中断,可跳过此步(参考[^1][^5])。 5. **配置下载方式和引脚分配** - System Core > SYS: 设置调试接口,如“Serial Wire”(用于ST-Link烧录)。 - 引脚自动分配:CubeMX会根据配置自动分配UART引脚(如PA9为TX,PA10为RX)。检查“Pinout View”确保无冲突。 6. **生成工程代码** - 点击“Project Manager”标签页: - 设置工程名称和位置。 - 选择IDE(如MDK-ARM for Keil)。 - 在“Code Generator”中,勾选“Generate peripheral initialization as a pair of .c/.h files”以生成模块化代码。 - 最后点击“GENERATE CODE”生成代码框架(参考[^3][^5])。 --- ### 二、代码添加步骤 CubeMX生成代码后,您需要在Keil或其他IDE中手动添加中断处理逻辑。以下是关键代码部分,基于引用内容简化(适用于HAL库)。 1. **初始化串口空闲中断** - 在生成的工程中,打开 `main.c` 文件。在 `MX_USARTx_UART_Init()` 函数后添加空闲中断使能代码: ```c // 在初始化函数后添加 void MX_USARTx_UART_Init(void) { // ... CubeMX生成的代码 ... } // 手动开启空闲中断 __HAL_UART_ENABLE_IT(&huartx, UART_IT_IDLE); // 使能空闲中断,huartx 是您的UART句柄 HAL_UART_Receive_DMA(&huartx, rx_buffer, BUFFER_SIZE); // 如果需要DMA,启动DMA接收 ``` 此处: - `huartx` 是CubeMX生成的UART句柄(如 `huart1`)。 - `rx_buffer` 是自定义接收缓冲区数组(如 `uint8_t rx_buffer[100]`)。 - `BUFFER_SIZE` 是缓冲区大小(参考[^4][^5])。 2. **添加中断回调函数** - 在 `stm32xx_it.c` 文件中,找到UART中断服务函数(如 `USARTx_IRQHandler()`)。 - 修改它以处理空闲中断: ```c void USARTx_IRQHandler(void) { HAL_UART_IRQHandler(&huartx); // 调用HAL库默认处理 // 检查空闲中断标志 if (__HAL_UART_GET_FLAG(&huartx, UART_FLAG_IDLE) != RESET) { __HAL_UART_CLEAR_IDLEFLAG(&huartx); // 清除空闲中断标志 // 处理接收完成的数据 HAL_UART_DMAStop(&huartx); // 停止DMA(如果使用) uint16_t data_length = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huartx.hdmarx); // 计算接收数据长度 // 调用自定义处理函数,例如 process_data(rx_buffer, data_length); } } ``` 说明: - 空闲中断触发后,需手动清除标志位。 - 使用 `__HAL_DMA_GET_COUNTER` 获取剩余字节数,计算实际接收长度(参考[^1][^4])。 - 添加自定义函数(如 `process_data`)处理接收到的数据帧。 3. **示例:完整接收流程** - 在 `main.c` 中添加接收缓冲区和处理函数: ```c uint8_t rx_buffer[100]; // 定义缓冲区 void process_data(uint8_t *data, uint16_t length) { // 处理收到的数据,如串口回显或解析 HAL_UART_Transmit(&huartx, data, length, 100); // 示例:回传数据 HAL_UART_Receive_DMA(&huartx, rx_buffer, 100); // 重新启动DMA接收 } // 在main()中初始化后启动接收 int main(void) { HAL_Init(); SystemClock_Config(); MX_USARTx_UART_Init(); HAL_UART_Receive_DMA(&huartx, rx_buffer, 100); // 初始化DMA接收 while (1) { // 主循环 } } ``` **注意事项**: - **可靠性**:空闲中断在通信可靠时高效,但如果数据帧错误(如噪声干扰),可能导致误判(参考[^4])。 - **性能提示**:对小数据帧,空闲中断即可;对大数据量,务必启用DMA以避免CPU瓶颈(参考[^3][^5])。 - **Debug**:编译下载后,使用串口调试助手测试:发送不定长数据,观察是否在空闲时触发中断。 通过以上步骤,您能高效实现STM32的串口空闲中断接收。配置成功率较高,但需确保硬件连接正确(如UART引脚)[^1][^5]。 --- ### 相关问题 1. 如何处理串口空闲中断中的数据帧解析错误?[^4] 2. 如何在CubeMX中配置多串口空闲中断(例如USART1和USART2同时使用)?(参考[^2]) 3. 空闲中断与DMA结合时,如何优化内存使用以防止缓冲区溢出?(参考[^1][^5]) [^1]: STM32HAL库CubeMx——UART DMA串口空闲中断的使用 [^2]: 串口是常用的设备与设备之间发送和接受信息的工具... [^3]: 用CubeMX生成F103芯片-串口+空闲中断、串口+DMA+空闲中断... [^4]: STM32CubeMX—串口空闲中断+DMA接收... [^5]: CubeMx配置生成代码系列(一)串口+空闲中断+DMA接收数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值