STM32_ADC————ADC+DMA多路数据传输,看门狗中断,传感器控制LED

这篇具有很好参考价值的文章主要介绍了STM32_ADC————ADC+DMA多路数据传输,看门狗中断,传感器控制LED。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要内容:

一:介绍ADC与DMA的基本情况与初始化

二:利用ADC+DMA+看门狗中断+传感器控制LED灯代码

三:总结实验过程中碰到的错误与问题

实验说明:

通过DMA转运ADC的数据,设置ADC的中断看门狗阈值,当光敏传感器的ADC采样值在看门狗高低阈值中间,不触发中断,如果超过看门狗的高低阈值就会触发中断,LED灯进行闪烁,并且利用串口打印出四个通道的ADC采样值(本实验传感器的D0口接PA0)。

1:介绍ADC与DMA的基本情况与初始化:

(1):ADC的模块框图,更多内容可以参考STM32官方文档。

stm32 adc dma,STM32系列,stm32,嵌入式硬件,单片机

 (2)根据上图对照总结出大致ADC的执行流程图如下。

stm32 adc dma,STM32系列,stm32,嵌入式硬件,单片机 根据STM32F103系列可知,

ADC内有18个通道:

其中16个位外部通道和2个内部通道信号源。

ADC的转换器通道有两种:

规则组:ADC可以对一组指定的通道,按照指定的顺序,逐个转换这组通道,转换结束后,再从头循环;这指定的通道组就称为规则组。

注入组:但是实际应用中,有可能需要临时中断规则组的转换,对某些通道进行转换,这些需要中断规则组而进行转换的通道组,就称为注入组。

ADC模式选择:

独立模式:ADC转换完1个通道的数据后才能转换下一个通道的数据。

双重模式:具有两个ADC时可实现。

三重模式:具有三个 ADC时可实现

本次实验选择一个ADC独立模式,我们可以根据需求进行单通道,不循环模式。单通道,循环模式。多通道,不循环模式。多通道,循环模式。

ADC配置的大致流程:

选择配置好相关ADC的GPIO口后,根据ADC的初始化可选择所需要的转换通道(规则组或注入组),开启ADC_Cmd(),ADC校准,软件触发。如果需要看门狗中断就进行初始化。

(3)  ADC的模块框图,更多内容可以参考STM32官方文档。

stm32 adc dma,STM32系列,stm32,嵌入式硬件,单片机

 (4)根据上图对照总结出大致DMA的执行流程图如下。

stm32 adc dma,STM32系列,stm32,嵌入式硬件,单片机

 DMA的传输模式:

外设与存储器之间:当配置完外设之后,就进行外设应答传输,将外设获取到的数据通过总线传输到存储器中。

存储器与存储器之间:当启动DMA传输模式后,DMA外设通过DMA总线,总线矩阵将Flash中的数据直接写到SRAM中。

 一般ADC都会与DMA搭配进行使用,因为ADC获取数据之后如果在很短的时间内不转运出去就会被下一波数据覆盖掉,所以需要DMA进行数据的搬运,DMA的搬运不需要消耗CPU资源。

DMA的实现过程:

在发生一个事件后,外设向DMA控制器发送一个请求信号。DMA控制器根据通道的优先权处理 请求。当DMA控制器开始访问发出请求的外设时,DMA控制器立即发送给它一个应答信号。当 DMA控制器得到应答信号时,外设立即释放它的请求。一旦外设释放了这个请求,DMA控制器同时撤销应答信号。如果有更多的请求时,外设可以启动下一个周期。

DMA配置的大致流程:

根据DMA的初始化配置,选择外设地址,内存储器地址,传输方向,缓存方向等,最后如果和ADC进行搭配一定要开启ADC_DMACmd()函数,进行ADC与DMA的硬件连接,最后开启DMA_Cmd().

二:利用ADC+DMA+看门狗中断+传感器控制LED灯代码

