给你一个电路,刚给你画的,信号整形电路,然后将输出给单片机的T0,用于计数,然后再给你一个数字频率计的程序,AVR的。
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar led_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar position[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar dis_buff[8]; // 显示缓冲区,存放要显示的8个字符的段码值
uchar posit;
uchar time_1ms_ok,display_ok=0;
uchar time0_old,time0_new,freq_time;
uint freq;
void display(void) // 8位LED数码管动态扫描函数
{
PORTA = 0xff;
PORTC = led_7[dis_buff[posit]];
if (posit==5)
PORTC = PORTC | 0x80;
PORTA = position[posit];
if (++posit >=8 )
posit = 0;
}
// Timer 2 output compare interrupt service routine
#pragma interrupt_handler timer2_isr:4
void timer2_isr(void)
{
time0_new = TCNT0; // 1ms到,记录当前T/C0的计数值
time_1ms_ok = 1;
display_ok = ~display_ok;
if (display_ok)
display();
}
void freq_to_disbuff(void) // 将频率值转化为BCD码并送入显示缓冲区
{
uchar i,j=7;
for (i=0;i<=4;i++)
{
dis_buff[j-i] = freq % 10;
freq = freq / 10;
}
dis_buff[2] = freq;
}
void main(void)
{
unsigned char i;
DDRA=0xFF; // LED数码管驱动
DDRC=0xFF;
// T/C0初始化,外部计数方式
TCCR0=0x06; // 外部T0脚下降沿触发计数,普通模式
TCNT0=0x00;
OCR0=0x00;
// T/C2初始化
TCCR2=0x0B; // 内部时钟,32分频(4M/32=125KHz),CTC模式
TCNT2=0x00;
OCR2=0x7C; // OCR2 = 0x7C(124),(124+1)/125=1ms
TIMSK=0x80; // 允许T/C2比较匹配中断
for (i=0;i<=7;i++) dis_buff[i] = 0;
time0_old = 0;
asm("sei"); // 开放全局中断
while (1)
{
if (time_1ms_ok)
{ // 累计T/C0的计数值
if (time0_new >= time0_old) freq = freq + (time0_new - time0_old);
else freq = freq + (256 - time0_old + time0_new);
time0_old = time0_new;
if (++freq_time >= 100)
{
freq_time = 0; // 100ms到,
freq_to_disbuff(); // 将100ms内的脉冲计数值送显示
freq = 0;
}
time_1ms_ok = 0;
}
}
}
这个好象是比赛题目嘛,你这么问,好像有点犯规了。