目次
前
次
周波数カウンタA
無線関係のハードウエアをテストする場合には、周波数カウンタを利用します。
マルチメータに周波数カウンタがついていますが、複数の周波数が混在している
場合、同時に2カ所を測定したいことがあります。
2MHz程度までの周波数を測定できればよいので、手持ちのマイコンとLCDを
利用して、自作しました。
回路図は、以下です。
ファームウエアは、Cで簡便に作りました。
#include <avr/io.h>
#include <avr/io8515.h>
#include <avr/interrupt.h>
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
typedef unsigned long ULONG ;
typedef signed char SBYTE ;
typedef signed short SWORD ;
typedef union {
struct {
unsigned char B0:1;
unsigned char B1:1;
unsigned char B2:1;
unsigned char B3:1;
unsigned char B4:1;
unsigned char B5:1;
unsigned char B6:1;
unsigned char B7:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP x_flags ;
#define SFLAG x_flags.BIT.B0
#define TFLAG x_flags.BIT.B1
#define DFLAG x_flags.BIT.B7
#define NO 0
#define YES NO+1
volatile UWORD cnt ;
volatile UBYTE stcnt1 ;
volatile UBYTE s[8] ;
volatile UBYTE lcdx[13] ;
#define LCD_E 2
#define LCD_RW 1
#define LCD_RS 0
#define MASK80 0x80
/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void user_initialize(void);
void lcd_out(void);
void start_timers(void);
void stop_timers(void);
void delay_ms(UWORD x);
void put_lcd_primitive(UBYTE which,UBYTE dat);
void init_lcd(void);
void put_lcd_str(UBYTE r,UBYTE c,UBYTE *ptr);
/*------*/
/* main */
/*------*/
int main(void)
{
ULONG scount ;
UWORD uscnt ;
UWORD lscnt ;
UBYTE i ;
/* disable interrupt */
cli();
user_initialize();
/* enable interrupt */
sei();
/* initialize LCD */
init_lcd();
/* start timers */
start_timers();
/* loop */
while ( ON ) {
/* watch flag */
if ( TFLAG ) {
TFLAG = OFF ;
/* stop timers */
stop_timers();
/* concatenate counter */
scount = TCNT1 + stcnt1 * 65536 ;
/* separate */
uscnt = scount / 10000 ;
lscnt = scount % 10000 ;
/* calculate digits */
*(s+0) = uscnt / 1000 ; uscnt %= 1000 ;
*(s+1) = uscnt / 100 ; uscnt %= 100 ;
*(s+2) = uscnt / 10 ;
*(s+3) = uscnt % 10 ;
*(s+4) = lscnt / 1000 ; lscnt %= 1000 ;
*(s+5) = lscnt / 100 ; lscnt %= 100 ;
*(s+6) = lscnt / 10 ;
*(s+7) = lscnt % 10 ;
/* convert ascii */
for ( i = 0 ; i < 8 ; i++ ) { *(s+i) += '0' ; }
/* copy */
*(lcdx+0) = *(s+0) ;
*(lcdx+1) = *(s+1) ;
*(lcdx+3) = *(s+2) ;
*(lcdx+4) = *(s+3) ;
*(lcdx+5) = *(s+4) ;
*(lcdx+7) = *(s+5) ;
*(lcdx+8) = *(s+6) ;
*(lcdx+9) = *(s+7) ;
/* LCD out */
lcd_out();
/* start timers */
start_timers();
}
}
/* dummy */
return 0 ;
}
void user_initialize(void)
{
/* PORT B */
PORTB = 0b00000000 ; /* 00000000 */
DDRB = 0b11111101 ; /* ooooooio */
/* PORT D */
PORTD = 0b00000000 ; /* 00000000 */
DDRD = 0b11111111 ; /* oooooooo */
/* PORT A */
PORTA = 0b00000000 ; /* 00000000 */
DDRA = 0b11111111 ; /* oooooooo */
/* PORT C */
PORTC = 0b00000100 ; /* 00000000 */
DDRC = 0b11111111 ; /* oooooooo */
/* clear flags */
x_flags.DR = 0 ;
/* initialize timer0 */
{
TCNT0 = 6 ;
TCCR0 = 0 ;
}
/* initialize timer1 */
{
TCNT1 = 0 ;
TCCR1A = 0 ;
TCCR1B = (1 << ICNC1) | (1 << ICES1) ;
}
/* enable timer interrupts */
TIMSK = (1 << TOIE1) | (1 << TOIE0) ;
/* */
*(lcdx+2) = ',' ;
*(lcdx+6) = ',' ;
*(lcdx+10) = 'H' ;
*(lcdx+11) = 'z' ;
*(lcdx+12) = '\0' ;
/* */
cnt = 0 ;
stcnt1 = 0 ;
}
void lcd_out(void)
{
put_lcd_str(0,0,(UBYTE *)lcdx);
}
void delay_ms(UWORD x)
{
UWORD loop ;
while ( x ) {
/* 1000 us */
for ( loop = 0 ; loop < 1000 ; loop++ ) ;
/* decrement */
x-- ;
}
}
/* timer0 interrupt */
ISR(TIMER0_OVF_vect)
{
/* set counter */
TCNT0 = 6 ;
/* increment */
cnt++ ;
/* judge */
if ( cnt == 400 ) {
cnt = 0 ;
TFLAG = ON ;
}
}
/* timer1 interrupt */
ISR(TIMER1_OVF_vect)
{
/* increment */
stcnt1++ ;
}
void start_timers(void)
{
/* prepare */
cnt = 0 ;
stcnt1 = 0 ;
/* */
TCNT0 = 6 ;
TCNT1 = 0 ;
TCCR0 |= (1 << CS00) ;
TCCR1B |= (7 << CS10) ;
}
void stop_timers(void)
{
TCCR0 = 0 ;
TCCR1B &= ~0x07 ;
}
void put_lcd_primitive(UBYTE which,UBYTE dat)
{
/* 0 -> E */
PORTC &= ~(1 << LCD_E) ;
/* RS */
PORTC &= ~(1 << LCD_RS) ;
if ( which ) { PORTC |= (1 << LCD_E) ; }
/* data */
PORTA = dat ;
/* 1 -> E */
PORTC |= (1 << LCD_E) ;
/* 0 -> E */
PORTC &= ~(1 << LCD_E) ;
}
void init_lcd(void)
{
/* initialize hardware */
delay_ms(15) ; /* 25ms */
put_lcd_primitive(OFF,0x30);
delay_ms(5) ; /* 5ms */
put_lcd_primitive(OFF,0x30);
delay_ms(1); /* 1ms */
put_lcd_primitive(OFF,0x30);
delay_ms(1); /* 1ms */
put_lcd_primitive(OFF,0x20);
delay_ms(1); /* 1ms */
/* set function */
put_lcd_primitive(OFF,0x28);
put_lcd_primitive(OFF,0x08);
put_lcd_primitive(OFF,0x01);
delay_ms(2); /* 2ms */
put_lcd_primitive(OFF,0x06);
delay_ms(2); /* 2ms */
put_lcd_primitive(OFF,0x0c);
put_lcd_primitive(OFF,0x02);
put_lcd_primitive(OFF,0x80);
}
void put_lcd_str(UBYTE r,UBYTE c,UBYTE *ptr)
{
UBYTE adr ;
/* check range */
if ( r > 1 ) return ;
if ( c > 15 ) return ;
/* set address */
switch ( r ) {
case 1 : adr = 0x40 ; break ;
case 2 : adr = 0x14 ; break ;
case 3 : adr = 0x54 ; break ;
default : adr = 0x00 ; break ;
}
adr += c ;
adr |= MASK80 ;
put_lcd_primitive(OFF,adr);
while ( *ptr != '\0' ) {
put_lcd_primitive(ON,*ptr);
ptr++ ;
}
}
目次
前
次