本次实验利用的是ADC+DMA多通道循环模式

(1)各种宏定义,方便后续移植。

#ifndef __ADG_H
#define __ADG_H
#include "stm32f10x.h"
#define				ADC_x                                 ADC1
#define       ADC_Channel_x                               ADC_Channel_0
#define       ADC_RCC_APB2Periph_ADC1                     RCC_APB2Periph_ADC1
#define 			ADC_RCC_APB2PeriphClockCmd            RCC_APB2PeriphClockCmd

#define       DMAy_Channelx                               DMA1_Channel1
#define       RCC_AHBPeriph_DMAx                          RCC_AHBPeriph_DMA1
#define       GPIO_x                                      GPIOA
#define       GPIO_PIN_x                                  GPIO_Pin_0
#define       GPIO_Pin_x1                                 GPIO_Pin_1
#define       GPIO_Pin_x2                                 GPIO_Pin_2
#define       GPIO_Pin_x3                                 GPIO_Pin_3
#define       GPIO_RCC_APB2Periph_ADC1                    RCC_APB2Periph_GPIOA
#define       GPIO_RCC_APB2PeriphClockCmd                 APB2PeriphClockCmd

void AD_DMA_GetValue(void);
extern uint16_t Value[4];
void   ADCInit(void);
void AD_DMA_GetValue(void);
void ADC_Config(void);
#endif

 (2)ADC的GPIO的初始化,这里特别注意配置GPIO_MODE模式一定要选择模拟输入GPIO_Mode_AIN。

//ADC的GPIO口初始化
void	ADC_GPIOInit(void)
{
            //开启GPIO的时钟
			ADC_RCC_APB2PeriphClockCmd(GPIO_RCC_APB2Periph_ADC1,ENABLE);
			GPIO_InitTypeDef		GPIO_InitStruture;
			GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AIN;
			GPIO_InitStruture.GPIO_Pin = GPIO_PIN_x |  GPIO_Pin_x1 | GPIO_Pin_x2 | GPIO_Pin_x3;
			GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO_Init(GPIO_x, &GPIO_InitStruture);
}


 (3) 模拟看门狗的初始化,特别注意看门狗的高低阈值内不发生中断。

void WatchDog_ADInit()
{
		//模拟看门狗的单通道
		ADC_AnalogWatchdogSingleChannelConfig(ADC_x, ADC_Channel_x);
		//设置模拟看门狗的高低,看门狗的高低值内不触发中断
		ADC_AnalogWatchdogThresholdsConfig(ADC_x,HighThreshold,LowThreshold); 
		//打开看门狗的单通道检测
		ADC_AnalogWatchdogCmd(ADC_x,ADC_AnalogWatchdog_SingleRegEnable);
		//使能中断
		ADC_ITConfig(ADC_x,ADC_IT_AWD,ENABLE);
}

 (4)中断优先级的设置。

//中断优先级的设置
void  ADC_NVICInit(void)
{
        //设置中断组
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
		NVIC_InitTypeDef				NVIC_InitStruture;
        //设置中断源
		NVIC_InitStruture.NVIC_IRQChannel = ADC1_2_IRQn;
        //设置主优先级
		NVIC_InitStruture.NVIC_IRQChannelPreemptionPriority = 1; 
        //设置子优先级
		NVIC_InitStruture.NVIC_IRQChannelSubPriority = 2;
        //使能中断
		NVIC_InitStruture.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStruture);
		
}

 (5)DMA初始化。

