搜索

[学习笔记] AC7811使用ADC门限功能实现主电检测

[复制链接]
324|4
 楼主 | 2020-3-4 15:13 | 显示全部楼层 | 奖励家园币|阅读模式
本帖最后由 JasonLee27 于 2020-3-4 15:13 编辑

软件环境: keil 5.23 SecureCRT
硬件环境: AC7811通用开发板 ATC-LINK

汽车上的电子产品采用汽车蓄电池供电,一般要求的正常工作电压范围是9~16V,过低,过高都需要记录故障。
对于这个功能,我们都会使用ADC来采集计算主电电压值。但如果一直采用软件的方式去判断是否过压欠压,未免太浪费CPU,所以ADC都会提供一个门限功能(AC7811叫模拟看门狗)。
工程师可以设置触发中断的上下限,在采样值未超出门限时,不会有中断,一旦超出后,就会产生ADC中断,这个时候在处理异常,就可以节省很多CPU资源。

我们可以看下7811的模拟看门狗配置说明
WeChat Screenshot_20200304144708.png

这里我使用mode5(连续扫描模式),模拟看门狗选择单规则组通道。

通用开发板上刚好有个ADC_IN1的模拟按键,可以产生不同的AD值,便于我测试
WeChat Screenshot_20200304144843.png
在代码中定义上下门限,以及超出门限后的恢复门限,这里异常门限和恢复门限值不同,是为了防止电压刚好在门限上下范围浮动,造成一直触发中断的问题。
  1. #define AMOHighValue    (3000)
  2. #define AMOLowValue     (1000)

  3. #define AMOLowRecoverValue  (1100)
  4. #define AMOHighRecoverValue (2900)
复制代码
然后是adc中断程序,根据采样值判断当前状态(AC7811并不能直接告诉你是超出上门限还是下门限,so,自己判断吧。根据当前状态重新设置门限,这是因为当采样值超出门限后,是会一直产生中断的,所以,要么产生中断后,关闭中断,要么重新设置门限将当前采样值包含进去,否则会一直产生中断,导致其他程序无法运行(话说我最开始还吐槽过这个设定,觉得这么搞怎么用,后来看了下瑞萨和NXP的,发现貌似别人也差不多。)
  1. void ADC_Callback(void)
  2. {
  3.     if (ADC_GetIntFlag(ADC, ADC_FLAG_AMO))  ///<发生模拟看门狗事件
  4.     {
  5.         if (s_sampleValue[0] > AMOHighValue)   ///<超出上限
  6.         {
  7.             ADC_SetAnalogWatchDogThreshold(ADC, 4095, AMOHighRecoverValue); ///<设置恢复门限
  8.             printf("\r\n too High %d ", s_sampleValue[0]);
  9.         }
  10.         else if (s_sampleValue[0] < AMOLowValue) ///<低于下限
  11.         {
  12.             ADC_SetAnalogWatchDogThreshold(ADC, AMOLowRecoverValue, 0); ///<设置恢复门限
  13.             printf("\r\n too Low %d ", s_sampleValue[0]);
  14.         }
  15.         else if ((s_sampleValue[0] > AMOLowRecoverValue) || (s_sampleValue[0] < AMOHighRecoverValue))   ///<进入正常值
  16.         {
  17.             ADC_SetAnalogWatchDogThreshold(ADC, AMOHighValue, AMOLowValue); ///<重设异常门限
  18.             printf("\r\n Recover %d ", s_sampleValue[0]);
  19.         }
  20.         else
  21.         {
  22.             ///<should not be here
  23.             printf("\r\n error %d", s_sampleValue[0]);
  24.         }
  25.     }
  26.    
  27.     ADC_ClearFlag(ADC, ADC_FLAG_AMO | ADC_FLAG_EOC | ADC_FLAG_IEOC); ///<直接清除所有标志,
  28. }
复制代码
下面是我测试的打印内容
  1. This is adc_sample1 demo

  2. too High 4095
  3. Recover 2088
  4. too High 4095
  5. Recover 2090
  6. too High 4095
  7. Recover 2108
  8. too High 4095
  9. too Low 928
  10. too High 4092
  11. too Low 893
  12. too High 4095
  13. Recover 2101
  14. too High 3164
  15. Recover 2111
  16. too High 4043
复制代码


最后的最后,附上完整的工程(代码有点乱,大家凑合着看)
游客,如果您要查看本帖隐藏内容请回复

使用特权

评论回复
| 2020-3-10 20:46 | 显示全部楼层 | 奖励家园币
非常棒,如果IO不够,有富余的ADC,绝对可以。

使用特权

评论回复
| 2020-3-19 18:32 | 显示全部楼层 | 奖励家园币
操作非常棒。

使用特权

评论回复
| 2020-3-24 11:55 | 显示全部楼层 | 奖励家园币
非常棒的操作

使用特权

评论回复
| 2020-3-26 09:00 | 显示全部楼层 | 奖励家园币
感谢分享

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表