0

我正在为我的代码寻找一些指导。

#include <mega164a.h>

// Declare your global variables here
#define BUTTON1 PINC7
#define Freq_e 0xEF
#define Freq_B 0x9F
#define Freq_G 0xDE
#define Freq_D 0xBD
#define Freq_A 0xF7
#define Freq_E 0xCF

// Standard Input/Output functions
#include <stdio.h>
#include <delay.h>
#include <stdbool.h>
void USARTInit()
{
    // USART0 initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART0 Receiver: On
    // USART0 Transmitter: On
    // USART0 Mode: Asynchronous
    // USART0 Baud rate: 9600
    UCSR0A = 0x00;
    UCSR0B = 0xD8;
    UCSR0C = 0x06;
    UBRR0H = 0x00;
    UBRR0L = 0x81;

    #asm("sei")
}
 bool button_state()
{
  if (!((PINC & (1 << BUTTON1)) >> BUTTON1))
  {
    delay_ms(30);
   if (!((PINC & (1 << BUTTON1)) >> BUTTON1))
     return true;
  }
  return false;
}
  unsigned char SelectedFreq=0;
/*unsigned char readanalog()
{
    unsigned short val=0;
    while(ADCSRA&(1<<ADSC));
    val=ADCL;
    val+=(ADCH<<8);
    return ADCL;
}
*/
float val1=0.0;
float desirefreqe=329.63;
float desirefreqB=246.94;
float desirefreqG=196;
float desirefreqD=146.83;
float desirefreqA=110;
float desirefreqEs=82.41;
void compfreq(unsigned char SelectedFreq)
{
    float tempfreq=0;
  if(SelectedFreq==0){
     tempfreq=desirefreqe;
  }
  else if(SelectedFreq==1){
     tempfreq=desirefreqB;
  }
   else if(SelectedFreq==2){
     tempfreq=desirefreqG;
  }
   else if(SelectedFreq==3){
     tempfreq=desirefreqD;
  }
   else if(SelectedFreq==4){
     tempfreq=desirefreqA;
  }
   else if(SelectedFreq==5){
     tempfreq=desirefreqEs;
  }
  if(val1>(tempfreq+2)){
   PORTB=0x9c;
  }
  else if(val1<(tempfreq-2)){
   PORTB=0xE2;
  }
  else{
  PORTB=0x81;
  }
}
void closefreq(){
    if(val1>=(desirefreqe-((desirefreqe-desirefreqB)/2))){
       PORTD=Freq_e;
    }
    else if(val1>=(desirefreqB-((desirefreqB-desirefreqG)/2))){
        PORTD=Freq_B;
    }
    else if(val1>=(desirefreqG-((desirefreqG-desirefreqD)/2))){
        PORTD=Freq_G;
    }
     else if(val1>=(desirefreqD-((desirefreqD-desirefreqA)/2))){
        PORTD=Freq_D;
    }
     else if(val1>(desirefreqA-((desirefreqA-desirefreqEs)/2))){
        PORTD=Freq_A;
    }
     else {
        PORTD=Freq_E;
    }
}
/*unsigned char read_adc(unsigned char adc_input) {
    ADMUX = adc_input | ADC_VREF_TYPE;
    // Delay needed for the stabilization of the ADC input voltage
    delay_us(10);
    // Start the AD conversion
    ADCSRA |= (1 << ADSC);
    // Wait for the AD conversion to complete
    while ((ADCSRA & (1 << ADIF)) == 0);

    ADCSRA |= (1 << ADIF);
    return ADCH;
}
*/
unsigned char read_adc1(void)
{
    ADCSRA |= 0b01000000;  //start conversion;
    while (ADCSRA&(0b01000000)); //wait conversion end
    return ADCH;
}
void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
PRR &= ~(1 << PRADC);
//ADMUX=ADC_VREF_TYPE;
ADMUX = 0b10100111; // set ADC0
ADCSRA = 0b10000111; //set ADEN, precale by 128
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRB=(0<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(0<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit7=T Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(1<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRD=(0<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
// State: Bit7=T Bit6=0 Bit5=0 Bit4=0 Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (0<<TOIE2);


// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-15: Off
// Interrupt on any change on pins PCINT16-23: Off
// Interrupt on any change on pins PCINT24-31: Off
EICRA=(0<<ISC21) | (0<<ISC20) | (0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT2) | (0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE3) | (0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);


// USART1 initialization
// USART1 disabled
UCSR1B=(0<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1) | (0<<RXEN1) | (0<<TXEN1) | (0<<UCSZ12) | (0<<RXB81) | (0<<TXB81);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
USARTInit();


while (1)
      {
     // readanalog();
      val1 = read_adc1();
      if( button_state())
      {
        SelectedFreq++;
        SelectedFreq=SelectedFreq%6;
        delay_ms(60);
      }
      if(SelectedFreq==0)
      {
        PORTC=Freq_e;
      }
      else if (SelectedFreq==1)
          {
            PORTC=Freq_B;
          }
      else if (SelectedFreq==2)
          {
            PORTC=Freq_G;
          }
      else if (SelectedFreq==3)
          {
            PORTC=Freq_D;
          }
      else if (SelectedFreq==4)
          {
            PORTC=Freq_A;
          }
       else if (SelectedFreq==5)
          {
            PORTC=Freq_E;
          }
       compfreq(SelectedFreq);
       closefreq();
      }
}

我所需要的只是一个可以从 atmega164 的 PINA1 读取频率的函数,仅此而已,但我不知道如何构建它。非常感谢所有帮助。在这里发布之前,我已经尝试了两个多星期来找到使我的代码工作的答案,但我无法做到。 代码无法从 PINA1 读取频率值

代码现在可以比较一个作为输入频率的值,并将其与 6 个不同节点(e、B、G、D、A、E)的 6 个频率进行比较。程序没有做的是从 PINA1 读取输入频率。

4

1 回答 1

0

一个简单(粗略,但可能可行)的解决方案是随时间计算零交叉。我不确定 CodeVision 库提供什么计时器支持,但我假设您有 1 毫秒的分辨率滴答计数和 1 毫秒的分辨率延迟。如果没有,您将不得不使用计时器外围设备提供自己的。

int measureFrequency( int dc_offset )
{
    int zero_x_count = 0 ;
    
    delayms(1) ;  // align to the tick boundary
    int start = tickms() ;
    int previous_sign  = read_adc1() = dc_offset < 0 ? -1 : 1 ;
    
    // Count zero x for 1 second
    while( tickms() - start < 1000 )
    {
        delayms(1) ;
        int sign  = read_adc1() = dc_offset < 0 ? -1 : 1 ;

        if( sign != previous_sign )
        {
            zero_x_count++ ;
        }
    }
    
    // Frequency = zero-x / 2
    return zero_x_count >> 1 ;
}

dc_offset参数是对应于无信号(静音)的静态 ADC 读数。您可以单独测量它,方法是在不拨弦的情况下随时间取平均值。一种更复杂的方法是使用截止频率非常低的高通 IIR 滤波器(隔直滤波器)实时消除信号中的偏移。

希望读数之间的 1ms 延迟足以防止由于读数中的高频谐波和噪声而导致的错误计数,但您必须进行实验。拨弦的波形很复杂,可能会破坏这种简单的方法。理想情况下,您的输入端有一个模拟抗混叠滤波器,其截止频率约为 500Hz;这将通过去除这些高频分量使其更可靠。

更复杂的数字信号处理 (DSP) 方法包括:

  • 快速傅里叶变换 (FFT) 并找到峰值频率。
  • 为每个字符串频率创建一个数字带通滤波器并测量每个频率的响应。

第二种方法的优点是您实际上可以通过弹奏开放和弦同时调整所有弦。在这种情况下,虽然您测量的不是频率,而是该频率的信号电平。您需要一个非常窄的频带和良好的拒绝,坦率地说,ATMega 可能无法满足它。

于 2021-01-28T19:52:21.480 回答