void ADC_DMA_Init(void)
{
	   
			RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx,ENABLE);
	
		  DMA_InitTypeDef		DMA_InitStruture;
	    //将DMA的通道1寄存器重设为缺省值 
	    DMA_DeInit(DMA1_Channel1);                                            
		  //外设站点的地址
			DMA_InitStruture.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;              
	    //外设寄存器低16位地址
			DMA_InitStruture.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 
	    //外设地址寄存器不变
	    DMA_InitStruture.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
 	    //传输的目的地址
			DMA_InitStruture.DMA_MemoryBaseAddr = (uint32_t)Value;         
	    //选择内部寄存器的低16位地址
			DMA_InitStruture.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;   
	    //选择内存地址寄存器递增
		  DMA_InitStruture.DMA_MemoryInc = DMA_MemoryInc_Enable;   
	    //传输方向,从外设到内设
			DMA_InitStruture.DMA_DIR = DMA_DIR_PeripheralSRC;  
	    //DMA通道的DMA缓存的大小
			DMA_InitStruture.DMA_BufferSize = 4; 
			//选择正常模式还是循环模式 
	    DMA_InitStruture.DMA_Mode = DMA_Mode_Circular;  
      //非内存到内存传输
			DMA_InitStruture.DMA_M2M = DMA_M2M_Disable;                                  
			//DMA通道X拥有中优先级
			DMA_InitStruture.DMA_Priority = DMA_Priority_Medium;                         
					
			DMA_Init(DMAy_Channelx,&DMA_InitStruture);
			//使能DMA
			DMA_Cmd(DMAy_Channelx, ENABLE);
	
}

 (6)ADC初始化。

void   ADCInit(void)
{
	  //开启ADC的时钟
		ADC_RCC_APB2PeriphClockCmd(ADC_RCC_APB2Periph_ADC1,ENABLE);
	  //ADC的时钟分频
		RCC_ADCCLKConfig(RCC_PCLK2_Div6);
		//输入规则组的通道的选择(扫描通道)
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_0,1, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_1,2, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_2,3, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_3,4, ADC_SampleTime_55Cycles5);
		ADC_InitTypeDef   	ADC_InitStruture;
		//模式选择
		ADC_InitStruture.ADC_Mode = ADC_Mode_Independent;
		//选择多通道模式或单通道模式
		ADC_InitStruture.ADC_ScanConvMode = ENABLE;
		//指定选择模式是单词还是多次
		ADC_InitStruture.ADC_ContinuousConvMode = DISABLE;
	  //软件触发
		ADC_InitStruture.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
		//选择右对其方式
		ADC_InitStruture.ADC_DataAlign = ADC_DataAlign_Right;
		//选择使用的通道
		ADC_InitStruture.ADC_NbrOfChannel = 4;
		ADC_Init(ADC_x,&ADC_InitStruture);
	
		//使能ADC
		ADC_Cmd(ADC_x, ENABLE);   
		//使能ADC与DMA的硬件连接
		ADC_DMACmd(ADC_x,ENABLE);                                             
    //复位校准	
		ADC_ResetCalibration(ADC_x);                        	
		//返回复位校准的状态
		while(ADC_GetResetCalibrationStatus(ADC_x) != RESET); 
    //启动校准
		ADC_StartCalibration(ADC_x);                          
		//获取校准的状态
		while(ADC_GetCalibrationStatus(ADC_x) != RESET);	    
		//:软件触发
		ADC_SoftwareStartConvCmd(ADC_x,ENABLE);               
		
		
	}		

(7)整体初始化放到一个函数中,特别注意WatchDog_ADInit();的位置,一定要放到ADC初始化的后面。

void ADC_Config(void)
{
		ADC_GPIOInit();
		ADC_NVICInit();
		ADC_DMA_Init();
		ADCInit();
	    WatchDog_ADInit();
}
	

(8)判断DMA获取的标志位,不断进行软件触发。

void AD_DMA_GetValue(void)
{
	
		DMA_SetCurrDataCounter(DMAy_Channelx,4);  //设置传输数据传输通道数
	
		DMA_Cmd(DMAy_Channelx,ENABLE);
		
		ADC_SoftwareStartConvCmd(ADC_x,ENABLE);   //软件触发开启
		
		while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//获取标志位状态
		DMA_ClearFlag(DMA1_FLAG_TC1);
}

