STM32F103C8T6 ADC采集数据一直是0

本文详细介绍了在使用STM32F103C8T6开发板时遇到的ADC问题,包括ADC转换时间、通道选择、DMA设置等,并提供了ADC直接采集和配合DMA采集的代码示例。作者还分享了在调试过程中遇到的心态挑战,以及如何通过自学和实践解决问题。
摘要由CSDN通过智能技术生成

淘宝上买了一块STM32F103C8T6开发板,调试的时候发现是国产山寨版,更换了芯片包后正常运行,但是最近调试ADC的时候发现怎么都不出结果,网上找了一堆解决方案,都不行,网上得来终觉浅,绝知此事要躬行。自己研究自己学,干。。

目录

1资料收集

1.1STM32F103C8T6闪存大小?

1.2ADC转换时间

1.3ADC转换框图

1.4引脚连接

1.5通道选择

1.6转换时序图

1.7DMA设置

1.8ADC通道

2心态搞崩

3ADC采集

4ADC+DMA采集

5定时器+ADC+DMA采集


1资料收集

stm32f1x系列芯片中文参考手册见: https://download.csdn.net/download/weixin_51248645/87704176

1.1STM32F103C8T6闪存大小?

64K的,属于中容量产品。

小容量产品 是指闪存存储器容量在 16K 32K 字节之间的 STM32F101xx STM32F102xx
STM32F103xx 微控制器。
中容量产品 是指闪存存储器容量在 64K 128K 字节之间的 STM32F101xx STM32F102xx
STM32F103xx 微控制器。
大容量产品 是指闪存存储器容量在 256K 512K 字节之间的 STM32F101xx STM32F103xx 微控
制器。

1.2ADC转换时间

ADC 转换时间:1.17us
STM32F103xx 增强型产品:时钟为 56MHz 时为 1 μ s( 时钟为 72MHz 1.17 μ s)
STM32F101xx 基本型产品:时钟为 28MHz 时为 1 μ s( 时钟为 36MHz 1.55 μ s)
STM32F102xxUSB 型产品:时钟为 48MHz 时为 1.2 μ s
STM32F105xx STM32F107xx 产品:时钟为 56MHz 时为 1 μ s( 时钟为 72MHz 1.17 μ s)
ADC 供电要求: 2.4V 3.6V
ADC 输入范围: V REF- V IN V REF+
● 规则通道转换期间有 DMA 请求产生。
下图是 ADC 模块的方框图。
注意: 如果有 V REF - 引脚 ( 取决于封装 ) ,必须和 VSSA 相连接

1.3ADC转换框图

 1.4引脚连接

(STM32F103C8T6不用关注,已经连好的)

 

 1.5通道选择

16 个多路通道。可以把转换组织成两组:规则组和注入组。在任意多个通道上以任意顺序进
行的一系列转换构成成组转换。例如,可以如下顺序完成转换:通道 3 、通道 8 、通道 2 、通道
2 、通道 0 、通道 2 、通道 2 、通道 15
规则组 由多达 16 个转换组成。规则通道和它们的转换顺序在 ADC_SQRx 寄存器中选择。规
则组中转换的总数应写入 ADC_SQR1 寄存器的 L[3:0] 位中。
注入组 由多达 4 个转换组成。注入通道和它们的转换顺序在 ADC_JSQR 寄存器中选择。注入
组里的转换总数目应写入 ADC_JSQR 寄存器的 L[1:0] 位中。
如果 ADC_SQRx ADC_JSQR 寄存器在转换期间被更改,当前的转换被清除,一个新的启动脉
冲将发送到 ADC 以转换新选择的组。
温度传感器 / V REFINT 内部通道
温度传感器和通道 ADC1_IN16 相连接,内部参照电压 V REFINT ADC1_IN17 相连接。可以按注入
或规则通道对这两个内部通道进行转换。
注意: 温度传感器和 V REFINT 只能出现在主 ADC1 中。

1.6转换时序图

1.7DMA设置

因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用
DMA ,这可以避免丢失已经存储在 ADC_DR 寄存器中的数据。
只有在规则通道的转换结束时才产生 DMA 请求,并将转换的数据从 ADC_DR 寄存器传输到用户
指定的目的地址。
注: 只有 ADC1 ADC3 拥有 DMA 功能。由 ADC2 转化的数据可以通过双 ADC 模式,利用 ADC1
DMA 功能传输。

1.8ADC通道

