急求正弦波转为方波的方法(利用单片机测1Hz~3MHz的正弦波)

2025-03-06 03:50:49
推荐回答(2个)
回答1:

给你一个电路,刚给你画的,信号整形电路,然后将输出给单片机的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;

     }

 }

}

回答2:

这个好象是比赛题目嘛,你这么问,好像有点犯规了。