Learn To Write Code For 8051, Arduino, AVR, dsPIC, PIC, STM32 ARM Microcontroller, etc.
Coding Embedded Controller With C/C++.
Printed Circuit Board (PCB) Project For Electronics Hobbyists.
Frequency meter can be made using a conventional digital ICs with a big size, and complicated circuit connection. A small 8-bit micro-controller could do this job using a low level Assembly language or even a higher level C language.
In this example, I use an 8-bit PIC16F84A micro-controller to count external TTL input pulse. The total count will update for every seconds.
Simulating Program
I use RA4/T0CKI (Timer0 External Clock Input) pin to count external TTL pulse. Since Timer0 is only 8-bit wide the maximum counting is only 255 counts. So I add Timer0 Interrupt to increase the maximum counts. I use XC8 built-in delay function to create a precise 1000 ms (1 second) delay before the summation of external pulse is evaluated. A 16x2 character LCD is suitable for this example.
#include <stdio.h>
#include <xc.h>
#define _XTAL_FREQ 4000000UL
#include "LCD4Bits.h"
void tmr0Init(void){
PORTA=0;
TRISA4=1;
T0CS=1;
T0SE=0;
PSA=1;
OPTION_REGbits.PS=0;
T0IE=1;
GIE=1;
T0IF=0;
}
long TMR0H=0;
void interrupt T0_ISR(void){
if(T0IF){
TMR0H+=1;
T0IF=0;
}
}
int main(void){
unsignedchar freq[10];
uint32_t temp=0;
PORTB=0;
TRISB=0;
lcdInit();
tmr0Init();
lcdXY(4,1);
lcdString("PIC16F84A");
lcdXY(1,2);
lcdString("Frequency Meter");
__delay_ms(1000);
lcdCommand(CLEAR_SCREEN);
__delay_ms(5);
lcdXY(4,1);
lcdString("Frequency:");
TMR0H=0;
TMR0=0;
while(1){
__delay_ms(1000);
temp=(TMR0H<<8)+TMR0;
lcdXY(6,2);
sprintf(freq,"%uHz ",temp);
lcdString(freq);
TMR0H=0;
TMR0=0;
}
return0;
}
I can not test it on bread-board because this chip was burn out. And I only have some newer PIC chips. So this program can only be tested using a simulator like Proteus. We can use another PIC chip like the PIC16F628A, and CCS PICC compiler.
Resource Usage
This program require 69.5% of program memory, and 89.7% of data memory. Click here to download this example.
PIC16F84A contains 68 bytes of EEPROM non-volatile memory. It's useful for storing some setting parameters when the MCU is powered off. EEPROM has a slower access time than SRAM and Flash memory. But it has a higher endurance compares to Flash memory. We can erase or write EEPROM up to 10 million times.
Running Program
Using a low level Assembly language or C programming language without EEPROM library, we can access to this memory via these four SRFs,
EEDATA - EEPROM Data Register
EEADR - EEPROM Address Register
EECON1
and EECON2.
EEPROM Control Regsiter 1 (EECON1) has some control bits to read, write, and status checking of EEPROM operations.
EECON1 Register
Using XC8 we can use all of these registers to read or write to EEPROM. However XC8 compiler has a built-in EEPROM library that's very easy to use. To read or write EEPROM, we only need these functions,
EEPROM_READ(address)
EEPROM_WRITE(address, data) .
We just include the "xc.h" header file to call these functions.
Example #1 : EEPROM Writing And Reading
In this example, the program write a set of ASCII characters to EEPROM starting from address 0. Then the controller read them back, and they will be shown on virtual terminal. I use software UART (bit banging) to process serial data.
Without using the EEPROM_WRITE function, we can initialize the EEPROM space. We use the __EEPROM_DATA() macro. The input is an 8 parameters. Each parameters are the 1 byte EEPROM data. For example,
__EEPROM_DATA('H','E','L','L','O','S','I','R'); .
In this example, I initialize some ASCII characters on EEPROM space. Then the program read them back before they are sent over the software UART terminal.
In previous post, I use a character LCD to display distance measurement result. However we can use a 7-Segment display instead because this display has a large size. Seven-Segment display is very very easy to find in most of local electronics components store.
Simulating Program
This program is similar to the previous example. It uses the same timer and pre-scaler. I use timer 0 interrupt timer tick to drive the display. The timer interrupt period is 1µs tick. The distance measurement process use timer 0 interrupt flag counting. The polling method is use for getting the duration of the echo high TTL signal from the distance sensor in µs. Even timer 0 is 8-bit wide we can get a longer duration by using the timer0 interrupt service routine.