您的位置:首页 > 游戏 > 手游 > 一起装修网装修质量靠谱吗_百度引流推广哪家好_做网站的网络公司_seo排名点击器曝光行者seo

一起装修网装修质量靠谱吗_百度引流推广哪家好_做网站的网络公司_seo排名点击器曝光行者seo

2025/1/8 12:02:31 来源:https://blog.csdn.net/qq_45973003/article/details/144979869  浏览:    关键词:一起装修网装修质量靠谱吗_百度引流推广哪家好_做网站的网络公司_seo排名点击器曝光行者seo
一起装修网装修质量靠谱吗_百度引流推广哪家好_做网站的网络公司_seo排名点击器曝光行者seo

注:DMA对应的库函数文件讲解


DMA_GetITStatus(uint32_t DMAy_IT) 是一个用于检查DMA(直接存储器访问)中断状态的库函数。它通常在使用STM32系列微控制器及其标准外设库时被调用。此函数的主要作用是返回指定DMA通道的特定中断标志的状态,以帮助开发者确定是否发生了特定类型的DMA事件。

参数 uint32_t DMAy_IT 用来指定你想要检查的DMA中断类型和对应的DMA流或通道。这个参数是一个组合值,通常由两个部分组成:

  1. DMAx:指明哪个DMA控制器(例如DMA1或DMA2),因为一些STM32芯片可能有多个DMA控制器。
  2. IT(Interrupt Type):指明具体的中断类型,比如传输完成(Transfer Complete, TC)、半传输完成(Half Transfer, HT)、传输错误(Transfer Error, TE)等。

函数会返回一个位标志,表明所选中断状态是设置(即事件发生)还是清除(即事件未发生)。这对于编写中断服务程序(ISR)非常重要,因为在ISR中你需要知道是什么类型的事件触发了中断,以便可以适当地处理它。

例如,如果你正在等待DMA传输完成中断,你可以使用 DMA_GetITStatus 来检查该中断是否已经发生。如果函数返回值表示中断已被设置,那么你可以安全地假设DMA传输已完成,并且可以继续执行后续的操作,如启动新的DMA传输、处理接收到的数据等。


DMA_ClearITPendingBit(uint32_t DMAy_IT) 是一个用于清除DMA(直接存储器访问)中断挂起位的库函数。在STM32系列微控制器中,当DMA传输过程中发生特定事件(如传输完成、半传输完成或传输错误),DMA硬件会设置相应的中断标志位,并可能触发中断请求。

然而,一旦这些事件被软件处理后,就需要清除相应的中断标志位,以确保相同的中断不会再次被误触发。这就是 DMA_ClearITPendingBit 函数的作用:它允许你手动清除指定DMA通道的特定中断挂起位,表明该事件已经被处理完毕。

参数 uint32_t DMAy_IT 用来指定要清除的DMA中断类型和对应的DMA流或通道。这个参数是一个组合值,通常由两个部分组成:

  1. DMAx:指明哪个DMA控制器(例如DMA1或DMA2)。
  2. IT(Interrupt Type):指明具体的中断类型,比如传输完成(Transfer Complete, TC)、半传输完成(Half Transfer, HT)、传输错误(Transfer Error, TE)等。

使用此函数是确保DMA中断系统正确工作的关键步骤之一。如果不清除这些标志位,可能会导致中断不断重复触发,或者新的相同类型的中断无法被正确识别。因此,在你的中断服务程序(ISR)中,你应该在检查并响应了某个DMA事件之后调用 DMA_ClearITPendingBit 来清除对应的中断挂起位。


定义:


DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源 12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道) 每个通道都支持软件触发和特定的硬件触发 STM32F103C8T6 DMA资源:DMA1(7个通道)


SRAM可以读也可以写 



 DMA基本结构




1.0 数据宽度与对齐


 在DMA中是如何解决数据宽度不一致的问题的,如果源端的数据大于目标端的数据,那么将读取出来的高位舍弃掉,然后只取低位。


 2.0 ADC与DMA数据转运

 连续扫描转运模式


3.0 手册解读



4.0 程序实现


注:本次程序主要实现的是DMA从存储器到存储器的数据转运,使用软件触发的方式

4.0.1 DMA初始化

初始化:主要包括RCC时钟初始化,GPIO初始化

 函数初始化实现

#include "stm32f10x.h" // Device headeruint16_t MyDMA_Size;/*** @brief  DMA初始化,包括时钟等* @param  ADDRA起始地址* @param  ADDRB结束地址* @param  SIZE大小* @return 无返回值*/
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{MyDMA_Size = Size;// RCC时钟初始化RCC_APB1PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// DMA 结构体初始化DMA_InitTypeDef DMA_InitStructure;// 起始地址DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;// 数据大小DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 是否自增DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;// 接收地址【目的地址】DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;// 接收地址数据大小DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;// 地址是否自增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 数据的传输方向,外设传输到存储器DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 重装计数器的大小DMA_InitStructure.DMA_BufferSize = Size;// DMA模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 触发方式DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;// DMA优先级,通道的优先级设置为中等DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;// 初始化DMADMA_Init(DMA1_Channel1, &DMA_InitStructure);// 使能DMA,初始化后会立即工作,等后续手动调用后再开始DMA_Cmd(DMA1_Channel1, DISABLE);
}

 4.0.2 数据转运函数

