728x90

Showing posts with label Meter. Show all posts
Showing posts with label Meter. Show all posts

Friday, November 10, 2023

PIC16F84A Simple Frequency Meter With LCD Using XC8

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.

PIC16F84A Simple Frequency Meter With LCD Using XC8
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.

  1. #include <stdio.h>
  2. #include <xc.h>
  3.  
  4. #define _XTAL_FREQ 4000000UL
  5.  
  6. #include "LCD4Bits.h"
  7.  
  8. void tmr0Init(void){
  9. PORTA=0;
  10. TRISA4=1;
  11. T0CS=1;
  12. T0SE=0;
  13. PSA=1;
  14. OPTION_REGbits.PS=0;
  15. T0IE=1;
  16. GIE=1;
  17. T0IF=0;
  18. }
  19.  
  20. long TMR0H=0;
  21.  
  22. void interrupt T0_ISR(void){
  23. if(T0IF){
  24. TMR0H+=1;
  25. T0IF=0;
  26. }
  27. }
  28.  
  29. int main(void){
  30. unsigned char freq[10];
  31. uint32_t temp=0;
  32. PORTB=0;
  33. TRISB=0;
  34. lcdInit();
  35. tmr0Init();
  36. lcdXY(4,1);
  37. lcdString("PIC16F84A");
  38. lcdXY(1,2);
  39. lcdString("Frequency Meter");
  40. __delay_ms(1000);
  41. lcdCommand(CLEAR_SCREEN);
  42. __delay_ms(5);
  43. lcdXY(4,1);
  44. lcdString("Frequency:");
  45. TMR0H=0;
  46. TMR0=0;
  47. while(1){
  48. __delay_ms(1000);
  49. temp=(TMR0H<<8)+TMR0;
  50. lcdXY(6,2);
  51. sprintf(freq,"%uHz ",temp);
  52. lcdString(freq);
  53. TMR0H=0;
  54. TMR0=0;
  55. }
  56. return 0;
  57. } 

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

PIC16F84A Simple Frequency Meter With LCD Using XC8
Resource Usage

 

This program require 69.5% of program memory, and 89.7% of data memory. Click here to download this example.


 

Saturday, January 2, 2021

PIC18F4550 ADC Simple Digital Volt Meter

The ADC module of PIC18F4550 could read an analog input voltage up to 5 V DC with some DC offset. However, the outside analog voltage fed to the ADC could be greater than 5 V DC by adding a simple voltage divider circuit. 

The voltage divider circuit is very simple, built by two resistors in this case. The output voltage from the divider circuit is smaller than the input according to the dividing factor. The factor created by picking up a different resistances of the selected's. The designer may decide and take a little math calculation using voltage divider theorem to get a specific division factor. 

I don't show the overall process of math calculation here. You can see this post to get a full detail.

A simple DIY DC voltmeter with PIC18F4550
The MCU reads the analog input voltage fed to RA0.

PICC Source Code



Schematic Diagram

A simple DIY DC voltmeter with PIC18F4550
Schematic Diagram

Click here to download the zip file of this example.

If you want a standard PCB for ATMega32 micro-controller, you can order my AVR Microcontroller project from PCBWay with a reasonable price. Click here to get a free $5 credit for new account.

Interfacing ATMega32 to 74HC595 shift register
ATMega16 ATMega32 Experiment Board PCB from PCBWay

 

Friday, May 15, 2020

PIC16F628A 50MHz Frequency Meters Using Timer1 External Counting

CCS PICC have a ready to use example, demonstrating the technique of using timer 1 external pulses counting to make a 50 MHz frequency meter.

The ex_freq.c explained the the process of making frequency meter using timer 1 of PIC16F877 with a one second delay. The output data is presented in serial terminal.

We can use timer 1 of PIC16F628A to count external digital input pulses. With this advantage, we can make a simple frequency meters, measuring the number of pulses per second.

In this example, I switch the CPU to PIC16F628A with the same build-in timer 1. A 16x2 character LCD uses to present the frequency and period.


PIC16F628A Frequency Meters With LCD
PIC16F628A supplied at +5V, clocks at 20 MHz.
Digital Clock pulse feds into pin RB6 Timer 1 Clock In.
SW1 hold the current frequency/period Value,
when shorted to ground

C Source code and simulation file could be download here:

---------------------------------------------------------------------
#include <16F628A.h>
#fuses HS,NOWDT
#use delay(clock=20000000)    
//one instruction=0.2us
#bit t1_overflow=0x0C.0

#define LCD_ENABLE_PIN  PIN_B2                                        
#define LCD_RS_PIN      PIN_B0                                        
#define LCD_RW_PIN      PIN_B1 

#define LCD_DATA4       PIN_B3                                       
#define LCD_DATA5       PIN_B4                                       
#define LCD_DATA6       PIN_B5                                        
#define LCD_DATA7       PIN_B7                                    


