搞了两天,终于可以用M8的模拟比较器实现频率测量[共享]
先说说问题所在:直接用M8内部的模拟比较器进行比较的话,在阈值电压处老出现多次跳变,没办法,只能采用滞回比较器.想了个法子,把M8的内部比较器和另外一个IO实现了滞回比较器.电路图:
1http://cache.amobbs.com/bbs_upload782111/files_9/ourdev_230795.JPG
/*************************************************************************
* AnalogCompa.h
*文件说明:模拟比较器相关的头文件
*编写作者:my_avr
*编写时间:2008年3月13日
**************************************************************************/
#ifndef _ANALOGCOMPA_H_
#define _ANALOGCOMPA_H_ 1
extern volatile unsigned int Pulse;
extern volatile unsigned int Timer;
extern volatile unsigned int Frequency;
extern void AnalogCompaInit(void);
#endif
/**********************************End of file*****************************/
/*************************************************************************
* AnalogCompa.c
*文件说明:模拟比较器的初始化程序和测试程序。
当AIN0(+)的电压大于AIN1(-)的电压时,
模拟比较器的输出(ACO)为高电平,可以选择该电平触发中断的方式:
ACIS1 ACIS0
0 0 比较器输出变化即可产生中断
0 1 保留
1 0 比较器输出的下降沿产生中断
1 1 比较器输出的上升沿产生中断
*编写作者:my_avr
**************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "AnalogCompa.h"
volatile unsigned int Pulse;
volatile unsigned int Timer;
volatile unsigned int Frequency;
/************************************************************************
*函数名称:AnalogCompaInit()
*函数功能:初始化模拟比较器
*输入参数:无
*输出参数:无
*编写作者:my_avr
*编写时间:2008年3月13月
*相关说明:触发中断方式为方式0,即比较器输出的电平变化产生中断
*************************************************************************/
void AnalogCompaInit(void)
{
DDRD&= ~((1<<PD7)|(1<<PD6)); //AIN为输入
PORTD &= ~((1<<PD7)|(1<<PD6)); //AIN上拉电阻关闭
DDRD|= (1<<PD5);
PORTD &= ~(1<<PD5);
SFIOR &= (~(1<<ACME)); //模拟比较器的负极连接AIN1
ACSR|= (1<<ACI); //先清除中断标志位
ACSR&= ~((1<<ACBG)|(1<<ACIS0)|(1<<ACIS1));//设定工作方式
ACSR|= (1<<ACIE); //允许模拟比较器中断
Pulse = 0;
Timer = 0;
Frequency = 0;
}
/************************************************************************
*函数名称:SIGNAL()
*函数功能:模拟比较器中断处理函数
*输入参数:无
*输出参数:无
*编写作者:my_avr
*编写时间:2008年3月13月
*相关说明:
*************************************************************************/
SIGNAL(SIG_COMPARATOR)
{
if ((ACSR & (1<<ACO)) > 0)
{
PORTD |= (1<<PD5);
}
else
{
PORTD &= ~(1<<PD5);
}
Pulse ++;
if (Timer == 0)
{
Timer = 100; //测量1秒钟
Frequency = Pulse;
Pulse = 0;
}
}
/*******************************End of file********************************/
/*************************************************************************
* main.c
*文件说明:主文件
*编写作者:my_avr
*编写时间:2008年3月13日
**************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "AnalogCompa.h"
#include "UART.h"
volatile unsigned char DelayTimer;
/********************************************************************
*函数名称:void TimerInit(void)
*函数功能:初始化定时时钟,T2,CTC模式,10ms自动重载
*输入参数:无
*返回参数:无
*编写作者:my_avr
*编写时间:2007年8月13日
*相关说明:
********************************************************************/
void TimerInit(void)
{
TCNT2= 0x00;
OCR2 = 77;
TIFR|= (1<<OCF2); //清匹配中断标志位
TIMSK |= (1<<OCIE2); //允许匹配中断
TCCR2= (1<<WGM21)|(1<<CS20)|(1<<CS21)|(1<<CS22); //1024分频,CTC模式
/*
Fi = F_CPU(8000) / (OCR0(77+1) * n(1024) ) = 0.1KHz
Ti = 1/Fi = 1/0.1 = 10ms
*/
}
/**********************************************************************
*函数名称:SIGNAL(SIG_OUTPUT_COMPARE2)
*函数功能:T2匹配中断函数,中断一次给延时变量减一
*输入参数:无
*返回参数:无
*编写作者:my_avr
*编写时间:2008年3月13月
*相关说明:
**********************************************************************/
SIGNAL(SIG_OUTPUT_COMPARE2)
{
if (Timer > 0)
{
Timer--;
}
if (DelayTimer > 0)
{
DelayTimer--;
}
}
/************************************************************************
*函数名称:main()
*函数功能:测试函数
*输入参数:无
*输出参数:无
*编写作者:my_avr
*编写时间:2008年3月13月
*相关说明:
*************************************************************************/
int main(viod)
{
unsigned char temp;
DDRB = 0xFF;
DelayTimer = 150;
AnalogCompaInit();
TimerInit();
UARTInit();
sei(); //打开全局中断
while(1) //循环等待中断
{
if (DelayTimer == 0)
{
DelayTimer = 150;
cli();
temp = (unsigned char) Frequency;
sei();
PutByte(0xAA);
PutByte(ACSR);
PutByte(temp);
}
}
}
/******************************End of file********************************/ 有另外一个文件是串口发送的程序,很简单的,就不发上来了.包含几个函数
UARTInit();
PutByte(); 注意电路的AIN0,AIN1,PD5处的电路,其实是一个经典的滞回比较器的电路 最高可以测多高的频率???? 这个电路主要目的是为了测量工频
主要目的是展示怎么处理缓慢变化的交流信号及其测量 这个要顶一下
Marking,谢谢分享。 谢谢分享
页:
[1]