【STM32的空闲中断(Idle Interrupt)】

这篇具有很好参考价值的文章主要介绍了【STM32的空闲中断(Idle Interrupt)】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、空闲中断基本框架

STM32的空闲中断(Idle Interrupt)通常用于在CPU空闲时执行任务,例如在低功耗模式下减少功耗等。当CPU完成当前任务后,会进入空闲状态,此时会触发空闲中断。在空闲中断中,可以执行一些需要在CPU空闲时执行的任务,例如读取传感器数据、更新LCD显示等。

要使用STM32的空闲中断,需要进行以下步骤:

1.配置NVIC优先级:将空闲中断的优先级设置为较低的值。

2.启用空闲中断:在代码中启用空闲中断,并设置空闲中断的处理函数。

以下是使用STM32 HAL库实现空闲中断的简单示例代码:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  //串口接收中断回调函数
}

int main(void)
{
  HAL_Init(); //初始化HAL库

  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //启用空闲中断

  while (1)
  {
    //主程序逻辑
  }
}

void HAL_UART_IdleCallback(UART_HandleTypeDef *huart)
{
  //空闲中断处理函数
  //更新LCD显示、读取传感器数据等任务
}
 

以上代码中,当串口接收完成时,会触发串口接收中断回调函数
(HAL_UART_RxCpltCallback)
在主程序中,会一直循环执行,直到CPU进入空闲状态触发空闲中断。
空闲中断处理函数 (HAL_UART_IdleCallback),会在空闲中断触发时被调用,执行一些需要在CPU空闲时执行的任务。

二、空闲中断(接收/发送)循环缓冲区

本次的文章主要是记录学习超子老师的代码。
他的B站链接:https://space.bilibili.com/517828171?spm_id_from=333.337.0.0
stm32空闲中断,物联网,stm32,单片机,嵌入式硬件

1、 定义一个数据管理结构体,一个总的功能结构体

#define U1_TX_SIZE 2048
#define U1_RX_SIZE 2048
#define U1_RX_MAX  256

typedef struct{//记录数据的开始位置和结束位置
	uint8_t  *start;
	uint8_t  *end;
}LCB;

typedef struct{
	uint32_t  RxCounter;//记录存入缓冲区的数据量
	uint32_t  TxCounter;
	uint32_t  TxState;//发送状态
	LCB       RxLocation[10];
	LCB       TxLocation[10];
	LCB      *RxInPtr;
	LCB      *RxOutPtr;
	LCB      *RxEndPtr;
	
	LCB      *TxInPtr;
	LCB      *TxOutPtr;
	LCB      *TxEndPtr;
	UART_HandleTypeDef uart;
}UCB;

2、然后对这个缓冲区进行一个初始化的工作,这个函数需要在(MX_USART1_UART_Init)进行调用。并且缓冲区初始化函数已经开启了空闲中断,开启了中断接收。

void U1_PtrInit(void)//发送和接收缓冲区初始化函数
{
	uart1.RxInPtr = &uart1.RxLocation[0];//数据输入指针指向数据开始和结束位置管理数组的首地址
	uart1.RxOutPtr = &uart1.RxLocation[0];
	uart1.RxEndPtr = &uart1.RxLocation[9];//数据输入指针指向数据开始和结束位置管理数组的尾地址
	uart1.RxCounter = 0;//存储到缓冲区的数据量
	uart1.RxInPtr->start = U1_RxBuff;//让第一个数据开始指针指向缓冲区的首地址
	
	uart1.TxInPtr = &uart1.TxLocation[0];
	uart1.TxOutPtr = &uart1.TxLocation[0];
	uart1.TxEndPtr = &uart1.TxLocation[9];
	uart1.TxCounter = 0;
	uart1.TxInPtr->start = U1_TxBuff;	
	
	__HAL_UART_ENABLE_IT(&uart1.uart, UART_IT_IDLE);//开启空闲中断
	HAL_UART_Receive_IT(&uart1.uart,uart1.RxInPtr->start,U1_RX_MAX);//开始接收
}

