本文章续STM32 ADC单通道上继续开发应用
ADC框图
![](https://img-blog.csdnimg.cn/3ea59c17faf44b5c96d6d8543f30a342.png)
- 从最上面模拟看门狗可以出,ADC中断信号分为三种:EOC、JEOC、AWD
- EOC :ADC规则组AD转化完成后发出的信号
- JEOC : ADC注入组AD转化完成后发出的信号、
- AWD :WatchDog发出的信号,通常超过或者低于Watchdog设置的范围,就会发出信号(叫)
- 从中断过程看,我们需要Enable标志位以及配置NVIC
代码解析
- 需要额外设置一个LED用于检测Watchdog是否响应,GPIOA0用于ADC输入信号INx,GPIOA1用于LED点亮。
// 配置ADC模拟信号输入
GPIO_InitTypeDef GPIO_InitTypeDefStructure;
GPIO_InitTypeDefStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitTypeDefStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitTypeDefStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStructure);
// 配置GPIOA1中的LED灯(ADCValue达到预订值就相应灯光)
GPIO_InitTypeDefStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitTypeDefStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStructure);
- 开启Watchdog的中断响应,使用ADC_ITConfig函数
// Analog WatchDog Interrupt Enable
ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);
- 配置WatchDog
// Analog WatchDog Configuration
ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_0);
ADC_AnalogWatchdogThresholdsConfig(ADC1, 3000, 0);
ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);
ADC_AnalogWatchdogSingleChannelConfig : 选择对应的ADC以及通道。
ADC_AnalogWatchdogThresholdsConfig :设置ADC的范围,形如 foo (ADCx,High,Low)。
ADC_AnalogWatchdogCmd :配置WatcgDog模式,选择单通道规则组模式。
- 在启动文件中寻找对应中断响应函数名
void ADC1_2_IRQHandler(void)
{
if(ADC_GetITStatus(ADC1, ADC_IT_AWD) == SET)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);
}
}
完整代码
#include "stm32f10x.h" // Device header
/**
******************************************************************************
1、开启RCC时钟,包括ADC和GPIO的时钟,ADCCLK分频器也需要配置一下
2、配置GPIO,把需要的GPIO配置成模拟输入的模式
3、配置多路开关,将左边的通道接入到右边的规则组表里
4、配置ADC转化器(结构体配置)
5、如果开启看门狗,在中断输出控制里用ITConfig函数开启对应的中断输出。然后在NIVC里配置优先级(选)
6、开启ADC、校准
******************************************************************************
*/
void AD_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72MHz / 6 = 12MHz
// 配置ADC模拟信号输入
GPIO_InitTypeDef GPIO_InitTypeDefStructure;
GPIO_InitTypeDefStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitTypeDefStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitTypeDefStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStructure);
// 配置GPIOA1中的LED灯(ADCValue达到预订值就相应灯光)
GPIO_InitTypeDefStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitTypeDefStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOA, &GPIO_InitTypeDefStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_1);
// 配置规则组
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 55.5 + 12.5 = 68 ADCCLK period
// 配置ADC
ADC_InitTypeDef ADC_InitTypeDefStructure;
ADC_InitTypeDefStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitTypeDefStructure.ADC_DataAlign = ADC_DataAlign_Right; //数字信号右对齐
ADC_InitTypeDefStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //Non Need EXT
ADC_InitTypeDefStructure.ADC_Mode = ADC_Mode_Independent; //单模式ADC
ADC_InitTypeDefStructure.ADC_NbrOfChannel = 1; //有多少个序列
ADC_InitTypeDefStructure.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1, &ADC_InitTypeDefStructure);
// ADC Enable
ADC_Cmd(ADC1, ENABLE);
// Analog WatchDog Configuration
ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_0);
ADC_AnalogWatchdogThresholdsConfig(ADC1, 3000, 0);
ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);
// Analog WatchDog Interrupt Enable
ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);
// NVIC Configure Priority Group
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitTypeDefStructure;
NVIC_InitTypeDefStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitTypeDefStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitTypeDefStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitTypeDefStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitTypeDefStructure);
/* 校准 */
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软中断
}
uint16_t AD_GetValue(void)
{
return ADC_GetConversionValue(ADC1); // 读取寄存器并自动清除EOC标志位
}
void ADC1_2_IRQHandler(void)
{
if(ADC_GetITStatus(ADC1, ADC_IT_AWD) == SET)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);
}
}