フランクリン発振回路に
周波数カウンタ(AVR使用)
を付けて、
Lメータ (インダクタンスの測定器) を作ってみました。 フランクリン発振回路の発振周波数とC = 1000PF固定より、L (インダクタンス) の値を得て、 LCDに発振周波数とL (インダクタンス) の値を表示します。 インダクタンスは数百mHから数十μHまで測れるようです。 発振周波数は フランクリン発振回路 で調べたように1.5MHz以下までは実用になるようです。 |
コイルの表示 (L) | Lメータの測定値(uH) (L) | Lメータの測定値(Hz) (f) |
---|---|---|
300mH | 326965 | 8802 |
4.7mH | 4733 | 73157 |
4mH | 3848 | 71135 |
2mH | 1933 | 114470 |
1mH | 999 | 159256 |
330μH | 316 | 283097 |
100μH | 100 | 502112 |
10μH | 10 | 1560550 |
回路図
実験風景
How to Compile (コンパイルのしかた) プログラム /* * l_meter.c * フランクリン発振回路の発振周波数とC = 1000PFよりLの値を得て、 * LCDに発振周波数とLの値を表示する。 * ATmega328P * * * Fuses(システムクロック:20MHz) * * 水晶 * EXTENDED 0xFD * HIGH 0xD9 * LOW 0xF7 */ #include <stdio.h> #include <string.h> #include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 20.0E6 /* 20 MHz */ #include <util/delay.h> #define LCD_RS_H PORTC |= _BV(5) #define LCD_E_H PORTC |= _BV(4) #define LCD_RS_L PORTC &= ~_BV(5) #define LCD_E_L PORTC &= ~_BV(4) #define LCD_DB PORTC typedef union tagCOUNT{ unsigned long DWORD; struct{ unsigned short lcount; unsigned short ucount; } WORD; } COUNT; #define PI 3.1415926535897932384626433832795 #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) void delay_us(unsigned short t){while(t--) _delay_us(1);} void delay_ms(unsigned short t){while(t--) _delay_ms(1);} void initLCD(void); void initTIMER(void); void clear_lcd(void); void print_lcd(int x, int y, char *s); unsigned long ltime; unsigned short ucount; COUNT freq; int main(void) { char buffer[32]; int i; double freq2, lx; /* ATmega328P */ DDRB = 0b00000000; /* XTAL2 XTAL1 SCK MISO MOSI ----- ----- ----- */ DDRC = 0b00111111; /* xxxxx RESET RS E DB7 DB6 DB5 DB4 */ DDRD = 0b00000000; /* ----- ----- T1 ----- ----- ----- ----- ----- */ PORTB = 0b00111111; PORTC = 0b00000000; PORTD = 0b11011111; initLCD(); initTIMER(); sei(); clear_lcd(); print_lcd(5, 0, "START"); delay_ms(2000); while(1){ freq2 = freq.DWORD / 1.024; // f = 1 / (2 * Π * √L * √C) // f * f = 1 / (4 * Π * Π * L * C) // L = 1 / (f * f * 4 * Π * Π * C) lx = 1.0E6 / (freq2 * freq2 * 4.0 * PI * PI * 1000.0E-12); sprintf(buffer, "%11lu", (unsigned long)round(freq2)); if(buffer[4] != ' '){ for(i=0; i<3; i++) buffer[i] = buffer[2 + i]; buffer[3] = ','; for(i=0; i<3; i++) buffer[4 + i] = buffer[5 + i]; buffer[7] = ','; } else if(buffer[7] != ' '){ for(i=0; i<3; i++) buffer[4 + i] = buffer[5 + i]; buffer[7] = ','; } strcat(buffer, "Hz"); clear_lcd(); print_lcd(1, 0, buffer); sprintf(buffer, "%11lu", (unsigned long)round(lx)); if(buffer[4] != ' '){ for(i=0; i<3; i++) buffer[i] = buffer[2 + i]; buffer[3] = ','; for(i=0; i<3; i++) buffer[4 + i] = buffer[5 + i]; buffer[7] = ','; } else if(buffer[7] != ' '){ for(i=0; i<3; i++) buffer[4 + i] = buffer[5 + i]; buffer[7] = ','; } strcat(buffer, "uH"); print_lcd(1, 1, buffer); delay_ms(1000); } } void initTIMER(void) { TCCR0A = 0b00000010; /* CTC動作 */ TCCR0B = 0b00000101; /* clk / 1024 */ OCR0A = 20 - 1; /* (1024 / 20MHz) * 20 = 1.024mS */ TIMSK0 = 0b00000010; /* 比較A割り込み要求有効 */ TCCR1B = 0b00000111; /* 外部クロックT1 (PD5)ピンの立ち上がりエッジ */ TIMSK1 = 0b00000001; /* オーバーフロー割り込み許可 */ } /* * TIMER0の割り込み(1.024mS) */ ISR(TIMER0_COMPA_vect) { static unsigned long ot; ++ltime; if((unsigned long)(ltime - ot) >= 1000){ ot = ltime; TCCR1B = 0b00000000; /* カウント停止 */ freq.WORD.lcount = TCNT1; TCNT1 = 0; TCCR1B = 0b00000111; /* 外部クロックT1 (PD5) ピンの立ち上がりエッジ */ freq.WORD.ucount = ucount; ucount = 0; } } ISR(TIMER1_OVF_vect) { ++ucount; } /* DB:4BIT(LOWER) */ void lcd_c4(unsigned char data) { unsigned char tmp; LCD_RS_L; /* RS --> L */ LCD_E_H; /* E --> H */ tmp = (unsigned char)(LCD_DB & 0xf0); tmp |= (unsigned char)(data & 0x0f); LCD_DB = tmp; LCD_E_L; /* E --> L */ delay_us(40); } void lcd_c(unsigned char data) { unsigned char tmp; LCD_RS_L; /* RS --> L */ LCD_E_H; /* E --> H */ tmp = (unsigned char)(LCD_DB & 0xf0); tmp |= (unsigned char)(data >> 4 & 0x0f); LCD_DB = tmp; LCD_E_L; /* E --> L */ delay_us(1); LCD_E_H; /* E --> H */ tmp = (unsigned char)(LCD_DB & 0xf0); tmp |= (unsigned char)(data & 0x0f); LCD_DB = tmp; LCD_E_L; /* E --> L */ delay_us(40); } /* DB:4BIT(LOWER) */ void lcd_d(unsigned char data) { unsigned char tmp; LCD_RS_H; /* RS --> H */ LCD_E_H; /* E --> H */ tmp = (unsigned char)(LCD_DB & 0xf0); tmp |= (unsigned char)(data >> 4 & 0x0f); LCD_DB = tmp; LCD_E_L; /* E --> L */ delay_us(1); LCD_E_H; /* E --> H */ tmp = (unsigned char)(LCD_DB & 0xf0); tmp |= (unsigned char)(data & 0x0f); LCD_DB = tmp; LCD_E_L; /* E --> L */ delay_us(40); } void initLCD(void) { delay_ms(15); lcd_c4(0x03); delay_ms(5); lcd_c4(0x03); delay_us(100); lcd_c4(0x03); lcd_c4(0x02); lcd_c(0x28); /* Function Set */ lcd_c(0x08); /* Display OFF */ lcd_c(0x01); /* Clear Display */ delay_ms(2); lcd_c(0x06); /* Enter Mode */ lcd_c(0x0c); /* Display ON */ } void clear_lcd(void) { lcd_c(0x01); /* Clear Display (& Cursor At Home) */ delay_ms(2); /// lcd_c(0x02); /* Cursor At Home */ /// delay_ms(2); } void cursor_lcd(int x, int y) { lcd_c((unsigned char)(0x80 + y * 0x40 + x)); } void print_lcd(int x, int y, char *s) { cursor_lcd(x, y); while(*s) lcd_d((unsigned char)*s++); } |