3、假设,现在已经有数据接收了,那么我们需要实现串口中断函数(注意看代码里的注释)

void USART1_IRQHandler(void)//串口中断函数
{							//当串口中断发生后会进入到此函数,但是我们接收的数据小于RX_MAX,所以不会发生串口接收完成中断.
	HAL_UART_IRQHandler(&uart1.uart);
	//由于程序的规定是接收和发送小于256字节的数据,所以不会发生串口接收完成中断。如果接收到45个字节,那么我理论上是根据接收函数要接收256个,
	//但是接收不到256个字节,所以再接收到45个个字节之后,串口线就处于空闲状态,也就是这个时候,空闲中断就发生了,也就是进入到USART1_IRQHandler函数
	//由于HAL没有处理空闲中断的程序,所以我们需要模仿它处理接收完成中断的程序,实现一个处理空闲中断的程序
	if(__HAL_UART_GET_FLAG(&uart1.uart, UART_FLAG_IDLE)){//判断是否是这个中断发生
		__HAL_UART_CLEAR_IDLEFLAG(&uart1.uart);//清楚中断标志位
		uart1.RxCounter += (U1_RX_MAX - uart1.uart.RxXferCount);//通过uart1.uart.RxXferCount(这个值表示还有多少个字节需要接收)我们用U1_RX_MAX减去就能得到接收的字节数量
		HAL_UART_AbortReceive_IT(&uart1.uart);最后再调用终止接收中断函数
	}
}

4、实现中断回调函数

void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)//终止串口接收中断回调函数
{
	if(huart->Instance == USART1){
		uart1.RxInPtr->end = &U1_RxBuff[uart1.RxCounter - 1];//将数据结束处的地址赋值给uart1.RxInPtr->end
		uart1.RxInPtr++;
		if(uart1.RxInPtr == uart1.RxEndPtr){
			uart1.RxInPtr = &uart1.RxLocation[0];
		}
		if((U1_RX_SIZE - uart1.RxCounter)<U1_RX_MAX){//再判断缓冲区剩下的空间是否能存储下U1_RX_MAX字节,不能则回滚
			uart1.RxCounter = 0;
			uart1.RxInPtr->start = U1_RxBuff;
		}else{//可以放下就让下一个数据输入指针指向下一个可以存储的地址
			uart1.RxInPtr->start = &U1_RxBuff[uart1.RxCounter];
		}
		HAL_UART_Receive_IT(&uart1.uart,uart1.RxInPtr->start,U1_RX_MAX);//然后再次开启中断接收函数
	}
}

5、实现发送函数

void U1_Txdata(uint8_t *data, uint32_t data_len)//串口发送函数
{
	if((U1_TX_SIZE - uart1.TxCounter )>=data_len){//判断发送数据是否可以存放在缓冲区内
		uart1.TxInPtr->start = &U1_TxBuff[uart1.TxCounter];//通过uart1.TxCounter可以获取到缓冲区内的数据有多少,
														   //从而可以将下一个下标的地址给uart1.TxInPtr->star
	}else{//说明缓冲区内的剩余空间已经不能放下我们所要发送的数据,所以要回滚到前面
		uart1.TxCounter = 0;
		uart1.TxInPtr->start = U1_TxBuff;//将缓冲区的地址给uart1.TxInPtr->star
	}
	memcpy(uart1.TxInPtr->start,data,data_len);//把data放在uart1.TxInPtr->start这个地方,长度是data_len
	uart1.TxCounter += data_len;//缓冲区计数加上放入的长度data_len
	uart1.TxInPtr->end = &U1_TxBuff[uart1.TxCounter - 1];//标记此次数据的结束位置,通过uart1.TxCounter可以计算出在缓冲区内的下标位置
	uart1.TxInPtr++;//让数据输入指针加一,指向下一个的TxLocation数组的地址
	if(uart1.TxInPtr == uart1.TxEndPtr){//判断数据输入指针是否到达10个的极限,如果是就会进行回滚,指向TxLocation数组的首地址
		uart1.TxInPtr = &uart1.TxLocation[0];
	}
}