(9)中断函数。

void ADC1_2_IRQHandler(void)
{
        //获取中断标志中断位
		if(ADC_GetITStatus(ADC_x,ADC_IT_AWD) == SET)
		{
		
				LED_R(ON);
				Delay(0xFFFFF);
				LED_R(OFF);
				Delay(0xFFFFF);
                //清楚中断标志位
				ADC_ClearITPendingBit(ADC_x,ADC_IT_AWD);
                //清楚ADC的标志位
				ADC_ClearFlag(ADC_x,ADC_FLAG_AWD);
		}
	
		
}

 (10)实验完整代码。

//main.c

#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp.usart.h"
#include "adg.h"
#include <stdio.h>
unsigned int AD_Value;

void Delay(uint32_t count)
{

	for(int i =0;i<count;count--);

}

int main(void)
{
		
	  LED_GPIO_Config();
		USART_Config();

	  ADC_Config();
		while(1)
   	{         
					AD_DMA_GetValue();
					printf("AD0 = %d\n",Value[0]);
					printf("AD1 = %d\n",Value[1]);
					printf("AD2 = %d\n",Value[2]);
					printf("AD3 = %d\n",Value[3]);
					Delay(0xFFFFF);
					
	  }
}


//stm32f10x_it.c

void ADC1_2_IRQHandler(void)
{
		if(ADC_GetITStatus(ADC_x,ADC_IT_AWD) == SET)
		{
				//BrightEnough = 0;
				LED_R(ON);
				Delay(0xFFFFF);
				LED_R(OFF);
				Delay(0xFFFFF);
				ADC_ClearITPendingBit(ADC_x,ADC_IT_AWD);
				ADC_ClearFlag(ADC_x,ADC_FLAG_AWD);
		}
	
		
}


//adg.c
   #include "adg.h"
unsigned  int   HighThreshold = 200;           
unsigned  int   LowThreshold =150;
extern unsigned int AD_Value;
uint16_t Value[4];
void	ADC_GPIOInit(void)
{	
			ADC_RCC_APB2PeriphClockCmd(GPIO_RCC_APB2Periph_ADC1,ENABLE);
			GPIO_InitTypeDef		GPIO_InitStruture;
			GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AIN;
			GPIO_InitStruture.GPIO_Pin = GPIO_PIN_x |  GPIO_Pin_x1 | GPIO_Pin_x2 | GPIO_Pin_x3;
			GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO_Init(GPIO_x, &GPIO_InitStruture);
}

void WatchDog_ADInit()
{
		//模拟看门狗的单通道
		ADC_AnalogWatchdogSingleChannelConfig(ADC_x, ADC_Channel_x);
		//设置模拟看门狗的高低,看门狗的高低值内不触发中断
		ADC_AnalogWatchdogThresholdsConfig(ADC_x,HighThreshold,LowThreshold); 
		//打开看门狗的单通道检测
		ADC_AnalogWatchdogCmd(ADC_x,ADC_AnalogWatchdog_SingleRegEnable);
		//使能中断
		ADC_ITConfig(ADC_x,ADC_IT_AWD,ENABLE);
}
//中断优先级的设置
void  ADC_NVICInit(void)
{
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
		NVIC_InitTypeDef				NVIC_InitStruture;
		NVIC_InitStruture.NVIC_IRQChannel = ADC1_2_IRQn;
		NVIC_InitStruture.NVIC_IRQChannelPreemptionPriority = 1;
		NVIC_InitStruture.NVIC_IRQChannelSubPriority = 2;
		NVIC_InitStruture.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStruture);
		
}
void ADC_DMA_Init(void)
{
	   
			RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx,ENABLE);
	
		  DMA_InitTypeDef		DMA_InitStruture;
	    //将DMA的通道1寄存器重设为缺省值 
	    DMA_DeInit(DMA1_Channel1);                                            
		  //外设站点的地址
			DMA_InitStruture.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;              
	    //外设寄存器低16位地址
			DMA_InitStruture.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 
	    //外设地址寄存器不变
	    DMA_InitStruture.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
 	    //传输的目的地址
			DMA_InitStruture.DMA_MemoryBaseAddr = (uint32_t)Value;         
	    //选择内部寄存器的低16位地址
			DMA_InitStruture.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;   
	    //选择内存地址寄存器递增
		  DMA_InitStruture.DMA_MemoryInc = DMA_MemoryInc_Enable;   
	    //传输方向,从外设到内设
			DMA_InitStruture.DMA_DIR = DMA_DIR_PeripheralSRC;  
	    //DMA通道的DMA缓存的大小
			DMA_InitStruture.DMA_BufferSize = 4; 
			//选择正常模式还是循环模式 
	    DMA_InitStruture.DMA_Mode = DMA_Mode_Circular;  
      //非内存到内存传输
			DMA_InitStruture.DMA_M2M = DMA_M2M_Disable;                                  
			//DMA通道X拥有中优先级
			DMA_InitStruture.DMA_Priority = DMA_Priority_Medium;                         
					
			DMA_Init(DMAy_Channelx,&DMA_InitStruture);
			//使能DMA
			DMA_Cmd(DMAy_Channelx, ENABLE);
	
}

