... und hier ist mein Arduino-Frequenzmessgerät bis 6 MHz !
Es kann auch als Zeit-Messgerät zur Bestimmung von ausführungszeiten im us-Bereich genutzt werden.
// ______________________________________________________________________________________________
// ______________________________________________________________________________________________
//
//
// (C) Helmut Weber 2/2015
//
// Frequenzmessgerät 1kHz bis 6MHz
//
// Für Fortgeschrittene:
//
// An Pin 5 werden positive Pulse per Hardware gezählt
// Innerhalb einer vorgegebenen Zeit gezählte Pulse werden
// dann als Frequenz ausgegeben
//
// ______________________________________________________________________________________________
// ______________________________________________________________________________________________
// Makros zum Setzen, Löschen / Testen von Bits
// ______________________________________________________________________________________________
// set bit
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){
*target |= (1<<bit);
};
// clear bit
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){
*target &= ~(1<<bit);
};
// test bit
static inline bool BIT_TEST(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));
static inline bool BIT_TEST(volatile uint8_t *target, uint8_t bit){
return(*target & (1<<bit));
};
unsigned int TIM16_ReadTCNT1( void )
{
unsigned char sreg;
unsigned int i;
/* Save global interrupt flag */
sreg = SREG;
/* Disable interrupts */
cli();
/* Read TCNT1 into i */
i = TCNT1;
/* Restore global interrupt flag */
SREG = sreg;
return i;
}
void TIM16_ClearTCNT1( void )
{
unsigned char sreg;
unsigned int i;
/* Save global interrupt flag */
sreg = SREG;
/* Disable interrupts */
cli();
/* Read TCNT1 into i */
TCNT1=0;;
/* Restore global interrupt flag */
SREG = sreg;
}
void setup() {
Serial.begin(115200);
pinMode(2,OUTPUT);
// Timer 1 wird zum Zähler von Pulsen an Pin 5 (TO1)
TCCR1A =0;
TCCR1B =0;
TCCR1B |=( (1<<CS10) | (1<<CS11) | (1<<CS12) ); // Counter: external clock rising edge
TCNT1 =0;
}
/*
// Messung von Befehlsausführungszeiten
void loop() {
unsigned long m;
unsigned int cnt, tim;
char buf[20];
unsigned long i;
cnt=TIM16_ReadTCNT1();
tim=1000000/cnt;
Serial.println(cnt);
Serial.print("pro loop: ");
sprintf(buf,"%d.%d us\n",tim/10,tim%10);
Serial.print(buf);
m=micros();
m+=100000; // Messung für 100000us
TIM16_ClearTCNT1();
// Messung in 100 ms = 10000us
// Die Pulse werden hier selbst erzeugt.
while (micros()<m) {
//BIT_SET(&PORTD,2); // 3.5us / loop
//BIT_CLEAR(&PORTD,2);
// oder
digitalWrite(2,HIGH); // 13.5 us
digitalWrite(2,LOW);
}
delay(100);
}
*/
// Messung von Frequenzen
unsigned int x=1;
void loop() {
unsigned long m;
unsigned int cnt, tim;
char buf[20];
unsigned long i;
cnt=TIM16_ReadTCNT1();
delay(100);
dtostrf( (float)cnt/(float)x, 8,3,buf);
Serial.print(buf); Serial.println(" kHz "); //Serial.print(cnt); Serial.print(" "); Serial.println(x);
if (cnt<3000) { if (x<1000) x*=10; }
if (cnt>30000) { if (x>1) x/=10; }
m=micros();
if(TIFR1&(1<<TOV1)) { if (x>1) x/=10; TIFR1 |= (1<<TOV1); }
// 100KHz -6MHz
//m+=10000;
m+=(unsigned long)x*(unsigned long)1000;
TIM16_ClearTCNT1();
// Messung in 100 ms = 10000us
// Die Pulse werden hier selbst erzeugt.
while (micros()<m) {
}
}