6、实现发送中断回调函数

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) //串口发送中断回调函数
{
    if(huart->Instance == USART1) {
        if(huart->Instance == USART1){
		uart1.TxState = 0;
		}
    }
}

7、在while(1)添加以下代码,这个代码实现的功能是:接收到数据后立马发送回去

if(uart1.RxOutPtr != uart1.RxInPtr){
			U1_Txdata(uart1.RxOutPtr->start,uart1.RxOutPtr->end - uart1.RxOutPtr->start + 1);
			uart1.RxOutPtr++;
			if(uart1.RxOutPtr == uart1.RxEndPtr){
				uart1.RxOutPtr = &uart1.RxLocation[0];
			}
		}
		if((uart1.TxOutPtr != uart1.TxInPtr)&&(uart1.TxState==0)){
			uart1.TxState = 1;
			HAL_UART_Transmit_IT(&uart1.uart,uart1.TxOutPtr->start,uart1.TxOutPtr->end - uart1.TxOutPtr->start + 1);
			uart1.TxOutPtr++;
			if(uart1.TxOutPtr == uart1.TxEndPtr){
				uart1.TxOutPtr = &uart1.TxLocation[0];
			}
		}

8、缓冲区管理结构图

stm32空闲中断,物联网,stm32,单片机,嵌入式硬件
9、下面是所以整理超子老师的代码文章来源地址https://www.toymoban.com/news/detail-722586.html

/***************在usart.h文件添加以下代码************************/
#ifndef __UART_H
#define __UART_H

#include "string.h"
#include "stdint.h"
#include "stm32f1xx_hal_uart.h"

#define U1_TX_SIZE 2048
#define U1_RX_SIZE 2048
#define U1_RX_MAX  256

typedef struct{//记录数据的开始位置和结束位置
	uint8_t  *start;
	uint8_t  *end;
}LCB;

typedef struct{
	uint32_t  RxCounter;//记录存入缓冲区的数据量
	uint32_t  TxCounter;
	uint32_t  TxState;//发送状态
	LCB       RxLocation[10];
	LCB       TxLocation[10];
	LCB      *RxInPtr;
	LCB      *RxOutPtr;
	LCB      *RxEndPtr;
	
	LCB      *TxInPtr;
	LCB      *TxOutPtr;
	LCB      *TxEndPtr;
	UART_HandleTypeDef uart;
}UCB;

void MX_USART1_UART_Init(uint32_t bandrate);

void U1_PtrInit(void);

void U1_Txdata(uint8_t *data, uint32_t data_len);


extern UCB  uart1;


#end
/***********************************************************/



//在usart.c文件里自行斟酌添加
/***************.C********************************************/
#include "stm32f1xx_hal.h"
#include "uart.h"

UCB  uart1;

uint8_t U1_RxBuff[U1_RX_SIZE];
uint8_t U1_TxBuff[U1_TX_SIZE];


void MX_USART1_UART_Init(void)//串口功能初始化
{
  uart1.uart.Instance = USART1;
  uart1.uart.Init.BaudRate = 115200;
  uart1.uart.Init.WordLength = UART_WORDLENGTH_8B;
  uart1.uart.Init.StopBits = UART_STOPBITS_1;
  uart1.uart.Init.Parity = UART_PARITY_NONE;
  uart1.uart.Init.Mode = UART_MODE_TX_RX;
  uart1.uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  uart1.uart.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&uart1.uart) != HAL_OK)
  {
    Error_Handler();
  }
  U1_PtrInit();//发送和接收缓冲区初始化函数
}