void   ADCInit(void)
{
	  //开启ADC的时钟
		ADC_RCC_APB2PeriphClockCmd(ADC_RCC_APB2Periph_ADC1,ENABLE);
	  //ADC的时钟分频
		RCC_ADCCLKConfig(RCC_PCLK2_Div6);
		//输入规则组的通道的选择(扫描通道)
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_0,1, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_1,2, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_2,3, ADC_SampleTime_55Cycles5);
		ADC_RegularChannelConfig(ADC_x,ADC_Channel_3,4, ADC_SampleTime_55Cycles5);
		ADC_InitTypeDef   	ADC_InitStruture;
		//模式选择
		ADC_InitStruture.ADC_Mode = ADC_Mode_Independent;
		//选择多通道模式或单通道模式
		ADC_InitStruture.ADC_ScanConvMode = ENABLE;
		//指定选择模式是单词还是多次
		ADC_InitStruture.ADC_ContinuousConvMode = DISABLE;
	  //软件触发
		ADC_InitStruture.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
		//选择右对其方式
		ADC_InitStruture.ADC_DataAlign = ADC_DataAlign_Right;
		//选择使用的通道
		ADC_InitStruture.ADC_NbrOfChannel = 4;
		ADC_Init(ADC_x,&ADC_InitStruture);
	
		//使能ADC
		ADC_Cmd(ADC_x, ENABLE);   
		//使能ADC与DMA的硬件连接
		ADC_DMACmd(ADC_x,ENABLE);                                             
    //复位校准	
		ADC_ResetCalibration(ADC_x);                        	
		//返回复位校准的状态
		while(ADC_GetResetCalibrationStatus(ADC_x) != RESET); 
    //启动校准
		ADC_StartCalibration(ADC_x);                          
		//获取校准的状态
		while(ADC_GetCalibrationStatus(ADC_x) != RESET);	    
		//:软件触发
		ADC_SoftwareStartConvCmd(ADC_x,ENABLE);               
		
		
	}		

void ADC_Config(void)
{
		ADC_GPIOInit();
		ADC_NVICInit();
		ADC_DMA_Init();
		ADCInit();
	  WatchDog_ADInit();
}
//可以获取ADC单个值	
unsigned int  ADC_GetADVal()
{
		ADC_SoftwareStartConvCmd(ADC_x,ENABLE);
		while(ADC_GetFlagStatus(ADC_x,ADC_FLAG_EOC) == 0);
		//等待规则转换完成
		ADC_SoftwareStartConvCmd(ADC_x,DISABLE);
		return(ADC_GetConversionValue(ADC_x));
}

