您当前的位置:五五电子网电子知识单片机-工控设备AVR单片机AVR 模拟比较器使用范例 正文
AVR 模拟比较器使用范例

AVR 模拟比较器使用范例

点击数:7835 次   录入时间:03-04 11:53:18   整理:http://www.55dianzi.com   AVR单片机

/*
AVR的模拟比较器模块可以用来比较接在AIN0(mega16 PB2的第二功能)和AIN1(PB3)两个引脚的电压大小。
程序操作流程:初始化 >> 开中断 >> 中断服务程序判断,比较结果将会同步到
模拟比较器控制和状态寄存器-ACSR的第五位ACO,检测ACO的值就可以得出比较结果。AIN0<AIN1(ACO=0);AIN0>AIN1(ACO=1)
*/
#include <iom16v.h>
#include <macros.h>
#include "delay.h"

//管脚定义
#define LED0        0     //PB0
#define AIN_P        2     //PB2(AIN0)
#define AIN_N        3     //PB3(AIN1)

//宏定义
#define LED0_ON()        PORTB|= (1<<LED0)   //输出高电平,灯亮
#define LED0_OFF()        PORTB&=~(1<<LED0)    //输出低电平,灯灭

//常量定义
/*
    模拟比较器的正输入端由 ACBG位决定,=0选择AIN0引脚,=1选择1.23V内部能隙基准源

  模拟比较器多工输入 (不常用,因为ADC将无法使用)
    可以选择ADC7..0 之中的任意一个来代替模拟比较器的负极输入端。
    ADC复用器可用来完成这个功能。
    当然,为了使用这个功能首先必须关掉ADC。
    如果模拟比较器复用器使    能位(SFIOR 中的ACME) 被置位,且ADC 也已经关掉(ADCSRA 寄存器的ADEN 为0),
    则可以通过ADMUX 寄存器的MUX2..0 来选择替代模拟比较器负极输入的管脚,
    如果ACME 清零或ADEN 置位,则模拟比较器的负极输入为AIN1。
    
*/
#define AC_ADC0             0x00        //ADC0
#define AC_ADC1             0x01        //ADC1
#define AC_ADC2             0x02        //ADC2
#define AC_ADC3             0x03        //ADC3
#define AC_ADC4             0x04        //ADC4
#define AC_ADC5             0x05        //ADC5
#define AC_ADC6             0x06        //ADC6
#define AC_ADC7             0x07        //ADC7

void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = ~((1<<AIN_P)|(1<<AIN_N)); //作模拟比较器输入时,不可使能内部上拉电阻。
 DDRB = (1<<LED0);                //PB0作输出
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
}


//初始化的步骤,关中断,更改ACSR的值,配置模拟比较器,开中断。
//Comparator initialize
// trigger on: Output toggle
void comparator_init(void)
{
 ACSR = ACSR & 0xF7; //ensure interrupt is off before changing
 //上面一句会使ACIE为零,不允许中断
 ACSR=(1<<ACIE);
  // 使能模拟比较器中断,比较器输出变化即可触发中断,AIN0为正输入端,AIN1为负输入端。
}

#pragma interrupt_handler ana_comp_isr:17
void ana_comp_isr(void)
{
 //analog comparator compare event
     //硬件自动清除ACI标志位
    delay_us(10);
    if ((ACSR&(1<<ACO))==0)    //检测ACO
                               //Bit 5 ACO: 模拟比较器输出    模拟比较器的输出经过同步后直接连到ACO。
        LED0_ON();            //如果AIN0<AIN1(ACO=0),LED亮        
    else
        LED0_OFF();            //否则 LED灭
    delay_ms(200);         //当电压差接近0V时,模拟比较器会产生临界抖动,故延时200mS令肉眼能看到  
}

//call this routine to initialize all peripherals
void init_devICes(void)
{
 //stop errant interrupts until set up
 CLI(); //dISAble all interrupts
 port_init();
 comparator_init();

 MCUCR = 0x00;
 GICR  = 0x00;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void main(void)
{
 init_devices();
 while(1)
 ;
}

/*
程序测试:

       VCC      VCC
        |        |
       | |      | |               
 AIN0--|W|      |W|--AIN1  PB0---R---LED--
       | |      | |                       |
        |        |                        |
       GND      GND                      GND
 
    两个电位器,一端接VCC,一端接地,构成电位器分压电路
    AIN0和AIN1都分别接到电位器的中心抽头。
    PBO输出串电阻驱动LED,高电平有效。
    然后分别旋转电位器,增减抽头的电压,将会发现PB0的输出(LED0)会根据 AIN0/AIN1的电压关系变动
    由于电源纹波,IO电流及外界干扰的影响,当电压差接近0V时,模拟比较器会产生临界抖动,AIN0/AIN1对地并上小电容可以改善这种情况。

[1] [2]  下一页


本文关键字:暂无联系方式AVR单片机单片机-工控设备 - AVR单片机