void U1_PtrInit(void)//发送和接收缓冲区初始化函数
{
	uart1.RxInPtr = &uart1.RxLocation[0];//数据输入指针指向数据开始和结束位置管理数组的首地址
	uart1.RxOutPtr = &uart1.RxLocation[0];
	uart1.RxEndPtr = &uart1.RxLocation[9];//数据输入指针指向数据开始和结束位置管理数组的尾地址
	uart1.RxCounter = 0;//存储到缓冲区的数据量
	uart1.RxInPtr->start = U1_RxBuff;//让第一个数据开始指针指向缓冲区的首地址
	
	uart1.TxInPtr = &uart1.TxLocation[0];
	uart1.TxOutPtr = &uart1.TxLocation[0];
	uart1.TxEndPtr = &uart1.TxLocation[9];
	uart1.TxCounter = 0;
	uart1.TxInPtr->start = U1_TxBuff;	
	
	__HAL_UART_ENABLE_IT(&uart1.uart, UART_IT_IDLE);//开启空闲中断
	HAL_UART_Receive_IT(&uart1.uart,uart1.RxInPtr->start,U1_RX_MAX);//开始接收
}
void U1_Txdata(uint8_t *data, uint32_t data_len)//串口发送函数
{
	if((U1_TX_SIZE - uart1.TxCounter )>=data_len){//判断发送数据是否可以存放在缓冲区内
		uart1.TxInPtr->start = &U1_TxBuff[uart1.TxCounter];//通过uart1.TxCounter可以获取到缓冲区内的数据有多少,
														   //从而可以将下一个下标的地址给uart1.TxInPtr->star
	}else{//说明缓冲区内的剩余空间已经不能放下我们所要发送的数据,所以要回滚到前面
		uart1.TxCounter = 0;
		uart1.TxInPtr->start = U1_TxBuff;//将缓冲区的地址给uart1.TxInPtr->star
	}
	memcpy(uart1.TxInPtr->start,data,data_len);//把data放在uart1.TxInPtr->start这个地方,长度是data_len
	uart1.TxCounter += data_len;//缓冲区计数加上放入的长度data_len
	uart1.TxInPtr->end = &U1_TxBuff[uart1.TxCounter - 1];//标记此次数据的结束位置,通过uart1.TxCounter可以计算出在缓冲区内的下标位置
	uart1.TxInPtr++;//让数据输入指针加一,指向下一个的TxLocation数组的地址
	if(uart1.TxInPtr == uart1.TxEndPtr){//判断数据输入指针是否到达10个的极限,如果是就会进行回滚,指向TxLocation数组的首地址
		uart1.TxInPtr = &uart1.TxLocation[0];
	}
}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)//串口底层硬件初始化
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {

    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

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

    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);

  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)//串口底层硬件复位
{

  if(uartHandle->Instance==USART1)
  {
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

    HAL_NVIC_DisableIRQ(USART1_IRQn);
  }
}

