历史上的今天
今天是:2024年09月16日(星期一)
2021年09月16日 | STM8单片机ADC模拟看门狗功能实现
2021-09-16 来源:eefocus
看门狗的功能大家都知道,而这个模拟看门狗又是什么东西呢?
简单的说就是这个模拟看门狗可以实时监控ADC采样的数据,当采样的数据值小于设置的最小值或者大于设置的最大值时,单片机就会触发ADC中断。这个在温度监控中非常实用,比如现在要监控设备的温度值,当温度值不在设置范围内的时候,就会自动触发中断,而不需要程序一直去采集ADC通道的值,然后使用软件来判断当前的温度值是否超出正常范围。
官方介绍如下:

下面直接通过代码来演示一下这个模拟看门狗的功能:
#include "adc.h"
#include "main.h"
u16 DATAH = 0; //ADC转换值高8位
u16 DATAL = 0; //ADC转换值低8位
_Bool ADC_flag = 0; //ADC转换成功标志
//AD通道引脚初始化
void ADC_GPIO_Init( void )
{
PD_DDR &= ~( 1 << 3 ); //PD3 设置为输入 电流
PD_CR1 &= ~( 1 << 3 ); //PD3 设置为悬空输入
}
void ADC_CH_Init( u8 ch )
{
char l = 0;
ADC_CR1 = 0x00; //fADC = fMASTER/2, 8Mhz 单次转换,禁止转换
ADC_CSR |= ch ; //控制状态寄存器 选择要 AD输入通道 如:PD2(AIN3)
ADC_CR2 = 0x00; //默认左对齐 读数据时先读高在读低
ADC_TDRL = ( 1 << ch ); //禁止相应通道 施密特触发功能 1左移ch+1位
ADC_CR1 |= 0x01; //使能ADC并开始转换
//设置上限门槛值
ADC_HTRH = ( u8 )( 800 >> ( u8 )2 ); //存放10位数据的高8位
ADC_HTRL = ( u8 )800; //存放10位数据的低8位
//设置下限门槛值
ADC_LTRH = ( u8 )( 300 >> ( u8 )2 ); //存放10位数据的高8位
ADC_LTRL = ( u8 )300; //存放10位数据的低8位
ADC_CSR |= 0x10; // 使能看门狗中断
for( l = 0; l < 100; l++ ); //延时,保证ADC模块的上电完成 至少7us
ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}
//采集PD2电压值
u16 ReadVol_CH3( void )
{
u16 voltage = 0;
while( ( ADC_CSR & 0x80 ) == 0 ); //等待转换结束
if( ADC_CSR & 0x80 )
{
DATAH = ADC_DRH; // 读出ADC结果的高8位
DATAL = ADC_DRL; // 读出ADC结果的低8位
voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024
ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 启动下一次转换
ADC_CSR &= 0x7F;
};
return voltage;
}
//AD中断服务函数 中断号22
#pragma vector = 24 // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void ADC_Handle( void )
{
ADC_CSR &= ~0x40;
//处理温度异常事件
}
ADC使用单次触发模式,然后设置ADC_HTR寄存器为上限报警值,这里设置为800,ADC_LTRL设置下限报警值,这里设置为300,也就是说当ADC的采样值大于800或者小于300的时候,ADC就会产生中断,然后将ADC_CSR寄存器的第4位,也就是AWDIE位设置为1,开启模拟看门狗中断。接下来在主函数中循环读取ADC采样值。
主程序代码如下:
#include "iostm8s103f3.h"
#include "led.h"
#include "adc.h"
void SysClkInit( void )
{
CLK_SWR = 0xe1; //HSI为主时钟源 16MHz CPU时钟频率
CLK_CKDIVR = 0x00; //CPU时钟0分频,系统时钟0分频
}
u16 val1 = 0;
void main( void )
{
SysClkInit();
__asm( "sim" ); //禁止中断
LED_GPIO_Init();
ADC_CH_Init( 3 );
__asm( "rim" ); //开启中断
while( 1 )
{
LED = !LED; //采样
val1 = ReadVol_CH3();
}
}
val1为采样的电压值,全速运行程序,在观察窗口中观察采样值:

当采样电压值在300到800之内时,ADC中断函数不会触发。

当电压值低于300时,ADC中断触发,ADC_CSR寄存器的第6位置位,说明产生了一次模拟看门狗中断。

当采样值大于800时,同样可以产生中断
产生中断后,需要在中断中手动清除AWD标志位。

在这里要特别注意一个问题,就是在设置模拟看门狗的上下限值时,高位寄存器存储的是10位值的高8位,低位寄存器存储的是10位值的低2位。

这里要参考英文手册中的寄存器设置,中文参考手册中这4个寄存器介绍是错误的。如果按照中文手册中的方法设置,模拟看门狗就会永远在中断中出不来。一定要注意。


中文手册中这几个寄存器介绍是错误的
这里的中文参考手册都是在ST官网上下载的,不知道是官方人员疏忽些写错了,还是翻译的时候搞错了。在使用模拟看门狗时一定要注意这个四个寄存器的设置。
史海拾趣
|
完整的工程文件,包括pcb图原理图gerber图,不同时期的版本都有。 花了半年功夫做的。 06年的作品,当时,房价是现在的1/4 没最后做pcb,大家参考吧。 [ 本帖最后由 wangkj 于 2009-12-24 17:04 编辑 ]… 查看全部问答> |
|
求个 .NET Compact Framework 2.0 for CE5.0 的下载地址 求个 .NET Compact Framework 2.0 for CE5.0 的下载地址就是能放到 CE 系统里。然后能安装的那个。我只下到WM5版的。。下不到CE版的 … 查看全部问答> |
|
这是我的程序:当定时器打开后就接收不到数据了,屏蔽掉定时器就可以了!请大侠指教原因所在! /*************************************************************/ /*本设计采用STC89C52单片机 &nb ...… 查看全部问答> |
|
最近老大要我用 ce6.0开发一个程序 要求实现 晃下手机就能关闭闹铃提示,我以前做游戏开发的,应用这方面做起来真的是好无头绪。 我想了 1中设计模式来实现: 就是做一个程序注入内存中时刻监视闹铃是否响 如果响了 然后关闭。不知道 ...… 查看全部问答> |
|
12 446 bytes of readonly code memory 58 bytes of readonly data memory 11 045 bytes of readwrite data memory 12 446个字节代码? 58和11 045是哪个 ...… 查看全部问答> |
|
说白了就是想搞个USB延长设备 想通网线读取远端USB接口的硬盘的数据,希望做过的或者准备搞的或者有兴趣的朋友进来讨论讨论 版主有没什么想法啊?… 查看全部问答> |
|
最近做了2个大功率充电设备(86V100A),用了STM32f103RB做人机接口,可以选择电压、电流、时间等。 考虑到不熟悉这个片子,直接买了淘宝上一位朋友的ARM_PLC板,散件130元。做好的180元。他是上海的,考虑到如果有问题能请教。怕自己焊好了 ...… 查看全部问答> |
|
想买个msp430 launchpad,不知除了官网还有哪里有卖,申请等不了回音,30块很有吸引力!啊啊啊啊啊啊啊啊啊啊啊!淘宝那些坑爹的整套要150! … 查看全部问答> |








