#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
const uchar seg_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uint cap1=0,cap2=0;
volatile uchar full_time=0,flag=0;
uchar a[6];
uchar i;
void Port_init() //端口初始化
{
PORTA=0X00;DDRA=0XFF;
PORTB=0X00;DDRB=0XFF;
PORTD=0X00;DDRD=0X00;
}
void T1_init() //定时器1初始化
{
TIMSK|=_BV(TICIE1)|_BV(TOIE1);
TCCR1B|=_BV(ICNC1)|_BV(ICES1)|_BV(CS12)|_BV(CS10);
}
void display() //数码管扫描
{
for(i=0;i<6;i++)
{
PORTB=_BV(i);
PORTA=seg_code[a[5-i]];
_delay_ms(1);
}
}
int main(void)
{
Port_init();
T1_init();
sei(); //开总中断
while(1)
{
if(flag==1)
{
if(cap1==0)
cap1=ICR1; //将第一次获得的ICR1值赋给cap1
else
cap2=ICR1; //将第二次获得的ICR1值赋给cap2
switch(full_time)
{
case 0:cap2=cap2-cap1;break; //定时器1没有溢出时获得两次ICR1差值赋给cap2
case 1:if(cap2<=cap1) cap2=65535-cap1+cap2;else break; //发生一次溢出时判断cap2是否小于cap1,如果小于根据计算获得两次差值,否则此数据无效
case 2:break; //溢出次数大于或者等于两次,此数据无效
}
}
TIMSK=0X00; //禁止输入捕获
cap2=4000000*1024/cap2; //将获得的差值,转换成频率值
a
=cap2%10;
cap2/=10;
display();
TCNT1=cap1=cap2=full_time=flag=0; //清零TCNT1和各标志位
}
}
ISR(TIMER1_OVF_vect)
{
full_time++; //溢出次数
}
ISR(TIMER1_CAPT_vect)
{
flag=1; //输入捕获标志
}
此帖出自小平头技术问答
一周热门 更多>