STM8单片机ADC模拟看门狗功能实现

581 阅读4分钟

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

  STM8单片机虽然是8为单片机,但是功能还是挺强大的,今天就来实现一下STM8单片机ADC的模拟看门狗功能。

官方介绍如下: image.png

  看门狗的功能大家都知道,而这个模拟看门狗又是什么东西呢?简单的说就是这个模拟看门狗可以实时监控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为采样的电压值,全速运行程序,在观察窗口中观察采样值:

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

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

image.png

当采样值大于800时,同样可以产生中断 image.png

产生中断后,需要在中断中手动清除AWD标志位。

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

image.png

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

image.png

image.png

中文手册中这几个寄存器介绍是错误的

image.png

image.png

image.png

image.png

这里的中文参考手册都是在ST官网上下载的,不知道是官方人员疏忽些写错了,还是翻译的时候搞错了。在使用模拟看门狗时一定要注意这个四个寄存器的设置。