Ich habe folgenden C Code:
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
}
}
}
Er ist für ein Gitarrenstimmgerät.
Ich benötigen das gleiche Prinzip für einen einfachen Frequenzmesser, der mir die Frequenz per RS232 sendet.
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
Leider haben mir meine MicrocontrollerC kentnisse um den rest rauszufriemeln.
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
Lesezeichen