Ich habe folgenden C Code:
Er ist für ein Gitarrenstimmgerät.Code:/* Jesper Hansen <jesperh@telia.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Simple Digital Guitar Tuner --------------------------- version 1.0 2001-02-12 jesper PIN assignements on the 2323 PB0 High LED PB1 Input pin PB2 Low Led */ #include <io.h> #include <signal.h> #define F_CPU 11059200 // CPU clock frequency #define PRESCALER 64 // CPU prescaler value #define BASE_FREQUENCY (F_CPU/PRESCALER) // counter frequency #define TUNING_FORK_A 440.0 // "base" A #define NOTE_DIFF 1.05946309436 // the 12'th root of 2 #define E_STRING 164.81 // top string (1) #define A_STRING 220.00 #define D_STRING 293.66 #define G_STRING 391.99 #define B_STRING 493.88 #define EH_STRING 659.26 // bottom string (6) // The guitar note span // # # # # # # # # # # //EF G A BC D EF G A BC D E //1 2 3 4 * 5 6 // unsigned int Center_Count[] = { BASE_FREQUENCY/EH_STRING, // High E BASE_FREQUENCY/B_STRING, // B BASE_FREQUENCY/G_STRING, // G BASE_FREQUENCY/D_STRING, // D BASE_FREQUENCY/A_STRING, // A BASE_FREQUENCY/E_STRING, // Low E }; unsigned int Transition_Count[] = { BASE_FREQUENCY/(B_STRING+(EH_STRING-B_STRING)/2), // E to B BASE_FREQUENCY/(G_STRING+(B_STRING-G_STRING)/2), // B to G BASE_FREQUENCY/(D_STRING+(G_STRING-D_STRING)/2), // G to D BASE_FREQUENCY/(A_STRING+(D_STRING-A_STRING)/2), // D to A BASE_FREQUENCY/(E_STRING+(A_STRING-E_STRING)/2), // A to E }; volatile unsigned char count_hi; // overflow accumulator // //timer 0 overflow interrupt // SIGNAL(SIG_OVERFLOW0) { count_hi++; // increment overflow count } //---------------------------------------------------------------------------- // Main Lupe //---------------------------------------------------------------------------- int main(void) { unsigned int i; unsigned int count; //------------------------------ // Initialize //------------------------------ cbi(DDRB, 1); // PB1 is input cbi(PORTB, 1); // no pullups active sbi(DDRB, 0); // PB0 is ouput, High LED sbi(DDRB, 2); // PB2 is ouput, Low LED outp(0x03,TCCR0); // set prescaler to f/64 (172.8 kHz @ 11.0592 MHz) sbi(TIMSK,TOIE0); // enable interrupt on timer overflow asm volatile ("sei"); // global interrupt enable //---------------------------------------------------------------------------- // Let things loose //---------------------------------------------------------------------------- while (1) // loop forever { count = 0; // clear sample count loop_until_bit_is_set(PINB,1); // wait for something to happen // got a high edge // start sampling outp(0,TCNT0); // clear counter count_hi = 0; // clear hi count // sample loop for (i=0;i<32;i++) { while (bit_is_set(PINB,1)) // ignore hi->lo edge transitions if (count_hi > 80) // skip if no edge is seen within break; // a reasonable time while (bit_is_clear(PINB,1)) // wait for lo->hi edge if (count_hi > 80) // skip if no edge is seen within break; // a reasonable time count += (count_hi << 8) + inp(TCNT0); // get counter value outp(0,TCNT0); // clear counter if (count_hi > 80) // skip if counter has accumulated a break; // too high value count_hi = 0; // clear hi count } // initially turn off both leds sbi(PORTB,0); sbi(PORTB,2); if (count_hi <= 80) // if count is reasonable { count = count >> 5; // average accumulated count by dividing with 32 // now we have to find the correct string // go through transition frequencies for (i=0;i<sizeof(Transition_Count)/sizeof(Transition_Count[0]);i++) { if (count < Transition_Count[i]) // stop if lower than this transition count break; } // i now holds the string index // check the count for a match, allowing // 1 extra count "hysteresis" to avoid too // much LED flickering if (count-1 <= Center_Count[i]) // if count <= this string count cbi(PORTB,0); // light "Too High" LED if (count+1 >= Center_Count[i]) // if count >= this string count cbi(PORTB,2); // light "Too Low" LED } } }
Ich benötigen das gleiche Prinzip für einen einfachen Frequenzmesser, der mir die Frequenz per RS232 sendet.
Leider haben mir meine MicrocontrollerC kentnisse um den rest rauszufriemeln.Code:$regfile = "m32def.dat" $crystal = 11059200 Dim I As Integer Dim Count As Integer Dim Count_hi As Byte Config Pinb.1 = Input Portb = &B00000000 Config Timer0 = Timer , Prescale = 64 On Timer0 Ttimer0isr Enable Timer0 Enable Interrupts Do Count = 0 Do If Pinb.1 = 1 Then Exit Do Loop Count_hi = 0 For I = 0 To 31 While Pinb.1 = 1 If Count_hi > 80 Then Exit While Wend While Pinb.1 = 0 If Count_hi > 80 Then Exit While Wend Count = Count_hi + Timer0 Timer0 = 0 Next I Loop Ttimer0isr: Timer0 = 172800 Incr Count_hi Return
Da dies ein (IMHO) sehr interessantes projekt ist wäre es sehr hilfreich wenn ihr mir helfen könntet.
Der dazugehörige schaltplan: http://www.myplace.nu/avr/gtuner/index.htm
Mfg
Tobi







Zitieren
Lesezeichen