void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)//终止串口接收中断回调函数
{
	if(huart->Instance == USART1){
		uart1.RxInPtr->end = &U1_RxBuff[uart1.RxCounter - 1];//将数据结束处的地址赋值给uart1.RxInPtr->end
		uart1.RxInPtr++;
		if(uart1.RxInPtr == uart1.RxEndPtr){
			uart1.RxInPtr = &uart1.RxLocation[0];
		}
		if((U1_RX_SIZE - uart1.RxCounter)<U1_RX_MAX){//再判断缓冲区剩下的空间是否能存储下U1_RX_MAX字节,不能则回滚
			uart1.RxCounter = 0;
			uart1.RxInPtr->start = U1_RxBuff;
		}else{//可以放下就让下一个数据输入指针指向下一个可以存储的地址
			uart1.RxInPtr->start = &U1_RxBuff[uart1.RxCounter];
		}
		HAL_UART_Receive_IT(&uart1.uart,uart1.RxInPtr->start,U1_RX_MAX);//然后再次开启中断接收函数
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收中断回调函数
{
    if(huart->Instance == USART1) {
		
    }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) //串口发送中断回调函数
{
    if(huart->Instance == USART1) {
        if(huart->Instance == USART1){
		uart1.TxState = 0;
		}
    }
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {//串口接收数据出错回调函数
    if(huart->Instance == USART1) {
        
    }
}
/***************.C********************************************/

//在中断函数文件里添加
/***************.IT********************************************/
void USART1_IRQHandler(void)//串口中断函数
{							//当串口中断发生后会进入到此函数,但是我们接收的数据小于RX_MAX,所以不会发生串口接收完成中断.
	HAL_UART_IRQHandler(&uart1.uart);
	//由于程序的规定是接收和发送小于256字节的数据,所以不会发生串口接收完成中断。如果接收到45个字节,那么我理论上是根据接收函数要接收256个,
	//但是接收不到256个字节,所以再接收到45个个字节之后,串口线就处于空闲状态,也就是这个时候,空闲中断就发生了,也就是进入到USART1_IRQHandler函数
	//由于HAL没有处理空闲中断的程序,所以我们需要模仿它处理接收完成中断的程序,实现一个处理空闲中断的程序
	if(__HAL_UART_GET_FLAG(&uart1.uart, UART_FLAG_IDLE)){//判断是否是这个中断发生
		__HAL_UART_CLEAR_IDLEFLAG(&uart1.uart);//清楚中断标志位
		uart1.RxCounter += (U1_RX_MAX - uart1.uart.RxXferCount);//通过uart1.uart.RxXferCount(这个值表示还有多少个字节需要接收)我们用U1_RX_MAX减去就能得到接收的字节数量
		HAL_UART_AbortReceive_IT(&uart1.uart);最后再调用终止接收中断函数
	}
}
/***************.IT********************************************/



//主函数里添加
		if(uart1.RxOutPtr != uart1.RxInPtr){
			U1_Txdata(uart1.RxOutPtr->start,uart1.RxOutPtr->end - uart1.RxOutPtr->start + 1);
			uart1.RxOutPtr++;
			if(uart1.RxOutPtr == uart1.RxEndPtr){
				uart1.RxOutPtr = &uart1.RxLocation[0];
			}
		}
		if((uart1.TxOutPtr != uart1.TxInPtr)&&(uart1.TxState==0)){
			uart1.TxState = 1;
			HAL_UART_Transmit_IT(&uart1.uart,uart1.TxOutPtr->start,uart1.TxOutPtr->end - uart1.TxOutPtr->start + 1);
			uart1.TxOutPtr++;
			if(uart1.TxOutPtr == uart1.TxEndPtr){
				uart1.TxOutPtr = &uart1.TxLocation[0];
			}
		}

到了这里,关于【STM32的空闲中断(Idle Interrupt)】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32 CubeMX】串口编程DMA+IDLE中断

    在嵌入式系统中,串口通信是一项关键的任务,而使用DMA(直接内存访问)结合IDLE中断进行串口编程,尤其是在STM32 CubeMX环境中,能够提高系统的效率和性能。STM32 CubeMX为STM32微控制器提供了图形化的配置工具,可以简化初始化代码的生成过程,使得串口编程变得更加容易。

    2024年02月20日
    浏览(56)
  • GD32实现串口空闲(IDLE)中断 + DMA机制接收数据

    前言 串口功能在单片机开发中,是比较常用的外设,熟练使用串口功能也是驱动开发必备的技能之一。 DMA 是一种CPU辅助手段,可以在CPU不参与的情况下,是做一些辅助CPU的事情,如通常的数据搬运。 在没有DMA之前,数据读取时,需要CPU的处理,在多任务处理时,增加资源紧

    2023年04月13日
    浏览(43)
  • STM32基于HAL库的串口接受中断和空闲中断

    在通信方面。UART由于全双工通信,可以同时接受数据和发送数据而被广泛使用。 而接受数据则又有很多种方法 比如: 1根据结束符判断,数据是字符串形式,所以一般串口接受的接受符就是 \\\"rn\\\"  换成16进制ascil码显示就是 0X0D   0X0A (对应rn)  2定时器中断,设计\\\"喂狗信号量

    2023年04月08日
    浏览(43)
  • STM32 cubemx+串口空闲中断+DMA双缓冲

            写这篇文章是为了记录下之前做过的项目中用到的一部分关键技术,之前做过的项目中涉及到 采用最小开销来实时接收遥控器数据、能够准确验证传输过来数据的准确性 ,减小误差率,要求能稳定适用于不同的环境。 目录 1、为什么要用到串口空闲中断? 2、为

    2024年02月09日
    浏览(58)
  • 【STM32】-串口开发经验分享-基于RTOS+空闲中断

    目录 1. 概述     2.串口介绍 2.1 原理框图 2.2 RS-232C 2.3 RS-422 2.4 RS-485 2.5 UART 3. STM32 USART介绍 4. CubeMx生成Uart初始化代码 4.1 NewProject选择单片机型号 4.2 设置rcc时钟  4.3 设置Usart 4.4 初始化代码 4.5 注意 5 工程源码解析 5.1 程序架构 5.2 源码 fml_ring_buffer.c fml_usart.c app_usart_task.c stm3

    2023年04月16日
    浏览(47)
  • STM32 F4串口空闲中断 + DMA实现数据发送

    最近在做 STM32 + ROS车的项目,STM32与ROS之间通信由于数据量大,所以在 STM32端 使用 空闲中断 + DMA 的方案来减轻 CPU 的压力。 一、空闲中断 空闲中断 顾名思义为空了,闲了,没事了进的中断,在 没有数据流 的时候会进入进行读取。 在我们串口进行发送时实则为连续发送,两

    2024年02月16日
    浏览(61)
  • STM32实战(三):利用空闲中断从串口接收任意长数据

    “ 想起密码了,终于想起密码了(´・ω・`) ” 这次我们利用STM32F103的UART内部的空闲中断来实现对串口任意长数据的接收,通过简洁的手段解决了接收端在事前无法得知数据长度的问题。本次教程我们需要一块STM32核心板与一个USB转TTL工具。 STM32的异步串口接收寄存器可以存放

    2024年02月13日
    浏览(44)
  • STM32 cubemx配置DMA+空闲中断接收不定长数据

    本篇文章给大家讲解一下DMA+串口空闲中断接收串口不定长数据,之前我们也是讲解过串口接收不定长数据的,那么本篇文章的话将使用DMA来接收不定长数据。 串口空闲中断是指在串口接收到数据后,在数据的传输结束之后,在一段连续的空闲时间内没有接收到新数据时触发

    2024年02月19日
    浏览(53)
  • 深入理解 STM32 串口空闲中断的工作原理与实现方法

    STM32 微控制器的串口空闲中断是一种重要的通信机制,用于处理数据接收方面的任务。 本文深入解析了 STM32 串口空闲中断的工作原理,包括触发条件和中断服务函数的实现方法,并给出了相应的代码示例。 STM32 微控制器的串口通信是嵌入式系统中常见的通信方式之一。为了

    2024年02月01日
    浏览(45)
  • STM32学习笔记(五)串口空闲中断+DMA实现不定长收发(stm32c8t6)

    记录一下学习过程 DMA DMA,全称为: Direct Memory Access,即直接存储器访问, DMA 传输将数据从一个 地址空间复制到另外一个地址空间。 这一过程无需cpu的参与,从而提高cpu使用的效率 DMA相关的参数:1 数据的源地址、2 数据传输的目标地址 、3 传输宽度,4 传输多少字节,5 传

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包