#include<LCD.C>

#define holdButton PIN_A0

void main() {
   int cycles8, cycles;
   long freq;
   long freqc_high;
   long freqc_low;
   set_tris_a(0x01);
   lcd_init();
   
   printf(LCD_PUTC,"Sampling!!!!!!");
   while (TRUE) {
      cycles8=0;
      cycles=0;
      freqc_high=0;
      t1_overflow=0;
      set_timer1(0);
      setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
/* ___ wait one second ___  */
      while (cycles!=0xFF) { //true=3, false=4
       cycles8=0; //1 cycle
       //start inner loop
       while (cycles8!=0xFF) { //true=3, false=4
         if (t1_overflow)//true=2,false=3             //----|
            {t1_overflow=0;freqc_high++;}//6 cycles   //    |
         else                                         //    |-- 8 cycles
            {delay_cycles(5);}                        //----|
         delay_cycles(62); //x
         cycles8++; //1
 ///2 cycles to jump to top
 //math: end inner loop
 //math: total inner loop=((3+8+x+1+2)*255 + 4)*255
 //math: if x=62.87781 then inner loops takes 5mil instructions
 //math: if x=62 then inner loop takes 4942920, have to fill 57080 cycles
  }
 delay_cycles(216);      //y
 cycles++;          ///1 cycle
 ///2 cylces to jump to top
 //math: outer=(3+1+y+1+2)*255+4=57080
 //math: y=(57080-4)/255)-(3+1+0+0+1+2)
 //math: if y=216.827450980392156862745098039216 then outer loop cylces is 57080
 //math: if y=216 then outer loop cycles is off by 211 cycles.  z=211
}
      delay_cycles(211);   //z
/* ___ end waiting 1 second ___ */
      setup_timer_1(T1_DISABLED);   
      //turn of counter to prevent corruption while grabbing value
      if (t1_overflow)            
      //check one last time for overflow
          freqc_high++;
      freqc_low=get_timer1();      
      //get timer1 value as the least sign. 16bits of freq counter
      freq=make32(freqc_high,freqc_low);   
      //use new make32 function to join lsb and msb
      //printf("%LU Hz\r\n",freq);      
      //and print frequency
      lcd_gotoxy(1,1);
      printf(LCD_PUTC,"FREQ:");
      lcd_gotoxy(6,1);
      
      float period;
      if(freq==0){
         printf(LCD_PUTC,"Zero Signal");
         printf(LCD_PUTC,"\nT: -------------");
         
      }
      else if(freq<100000)  {
         printf(LCD_PUTC," %LU Hz      ",freq);
         period=1000.0/freq;
         printf(LCD_PUTC,"\nT: %.6f mS  ",period);
      }
      else if(freq<1000000){
         printf(LCD_PUTC," %3.3f kHz       ",(float)freq/1000.0);
         period=1000.0/freq;
         printf(LCD_PUTC,"\nT: %3.6f mS    ",period);
      }
      else{
         printf(LCD_PUTC," %3.3f MHz       ",(float)freq/1000000.0);
         period=1000000.0/freq;
         printf(LCD_PUTC,"\nT: %.6f uS   ",period);
      }
      
      while(input(holdButton)==0);
   }
}

---------------------------------------------------------------------

Simulation Result:

PIC16F628A Frequency Meters Simulation Result
Simulation Result,
signal feed from a virtual signal generator.
The picture show a sampling signal of 8.299 kHz.

If you want a standard PCB for ATMega32 micro-controller, you can order my AVR Microcontroller project from PCBWay with a reasonable price. Click here to get a free $5 credit for new account.

Interfacing ATMega32 to 74HC595 shift register
ATMega16 ATMega32 Experiment Board PCB from PCBWay

Search This Blog

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (34) Analog Comparator (1) Arduino (16) ARM (13) AT89C52 (7) ATMega32 (58) ATMega644P (27) AVR (87) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (4) Display (133) Distance Sensor (3) ds1307 (10) DS18B20 (5) ds3231 (1) ds3232 (2) dsPIC (5) dsPIC30F1010 (3) dsPIC30F2010 (5) EEPROM (5) Environment Sensor (5) ESP32 (1) esp8266 (1) Graphical LCD (2) I2C (38) ILI9341 (1) Input/Output (75) Interrupt (22) Keil (5) Keypad (16) KS0108 (2) LCD (75) LM35 (3) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (10) PIC (108) PIC12F (3) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (13) SH1106 (3) Shift Register (13) Shift Registers (10) Software TWI (2) SPI (39) ST7735 (1) STM32 (11) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (5) STM32CubeIDE (13) STM32F103C8T6 (9) STM32F401CCU6 (1) SysTick (4) temperature sensor (13) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (8) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)