void AD_DMA_GetValue(void)
{
	
		DMA_SetCurrDataCounter(DMAy_Channelx,4);  //设置传输数据传输通道数
	
		DMA_Cmd(DMAy_Channelx,ENABLE);
		
		ADC_SoftwareStartConvCmd(ADC_x,ENABLE);   //软件触发开启
		
		while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//获取标志位状态
		DMA_ClearFlag(DMA1_FLAG_TC1);
}

//adg.h

#ifndef __ADG_H
#define __ADG_H
#include "stm32f10x.h"
#define				ADC_x                                       ADC1
#define       ADC_Channel_x                               ADC_Channel_0
#define       ADC_RCC_APB2Periph_ADC1                     RCC_APB2Periph_ADC1
#define 			ADC_RCC_APB2PeriphClockCmd                  RCC_APB2PeriphClockCmd

#define       DMAy_Channelx                               DMA1_Channel1
#define       RCC_AHBPeriph_DMAx                          RCC_AHBPeriph_DMA1
#define       GPIO_x                                      GPIOA
#define       GPIO_PIN_x                                  GPIO_Pin_0
#define       GPIO_Pin_x1                                 GPIO_Pin_1
#define       GPIO_Pin_x2                                 GPIO_Pin_2
#define       GPIO_Pin_x3                                 GPIO_Pin_3
#define       GPIO_RCC_APB2Periph_ADC1                    RCC_APB2Periph_GPIOA
#define       GPIO_RCC_APB2PeriphClockCmd                 APB2PeriphClockCmd

void AD_DMA_GetValue(void);
extern uint16_t Value[4];
//extern char  BrightEnough;
void   ADCInit(void);
unsigned int  ADC_GetADVal();
void AD_DMA_GetValue(void);
void ADC_Config(void);
#endif




三:总结实验过程中碰到的错误与问题

1:DMA_PeripheralDataSize_HalfWord与DMA_MemoryDataSize_HalfWord在配置过程中十分相似,如果在配置DMA_PeripheralDataSize使用DMA_MemoryDataSize_HalfWord;就会丢失高位数据。

2:注意开启ADC_DMACmd();函数。不然ADC与DMA无法进行连接。

3:注意在DMA内存地址一定要uint32_t 强制转化,而且注意内存地址一定对照清楚。

4:注意在最后设置DMA完成的标志位判定,并进行ADC软件触发,不然就只会转运第一个ADC接收到转运的数据,不再工作。

5:注意DMA配置DMA_DIR时DMA_DIR_PeripheralSRC(外设到内存的配置)。文章来源地址https://www.toymoban.com/news/detail-766134.html