// STM32F103C8T6 的ADC1 通道有10路,分别是:
// 10 脚PA0 ADC12_IN0
// 11 脚PA1 ADC12_IN1
// 12 脚PA2 ADC12_IN2
// 13 脚PA3 ADC12_IN3
// 14 脚PA4 ADC12_IN4
// 15 脚PA5 ADC12_IN5
// 16 脚PA6 ADC12_IN6
// 17 脚PA7 ADC12_IN7
// 18 脚PA8 ADC12_IN8
// 19 脚PA9 ADC12_IN9
// ADC12 意为可配成ADC1或ADC2,不是有ADC12

2心态搞崩

。。。。。经过实验测试,TMD国产山寨货实物是可以模数转换的,但是仿真时proteus识别不了,所以一直是0,暂时没找到解决办法。

3ADC采集

直接采用ADC通道采集,然后将采集结果获取到即可。代码如下。

void ADCx_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_CC2;
	//ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	//ADC_DMACmd(ADC1, ENABLE);	//ADCµÄDMA¹¦ÄÜʹÄÜ
	
	ADC_ResetCalibration(ADC1);
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5 );//ADC1ͨµÀ6,²ÉÑùʱ¼äΪ239.5ÖÜÆÚ	 
	//ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)){}
  ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1))
	{
	}  	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
u16 Get_ADC_Value(u8 ch,u8 times)
{
	u8 t;
	u16 out;
	u16 temp_val=0;
	//float vol=0;
	
	ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);


	for(t=0;t<times;t++)
	{
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);

		while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC))
		{
		}

	  temp_val+=ADC_GetConversionValue(ADC1);
		//temp_val=ADC_GetConversionValue(ADC1);
		delay_ms(5);
	}
	out=temp_val/times;
	//vol=(float)(temp_val/times)*(3.3/4096);
	//printf("¼ì²âADֵΪ£º%d \r\n",temp_val/times);
	//printf("¼ì²âµçѹֵΪ£º%.2f V \r\n",vol);
	
	//return temp_val/times;
	return out;
}

 main函数里面调用Get_ADC_Value(ADC_Channel_1,10)即可。

4ADC+DMA采集

DMA作为数据自动搬运模块,所以只需要配置好搬运的方式即可,分两部分,首先ADC设置里将DMA使能,然后DMA里对各个参数进行配置。(DMA数据搬运完成可以采用中断方式输出,也可以直接读取,此次采用中断输出的方式)

初始化和调用分为4个步骤:

1ADC初始化

void ADCx_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_CC2;
	//ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	ADC_DMACmd(ADC1, ENABLE);	//ADCµÄDMA¹¦ÄÜʹÄÜ
	
	ADC_ResetCalibration(ADC1);
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5 ); 
	//ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)){}
  ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1))
	{
	}  	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}

 2DMA初始化

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位

这两个要设置为16位的,如果是8位,则输出最大为255.

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位

#include "dma.h"
#include "usart.h"

/******************************************************************
函数名称:MYDMA1_Config()
函数功能:DMA1初始化配置
参数说明:DMA_CHx:DMA通道选择
		 cpar:DMA外设ADC基地址
		 cmar:DMA内存基地址
		 cndtrDMA通道的DMA缓存的大小
备    注:
*******************************************************************/
void MYDMA1_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
	DMA_InitTypeDef DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
	
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存//
	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
	DMA_Init(DMA_CHx, &DMA_InitStructure);  //ADC1匹配DMA通道1
	
	DMA_ITConfig(DMA1_Channel1,DMA1_IT_TC1,ENABLE);	//使能DMA传输中断	
	
	//配置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	

	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA通道
}

   初始化调用如下:

 MYDMA1_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)&currentadc,1);

currentadc为最后数据搬运到的地址,可以设置一个全局变量,然后读取这个数据即可。

3中断控制

/******************************************************************
简介:DMA中断用于完整采样一次(采样1024次),
	  并将其存储于adcx[]缓存数组中,等待后续数据处理
*******************************************************************/	

void DMA1_Channel1_IRQHandler(void) 
{
	if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
	{
		adcx[t]=currentadc;
		t++;
		if(t==NPT)
		{
			t=0;
			adc_flag=1;
			DMA_Cmd(DMA1_Channel1, DISABLE);        //失能DMA
		}
	}
	DMA_ClearITPendingBit(DMA1_IT_TC1);
}

 4主函数while里面还要每次都打开ADC

	while(1)
	{
		ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);		
		v_get=currentadc;
		OLED_ShowNum(20,30,v_get,5,16);//oled????
		OLED_Refresh_Gram();
    }

5定时器+ADC+DMA采集

