模拟看门狗如何实现?
扫描二维码
随时随地手机看文章
啥是看门狗?
上面大致介绍了常见的独立看门狗的功能及工作流程。那么STM32芯片的模拟看门狗是又怎么回事呢?跟上面提到的独立看门狗有关系吗?它是怎么工作的?
模拟看门狗
如果说没有这个模拟看门狗,而我们又需要对模拟输入信号幅度做实时监测,往往会有两方面的方案。其一,我们通过软件方式,对ADC采样值进行代码轮询。显然,这会大大增加CPU的负荷,而且实时性也难以保证。其二,我们可以考虑额外设计硬件监控电路。比方,将模拟输入外接两个比较器,将模拟信号与外部产生的上下边界比较阈值进行比较(如下图),从而产生中断信号给单片机也能实现类似的实时功能需求。
模拟看门狗在哪里?
有啥工程应用价值?
供电电源超界检测。在产品开发中,常常需要实现较为智能的电源诊断。在一个产品的关键功能链中,电源是否异常往往需要格外关注。通常需要相应的诊断检测电路,以检测设备电源电压是否超出限定值,如超出限定值需做出诊断报警。这在工业产品、汽车电子、医疗器械中都有明确强制要求。
实现控制环路fail-safe模式。比如一个控制系统根据采集到的传感器信号来控制阀门的开度,以实现流量控制。或者一个速度控制系统,如果传感器信号异常,需要马上将设备置于功能安全状态,以避免造成经济损失或者带来人身伤害。还比如一个电机转速控制系统,如果电流传感器值超限,需要马上让电机停机等。
其实,需要做模拟监测的场合还很多,这里不多做列举。
代码怎么写呢?
static void ADC_Config(void){ ADC_ChannelConfTypeDef sConfig; ADC_AnalogWDGConfTypeDef AnalogWDGConfig;
/* 初始化 */
AdcHandle.Instance = ADCx;
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; /* 异步时钟模式,时钟不分频 */
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; /* 12位 */
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* 右对齐模式 */
AdcHandle.Init.ScanConvMode = DISABLE; /* Sequencer
disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC标志指示转换结束 */
AdcHandle.Init.LowPowerAutoWait = DISABLE; /* 自动延迟转换功能禁用 */
AdcHandle.Init.ContinuousConvMode = DISABLE; /* 禁用连续模式,单次模式 */
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.NbrOfDiscConversion = 1;
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T3_TRGO; /* Timer 3 触发 */
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; /* 软件触发 */
AdcHandle.Init.DMAContinuousRequests = ENABLE; /* DMA 循环模式使能 */
AdcHandle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* 如溢出DR寄存器将被最后的转换结果覆盖 */
AdcHandle.Init.OversamplingMode = DISABLE; /* 禁用过采样 */
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* 初始化错误处理 */
Error_Handler();
}
/* 如ADC转换超出所设模拟看门狗窗口,则考虑到IT在每次ADC转换后发生,*/
/* 请选择足够长的采样时间和ADC时钟,以免在IRQHandler中产生开销。*/
sConfig.Channel = ADC_CHANNEL_5; /* 通道选择 */
sConfig.Rank = ADC_REGULAR_RANK_1; /* Rank 选择 */
sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; /* 采样时间 */
sConfig.SingleDiff = ADC_SINGLE_ENDED; /* 单端输入模式 */
sConfig.OffsetNumber = ADC_OFFSET_NONE; /* 无偏移 */
sConfig.Offset = 0; /* 偏移禁用,该值无用 */
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* 通道配置错误处理 */
Error_Handler();
}
/* 设置模拟看门狗阈值 */
/* Analog watchdog 1 模拟看门狗配置 */
AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_ALL_REG;
AnalogWDGConfig.Channel = ADCx_CHANNELa;
AnalogWDGConfig.ITMode = ENABLE;
AnalogWDGConfig.HighThreshold = (RANGE_12BITS * 5/8);
AnalogWDGConfig.LowThreshold = (RANGE_12BITS * 1/8);
if (HAL_ADC_AnalogWDGConfig(&AdcHandle, &AnalogWDGConfig) != HAL_OK)
{
/* 配置错误处理 */
Error_Handler();
}
}
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
{
/* 看门狗错误处理,这里可以实现fail-safe需求*/
/* 1.比如关闭关键电路 */
/* 2.设置报警标志 */
/* 3.代码尽可能运行短 */
.....
ubAnalogWatchdogStatus = SET;
}
#define ADCCONVERTEDVALUES_BUFFER_SIZE 256 /* 数组aADCxConvertedValues[]大小 */
/* ADC转换结果 */
static __IO uint16_t aADCxConvertedValues[ADCCONVERTEDVALUES_BUFFER_SIZE];
static void start_adc(void)
{
/* 启动ADC以DMA模式运行 */
if (HAL_ADC_Start_DMA(&AdcHandle,
(uint32_t *)aADCxConvertedValues,
ADCCONVERTEDVALUES_BUFFER_SIZE
) != HAL_OK)
{
/* 启动错误处理 */
Error_Handler();
}
}
总结
长按前往图中包含的公众号关注
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!