到了这里,关于STM32_ADC————ADC+DMA多路数据传输,看门狗中断,传感器控制LED的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【N32L40X】学习笔记11-ADC规则通道采集+dma数据传输

    支持 1 个 ADC,支持单端输入和差分输入,最多可测量 16 个外部和 3 个内部源。 支持 12 位、10 位、8 位、6 位分辨率。 ADC 时钟源分为 工作时钟源、采样时钟源和计时时钟源 仅可配置 AHB_CLK 作为 工作时钟源 。 可配置 PLL 作为 采样时钟源 ,最高可到 64MHz,支持分频 1,2,4,6,8,

    2024年02月15日
    浏览(24)
  • STM32 TIMER_TRGO触发+ADC采集 + DMA传输 + 中断均方根处理 实现三相电压显示

    STM32 TIMER_TRGO触发+ADC采集 + DMA传输 实现三相电压采集 首先,是实际采集的三相电压值,用excel处理了下: 采集个电压,为什么这么复杂。 开始我也是直接用ADC采集,然后delay,再采集,然后delay,再采集……最后数据处理…… 问题是如果我们用单片机裸跑,每次delay都会卡死

    2024年02月16日
    浏览(17)
  • STM32 HAL库定时器触发DMA并口数据传输

    STM32与FPGA通讯,通过8位并口线进行通讯,16byte的数据在10us之内通过8位并口数据线传给FPGA,FPGA读取该数据。 时钟采用80MHz,由于16byte的数据要在10us之内传完,那么10/(16*2)=0.3125us/次,也就是传输频率得≥3.2MHz。 定时器设置:为了方便起见,先选用了4MHz的传输频率。80MHz

    2024年02月02日
    浏览(29)
  • 【STM32】IIC使用中DMA传输时 发送数据总少一个的问题

    在使用STM32 I2C数据发送过程中,发现每轮实际发送出去的数据总比在DMA配置中设定的传输数据个数要少一个。比方说:DMA配置里设定的传输数据个数是10个,结果发现在总线上只能发出9个,经过进一步发现是少了最后一个数据。当对I2C接收到的数据进行DMA传输时,没有异常。

    2024年02月10日
    浏览(14)
  • STM32F103采用DMA方式多路ADC采样

    stm32采用DMA方式进行ADC采样可以高效的进行数据采集,不用cpu实时参与,以节省单片机资源,让单片机可以在同一时间里干更多事,STM32F103 ADC为12位ADC的,是一种逐次逼近型模拟数字转换器,它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续

    2024年02月06日
    浏览(27)
  • STM32——ADC读取光敏传感器控制LED灯,看门狗中断

    一、编写读取AD值的函数,之后判断AD值,进行相应操作,比如点灯。 二、用ADC读取光敏传感器AO口输出,并配置ADC通道看门狗监控这条通道,当光线太暗时打开LED灯。 之后会再介绍可编程RGB灯带WS2812B。 光敏传感器有两个输出口,一个是DO(Digital Output),一个是AO(Analog O

    2023年04月18日
    浏览(17)
  • STM32 ADC采集 DMA中断处理

    //============================================ //函数名称:ADC1_Mode_Config(void) //功能描述:配置ADC1的工作模式为MDA模式 //输入:无 //输出:无 //============================================ void ADC1_Mode_Config(void) {         DMA_InitTypeDef DMA_InitStructure;         ADC_InitTypeDef ADC_InitStructure;              

    2024年02月14日
    浏览(16)
  • (EMQX)STM32L+BC20+MQTT协议传输温湿度,ADC,电压,GPS数据到EMQX

    1、材料准备 准备以下材料 2、设备连接 2.1 插入物联网卡,天线 首先把BC20核心板从开发板上拆下来 然后将物联卡放置在BC20核心板内 物联卡放置完成将BC20核心板重新插入到开发板内(注意不要弄错方向) 同时接入天线 2.2 连接ST-Link仿真器 用3条杜邦线接入STM32L的 DIO、GND、

    2024年02月16日
    浏览(22)
  • HC06蓝牙2.0模块连接不稳定 和 STM32串口不传输数据(串口接收中断)的一些问题

    最近,在一个项目中使用到蓝牙,但是调试过程出现了很多问题。 刚开始使用的是HC06蓝牙,刚开始使用较为正常,可以实现蓝牙模块和电脑设备直接连接,而且数据接收正常。 在接下来的设计中,考虑到适配问题,就设计了配套的蓝牙接收模块,同样是HC06贴片模块。但问题

    2024年02月14日
    浏览(22)
  • (Onenet)STM32L+BC20+MQTT协议传输温湿度,ADC,电压,GPS数据到Onenet物联网平台

    1、材料准备 准备以下材料 2、设备连接 2.1 插入物联网卡 首先把BC20核心板从开发板上拆下来 然后将物联卡放置在BC20核心板内 物联卡放置完成将BC20核心板重新插入到开发板内(注意不要弄错方向) 同时接入天线 2.2 连接ST-Link仿真器 用3条杜邦线接入STM32L的 DIO、GND、CLK中 另

    2024年02月15日
    浏览(17)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包