STM32 AD转换(非扫描模式)

单通道:

单次转换非扫描模式

#include "stm32f10x.h"                  // Device header

void AD_init(void)
{
	//1:开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2:ADCLK分频
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3:配置GPIO
	GPIO_InitTypeDef GPIO_InitSTRUCT;
	GPIO_InitSTRUCT.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitSTRUCT.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitSTRUCT.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSTRUCT);
	//4:配置多路开关
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);

	//5:配置AD转换器
	ADC_InitTypeDef ADC_InitSTRUCT;
	ADC_InitSTRUCT.ADC_ContinuousConvMode=ENABLE;
	ADC_InitSTRUCT.ADC_DataAlign=ADC_DataAlign_Right ;
	ADC_InitSTRUCT.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitSTRUCT.ADC_Mode=ADC_Mode_Independent;
	ADC_InitSTRUCT.ADC_NbrOfChannel=1;
	ADC_InitSTRUCT.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitSTRUCT);
	//7:开启AD
	ADC_Cmd(ADC1,ENABLE);
	//8:校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
}
uint16_t AD_getvalue(void)
{
	//8:软件触发
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	
	//9:获取转换值
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);
}

连续转换非扫描模式

#include "stm32f10x.h"                  // Device header

void AD_init(void)
{
	//1:开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2:ADCLK分频
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3:配置GPIO
	GPIO_InitTypeDef GPIO_InitSTRUCT;
	GPIO_InitSTRUCT.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitSTRUCT.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitSTRUCT.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSTRUCT);
	//4:配置多路开关
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);

	//5:配置AD转换器
	ADC_InitTypeDef ADC_InitSTRUCT;
	ADC_InitSTRUCT.ADC_ContinuousConvMode=ENABLE;
	ADC_InitSTRUCT.ADC_DataAlign=ADC_DataAlign_Right ;
	ADC_InitSTRUCT.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitSTRUCT.ADC_Mode=ADC_Mode_Independent;
	ADC_InitSTRUCT.ADC_NbrOfChannel=1;
	ADC_InitSTRUCT.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitSTRUCT);
	//7:开启AD
	ADC_Cmd(ADC1,ENABLE);
	//8:校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
	//8:软件触发
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
uint16_t AD_getvalue(void)
{
	//9:获取转换值
	return ADC_GetConversionValue(ADC1);
}

多通道:

单次转换非扫描模式实现AD多通道转换

刚开始存在bug,总有一个通道失效,显示其他通道的值。

后来经过弹幕大佬提醒才发现原来是因为忘记把连续模式关掉了即,ADC_InitSTRUCT.ADC_ContinuousConvMode参数应该DISABLE

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
uint16_t advalue1=0,advalue2=0,advalue3=0,advalue4=0;
void attention(void);
void beep(uint16_t advalue2);
int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	AD_init();
	OLED_ShowString(1,1,"ADvalue:");
	while (1)
	{
		advalue1=AD_getvalue(ADC_Channel_0);
		advalue2=AD_getvalue(ADC_Channel_1);
		advalue3=AD_getvalue(ADC_Channel_2);
		advalue4=AD_getvalue(ADC_Channel_3);
		Delay_ms(100);
		OLED_ShowNum(1,9,advalue1,4);
		OLED_ShowNum(2,9,advalue2,4);
		OLED_ShowNum(3,9,advalue3,4);
		OLED_ShowNum(4,9,advalue4,4);

		
	}
}

	
#include "stm32f10x.h"                  // Device header

void AD_init(void)
{
	//1:开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//2:ADCLK分频
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//3:配置GPIO
	GPIO_InitTypeDef GPIO_InitSTRUCT;
	GPIO_InitSTRUCT.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitSTRUCT.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
	GPIO_InitSTRUCT.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSTRUCT);
	//4:配置多路开关
	//ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);

	//5:配置AD转换器
	ADC_InitTypeDef ADC_InitSTRUCT;
	ADC_InitSTRUCT.ADC_ContinuousConvMode=DISABLE;
	ADC_InitSTRUCT.ADC_DataAlign=ADC_DataAlign_Right ;
	ADC_InitSTRUCT.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
	ADC_InitSTRUCT.ADC_Mode=ADC_Mode_Independent;
	ADC_InitSTRUCT.ADC_NbrOfChannel=1;
	ADC_InitSTRUCT.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1,&ADC_InitSTRUCT);
	//7:开启AD
	ADC_Cmd(ADC1,ENABLE);
	//8:校准
	ADC_ResetCalibration(ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
}
uint16_t AD_getvalue(uint8_t channel)
{
	ADC_RegularChannelConfig(ADC1,channel,1,ADC_SampleTime_55Cycles5);
	//8:软件触发
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	
	//9:获取转换值
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);
}

ADC模拟看门狗

看门狗初始化模块(调用函数加在ADC_Cmd( ) 函数前面 )

void mywatchdog(void)//模拟看门狗
{
	ADC_AnalogWatchdogSingleChannelConfig(ADC1,ADC_Channel_1);//配置看门狗通道
	ADC_AnalogWatchdogThresholdsConfig(ADC1,3000,1000);//配置触发上下界
	ADC_AnalogWatchdogCmd(ADC1,ADC_AnalogWatchdog_SingleRegEnable);//看门狗使能
	
	ADC_ITConfig(ADC1,ADC_IT_AWD,ENABLE);//开启ADC中断
	//NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置中断优先级分组
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);

}

主函数后面添加中断函数

void ADC1_2_IRQHandler(void)//中断函数都在startup_stm32f10x_md.s中,程序中无需调用,自动触发
	//并不是上下界触发中断,而是ADC转换值在上界以上或下界以下范围内就进入中断
{
	if(ADC_GetITStatus(ADC1,ADC_IT_AWD) == SET)
	{
		num++;
		uint16_t value= AD_getvalue(ADC_Channel_1);
		if(value>3000)//上界		
			TEMP=1;
		else if(value <1000)//下界
			TEMP=2;
		ADC_ClearITPendingBit(ADC1,ADC_IT_AWD);//清除中断标志位
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值