加入定时器,通过定时器控制ADC进行采集。作用是将上面ADC+DMA里面,主函数中while每次都要重新打开ADC才能开始采集,所以通过定时器的方式,时间到了就可以自动采集,然后触发DMA进行处理。

1ADC初始化

void ADCx_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_CC2;
	//ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel=1;
	ADC_Init(ADC1,&ADC_InitStructure);
	ADC_ExternalTrigConvCmd(ADC1, ENABLE);
	
	ADC_Cmd(ADC1,ENABLE);
	ADC_DMACmd(ADC1, ENABLE);	//ADCµÄDMA¹¦ÄÜʹÄÜ
	
	ADC_ResetCalibration(ADC1);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5 );//ADC1ͨµÀ6,²ÉÑùʱ¼äΪ1.5ÖÜÆÚ	 
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)){}
  ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1))
	{
	}  	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	
  TIM_Cmd(TIM2, ENABLE);
  DMA_Cmd(DMA1_Channel1, ENABLE);
}

2DMA初始化

/******************************************************************
函数名称:MYDMA1_Config()
函数功能:DMA1初始化配置
参数说明:DMA_CHx:DMA通道选择
		 cpar:DMA外设ADC基地址
		 cmar:DMA内存基地址
		 cndtrDMA通道的DMA缓存的大小
备    注:
*******************************************************************/
void MYDMA1_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
	DMA_InitTypeDef DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
	
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存//
	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
	DMA_Init(DMA_CHx, &DMA_InitStructure);  //ADC1匹配DMA通道1
	
	DMA_ITConfig(DMA1_Channel1,DMA1_IT_TC1,ENABLE);	//使能DMA传输中断	
	
	//配置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	

	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA通道
}

3定时器初始化

/******************************************************************
函数名称:TIM2_PWM_Init(u16 arr,u16 psc)
函数功能:定时器2,PWM输出模式初始化函数
参数说明:arr:重装载值
		 psc:预分频值
备    注:通过TIM2-CH2的PWM输出触发ADC采样
*******************************************************************/ 	
void TIM2_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能定时器2时钟
	/*
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
 
   //设置该引脚为复用输出功能,输出TIM2 CH2的PWM脉冲波形	GPIOA.1
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 */
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM2 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
	TIM_OCInitStructure.TIM_Pulse=1000;
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2

	TIM_CtrlPWMOutputs(TIM2, ENABLE);//使能PWM输出
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
	TIM_InternalClockConfig(TIM2);

	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

	TIM_UpdateDisableConfig(TIM2, DISABLE);
}

4初始化调用

u16 T=2000;//定时器2重载值,不能小于PWM的Pluse值
u16 pre=36;//定时器2预分频值
u16 currentadc;//实时采样数据

void Init()
{
	RCC_HSE_Config(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);  //初始化时钟72M
	SysTick_Init(72);//初始化定时器72M
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			//中断分组

	//USART1_Init(115200);//初始化串口1
	
	LED_Init();
	Ext_interrupts_Init();//初始化中断
	OLED_Init();		//OLED

	MYDMA1_Config(DMA1_Channel1,(u32)&ADC1->DR,(u32)&currentadc,1);
	
	//BEEP_Init();
	//TIM4_Init(1000,36000-1);
	TIM4_Init(1,35);	//三角波和噪声频率控制,
	//TIM3_Int_Init(39,71);	//72MHz/40/72=25kHz   25kHz/1024≈25Hz 正弦波频率约为24.5Hz
	TIM2_PWM_Init(T-1,pre-1);	//最大频率72000000/1/2000=3.6KHz
}

5DMA中断配置

/******************************************************************
简介:DMA中断用于完整采样一次(采样1024次),
	  并将其存储于adcx[]缓存数组中,等待后续数据处理
*******************************************************************/	

void DMA1_Channel1_IRQHandler(void) 
{
	if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
	{
		adcx[t]=currentadc;
		t++;
		if(t==NPT)
		{
			t=0;
			adc_flag=1;
			DMA_Cmd(DMA1_Channel1, DISABLE);        //失能DMA
		}
	}
	DMA_ClearITPendingBit(DMA1_IT_TC1);
}


6DMA使能

。。。。特别重要。

主函数while中,要加入DMA使能,否则DMA搬运完一次后就停止了。

	while(1)
	{
		v_get=currentadc;
		OLED_ShowNum(20,30,v_get,5,16);
		OLED_Refresh_Gram();
	
		led0=!led0;
		DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA1-CH1
    }

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪法师解剖鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值