所谓模拟比较器就是模拟电平之间的比较,单片机的内部的比较器一般都很简单,没有分立元件组成的比较器精准度高,但是小东东也有大用途,可以用他来检测单片机的电压跌落,也可以比较从传感器采集过的模拟信号……正好ATmega8515内部有模拟比较器,所以懒猫决定来试一下这个功能。Analog Comparator
关于ATmega8515内部比较器由PB2(AIN0)与PB3(AIN1)口输入,模拟比较器对正极 AIN0 的值与负极 AIN1 的值进行比较。当 AIN0 上的电压比负极 AIN1上的电压要高时,模拟比较器的输出 ACO 即置位。比较器的输出可用来触发定时器/计数器 1 的输入捕捉功能。此外,比较器还可触发自己专有的、独立的中断。我们也可以自己选择比较器是以上升沿、下降沿还是交替变化的边沿来触发中断。关于这些可以参看寄存器ACSR.
下面给出程序:
[code="CPP"]
/************************************************
//文件名称:Analog_Comparator.c
//功 能:学习使用单片机内部的模拟比较器
//作 者:懒猫爱飞
//建立日期:2010.11.02
//备 注:MCU-ATmega8515 开发环境-winavr100110
************************************************/
#include <avr/io.h>
#include <inttypes.h> //关于数据类型的一些定义
#include <stdint.h> //同样是一些数据类型的定义
#include <avr/interrupt.h>
#include <util/delay.h>
#define LED_ON(N) PORTC &= ~_BV(N) /*第N个LED灯亮*/
#define LED_OFF(N) PORTC |= _BV(N) /*第N个LED灯灭*/
/************************************************
//函数名称:void port_init(void)
//功 能:端口初始化
//入口参数:NULL
//出口参数:NULL
//备 注:NULL
************************************************/
void port_init(void)
{
PORTA = 0x00;
DDRD = 0x00;
PORTB = 0x00; //关闭弱上拉,
DDRB = 0x00; //PB2,PB3(AIN0/AIN1)设置为输入
//PB3 AIN1 (Analog Comparator Negative Input)
//PB2 AIN0 (Analog Comparator Positive Input)
PORTC = 0xff;
DDRC = 0xff; //LED灯l输出端口
}
/************************************************
//函数名称:int main(void)
//功 能:主程序
//入口参数:NULL
//出口参数:0
//备 注:NULL
************************************************/
int main(void)
{
port_init();
SFIOR |= _BV(PUD); //禁止内部上拉
ACSR |= _BV(ACIE); //允许模拟比较器是断
sei();
while(1);
return 0;
}
/************************************************
//函数名称:ISR(ANA_COMP_vect)
//功 能:模拟比较中断处理程序
//入口参数:中断向量入口地址 ANA_COMP_vect
//出口参数:NULL
//备 注:NULL
************************************************/
ISR(ANA_COMP_vect)
{
if(ACSR & _BV(ACO)) //检测AC0位,判断AN0电压是否大于AN1电压
{
LED_ON(0);
LED_OFF(1);
}
else
{
LED_ON(1);
LED_OFF(0);
}
}
[/code]
其测试电路图如下:
仿真说明:当AIN1低于AIN0时L1(绿灯亮),当AIN1高于AIN0时L2亮(黄灯亮)。