Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

i just wanna share this :) a freq counter using atmega 8 and a 16*2 hitachi lcd

Status
Not open for further replies.

magvi

Member
just wanna share this. i got it working but the problem is that its not *that* precise, but its okay for a start, i guess.. :)
the code

Code:
#define F_CPU 8000000UL
#include <avr/interrupt.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#include <stdlib.h>
#include<avr/io.h>
#include<util/delay.h>
#define rs PB0	
#define en PB2
 

short val,val1,i;
unsigned int presc;
char a[10]; 
char ff[5] = {'F','r','e','q',':'};
void lcddata(char dataout);
void lcdcmd(char cmdout);
void dis_data(char data_value);
void dis_cmd(char cmd_value);
void lcd_init()	;

int main()
{
    DDRD = 0x02;
    DDRB =0xff;
	//counter1 initialization
    TIMSK |= 1<<TICIE1;
	//TCCR1B |= 
	TCCR1B |=(1<<ICES1)|(1 << CS12) | (1 << CS11) | (1 << CS10);
	//counter 0 initialization
    TIMSK |= (1<<TOIE0);
	TCCR0 = (1<<CS02) | (1<<CS00);
	_delay_ms(50);		// delay of 50 mili seconds
    lcd_init();	// fuction for intialize 
	sei();
	while(1)
	{
/*	switch (presc)
	{
     case 1024:
	 	TCCR0 = (1<<CS02) | (1<<CS00);
     case 256:
	    TCCR0 = (1<<CS02);
	case 64:
		TCCR0 = (1<<CS01) | (1<<CS00);
	case 8:
		TCCR0 = (1<<CS01) ;
	case 1:
		TCCR0 = (1<<CS00);
	default :
		TCCR0 = (1<<CS02) | (1<<CS00);

	}*/
	 }

	return 0;
}


ISR(TIMER0_OVF_vect)
{ 
        val =TCNT1;
		TCNT1=0x00;
		TCNT0=0X00;
		TIFR =0x00;
	    val =(val/19.912)*100;
		itoa(val,a,10);
		for(i=0;i<=5;i++)
		{
     dis_data(ff[i]);
	    }
		for(i=0;i<=10;i++)
		{
     dis_data(a[i]);
	    }
		_delay_ms(100);
	
}
void lcd_init()	// fuction for intialize 
{
    dis_cmd(0x83);
	dis_cmd(0x02);		// to initialize LCD in 4-bit mode.
	dis_cmd(0x28);		//to initialize LCD in 2 lines, 5X7 dots and 4bit mode.
	dis_cmd(0x0C);
	dis_cmd(0x06);
	dis_cmd(0x83);
	dis_cmd(0x01);
}
 
void dis_cmd(char cmd_value)
{
	char cmd_value1;
	
	cmd_value1 = cmd_value & 0xF0;		//mask lower nibble because PA4-PA7 pins are used. 
	lcdcmd(cmd_value1);			// send to LCD
 
	cmd_value1 = ((cmd_value<<4) & 0xF0);	//shift 4-bit and mask
	lcdcmd(cmd_value1);			// send to LCD
}						
 
 
void dis_data(char data_value)
{
	char data_value1;
	
	data_value1=data_value&0xF0;
	lcddata(data_value1);
 
	data_value1=((data_value<<4)&0xF0);
	lcddata(data_value1);
}
 
void lcdcmd(char cmdout)
{
	PORTB=cmdout;
	PORTB&=~(1<<rs);
	PORTB|=(1<<en);
	_delay_ms(1);
	PORTB&=~(1<<en);
}
 
void lcddata(char dataout)
{
	PORTB=dataout;
	PORTB|=(1<<rs);
	PORTB|=(1<<en);
	_delay_ms(1);
	PORTB&=~(1<<en);
}

proteus simulation :-
View attachment 65753

real time pic:-
View attachment 65751
 
Last edited:
Please use the CODE tags for your code (I think you used the QUOTE tags) so the formatting is preserved, making your code easier for others to read. :)

It would also help people if you explain the working procedure, ie HOW it measures the frequency.

I only looked in your code for a few seconds but this seems wrong;
val =(val/19.912)*100;

as val is a 16bit short int and would not be divided by 19.912 as that is a float constant. I'm surprised your compiler did not give an error message! Anyway if it compiled if probably compiled to;
val =(val/19)*100;

which is a long way off.
 
Please use the CODE tags for your code (I think you used the QUOTE tags) so the formatting is preserved, making your code easier for others to read. :)

It would also help people if you explain the working procedure, ie HOW it measures the frequency.
Done!!

I only looked in your code for a few seconds but this seems wrong;
val =(val/19.912)*100;

as val is a 16bit short int and would not be divided by 19.912 as that is a float constant. I'm surprised your compiler did not give an error message! Anyway if it compiled if probably compiled to;
val =(val/19)*100;

which is a long way off.
yeah, that was a surprise to me too, but compiler got around it ;) less head ache for me. the compiler is avr GCC.
 
what's with the weird characters on display?
 
that i don't know, its an el-cheapo LCD (yeah , Chinese) the thing has got Chinese characters in its memory. i think its one of it. :(
 
Since the uC's timebase is what is as the reference for your frequency counter, the measurements will only be as accurate and that timebase.

I don't see a crystal in your schematic, so I assume that you are using the uC's internal oscillator. I don't know about that particular chip, but internal RC oscillators are seldom better than 2%, and may be out 5%.

If you want better accuracy, use an external crystal. Good ones can be had with accuracies to better than 10ppm.
 
yeah i used the internal RC oscillator (8MHz) . thermal drifting of xtal (external ) is much more less right?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top