注:该函数的主要作用是,从新设置传输计数器的值

/*** @brief  DMA数据传输,重置* @param  MULL* @param  MULL* @param  SIZE大小* @return 无返回值*/
void MyDMA_Transfer(void)
{// DMA失能,在写入传输计数器之前,需要DMA暂停工作DMA_Cmd(DMA1_Channel1, DISABLE);// 写入传输计数器,指定将要转运的次数DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);// 使能DMADMA_Cmd(DMA1_Channel1, ENABLE);// 等待DMA工作完成,工作完成标志位设置为1while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);// 清除工作完成标志位DMA_ClearFlag(DMA1_FLAG_TC1);
}

4.0.3 全部程序

#include "stm32f10x.h" // Device headeruint16_t MyDMA_Size;/*** @brief  DMA初始化,包括时钟等* @param  ADDRA起始地址* @param  ADDRB结束地址* @param  SIZE大小* @return 无返回值*/
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{MyDMA_Size = Size;// RCC时钟初始化RCC_APB1PeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// DMA 结构体初始化DMA_InitTypeDef DMA_InitStructure;// 起始地址DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;// 数据大小DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 是否自增DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;// 接收地址【目的地址】DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;// 接收地址数据大小DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;// 地址是否自增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 数据的传输方向,外设传输到存储器DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 重装计数器的大小DMA_InitStructure.DMA_BufferSize = Size;// DMA模式DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 触发方式DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;// DMA优先级,通道的优先级设置为中等DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;// 初始化DMADMA_Init(DMA1_Channel1, &DMA_InitStructure);// 使能DMA,初始化后会立即工作,等后续手动调用后再开始DMA_Cmd(DMA1_Channel1, DISABLE);
}/*** @brief  DMA数据传输,重置* @param  MULL* @param  MULL* @param  SIZE大小* @return 无返回值*/
void MyDMA_Transfer(void)
{// DMA失能,在写入传输计数器之前,需要DMA暂停工作DMA_Cmd(DMA1_Channel1, DISABLE);// 写入传输计数器,指定将要转运的次数DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);// 使能DMADMA_Cmd(DMA1_Channel1, ENABLE);// 等待DMA工作完成,工作完成标志位设置为1while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);// 清除工作完成标志位DMA_ClearFlag(DMA1_FLAG_TC1);
}

4.0.4 头文件


#ifndef __MYDMA_H
#define __MYDMA_Hvoid MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size);
void MyDMA_Transfer(void);#endif

4.0.5 main函数文件


#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyDMA.h"uint8_t DataA[] = {0x01, 0x02, 0x03, 0x04}; // 定义测试数组DataA,为数据源
uint8_t DataB[] = {0, 0, 0, 0};				// 定义测试数组DataB,为数据目的地int main(void)
{/*模块初始化*/OLED_Init(); // OLED初始化MyDMA_Init((uint32_t)DataA, (uint32_t)DataB, 4); // DMA初始化,把源数组和目的数组的地址传入/*显示静态字符串*/OLED_ShowString(1, 1, "DataA");OLED_ShowString(3, 1, "DataB");/*显示数组的首地址*/OLED_ShowHexNum(1, 8, (uint32_t)DataA, 8);OLED_ShowHexNum(3, 8, (uint32_t)DataB, 8);while (1){DataA[0]++; // 变换测试数据DataA[1]++;DataA[2]++;DataA[3]++;Delay_ms(1000); // 延时1s,观察转运前的现象MyDMA_Transfer();OLED_ShowHexNum(2, 1, DataA[0], 2); // 显示数组DataAOLED_ShowHexNum(2, 4, DataA[1], 2);OLED_ShowHexNum(2, 7, DataA[2], 2);OLED_ShowHexNum(2, 10, DataA[3], 2);OLED_ShowHexNum(4, 1, DataB[0], 2); // 显示数组DataBOLED_ShowHexNum(4, 4, DataB[1], 2);OLED_ShowHexNum(4, 7, DataB[2], 2);OLED_ShowHexNum(4, 10, DataB[3], 2); // 使用DMA转运数组,从DataA转运到DataBOLED_ShowHexNum(2, 1, DataA[0], 2); // 显示数组DataAOLED_ShowHexNum(2, 4, DataA[1], 2);OLED_ShowHexNum(2, 7, DataA[2], 2);OLED_ShowHexNum(2, 10, DataA[3], 2);OLED_ShowHexNum(4, 1, DataB[0], 2); // 显示数组DataBOLED_ShowHexNum(4, 4, DataB[1], 2);OLED_ShowHexNum(4, 7, DataB[2], 2);OLED_ShowHexNum(4, 10, DataB[3], 2);Delay_ms(1000); // 延时1s,观察转运后的现象}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com