单通道:
单次转换非扫描模式
#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);//清除中断标志位
}
}