728x90

728x90

Showing posts with label PIC16F818. Show all posts
Showing posts with label PIC16F818. Show all posts

Friday, July 11, 2025

DIY PICMicro Low Pin Count DIP Prototype Board

Overview 

Using a prototype board for micro-controller firmware testing could save time and safer. Putting an on-board device programmer with prototype board could be more satisfy for electronic hobbyists.

I have some PIC18 and PIC16 series of micro-controllers left from previous projects. I don't know what to do with them anymore. So I put them on single board to PIC program testing next time I need them without checking their pin diagram, and wiring them on bread board. 

DIY PICMicro Low Pin Count DIP Prototype Board
PCB Front View

DIY PICMicro Low Pin Count DIP Prototype Board
PCB Back View
 

I designed a PCB with a 

  1. PICKit2 device programmer (with AVR ISP header)
  2. +5VDC and +3.3VDC low drop out power supply
  3.  RS-232 to TTL logic converter
  4. I2C DS1307 RTC and 24LC08 EEPROM 
  5. 4-bit LCD (HD4478)
  6. 3-digit 056'common cathode multiplexing display 
  7. One passive buzzer with transistor driver (using CCP1 PWM output pin of PIC16F876A)
  8. 8-LED that connects to PORTC of PIC16F876A
  9. A 4x4 keypad matrix that connects to PORTB of PIC16F876A
  10. Three analog inputs (one LM35 and two potentiometers) that connect to RA0...RA1 of PIC16F876A. 
  11. A 28-pin IC socket for 28-pin PIC devices
  12. A 20-pin IC socket for 20-pin PIC devices
  13. A 18-pin IC socket for 18-pin PIC devices
  14. A 14-pin IC socket for 14-pin PIC devices
  15. And a 8-pin IC socket for 8-pin PIC devices

This board seem to be a large PCB with two copper layer near a size of an A4 paper that I'm not yet fabricate it. It need a PCB fabrication service.

Schematic

I use Protues VSM Release 8.16 SP3 to design draw its circuit diagram. Some components are not in its original libraries. So I find and download some devices symbol, footprints and 3D objects from snapeda website. I separate its schematic into A4 sheets. 



DIY PICMicro Low Pin Count DIP Prototype Board
Sheet #1

DIY PICMicro Low Pin Count DIP Prototype Board
Sheet #2

DIY PICMicro Low Pin Count DIP Prototype Board
Sheet #3

DIY PICMicro Low Pin Count DIP Prototype Board
Sheet #4

DIY PICMicro Low Pin Count DIP Prototype Board
Sheet #5

This board could fit,

  1. 28-pin PIC microcontrollers: PIC16F876A, PIC16F886, etc.
  2. 20-pin PIC microcontrollers: PIC16F1459(USB), PIC16F690, etc.
  3. 18-pin PIC microcontrollers: PIC16F1827, PIC16F84A, PIC16F818, etc.
  4. 14-pin PIC microcontrollers: PIC16F630, PIC16F676, etc.
  5. 8-pin PIC microcontrollers: PIC12F629, PIC12F675, PIC12F683, etc.

These are some mid-range PIC micro-controllers I have at my own workshop.

Printed Circuit Board (PCB)

This board size is 8.02x6.30 inches that could be a little bit expensive to order from any professional PCB fabrication service. But if we need to use it with classmate or friend the share cost is cheaper.

DIY PICMicro Low Pin Count DIP Prototype Board
Top Copper non-mirror


DIY PICMicro Low Pin Count DIP Prototype Board
Bottom Copper


DIY PICMicro Low Pin Count DIP Prototype Board
Top Silk

I preview this PCB on an online Gerber viewer software.

DIY PICMicro Low Pin Count DIP Prototype Board
Gerber View Top Copper

DIY PICMicro Low Pin Count DIP Prototype Board
Gerber View Bottom Copper


 Click here to download its design file.


PCB Fabrication

I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
10 PCBs for only 5USD
 

For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.


A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay Instant Quote
 

We can accurately see the preview of fabricated PCB generated by the company's online Gerber file viewer.

PCBWay also offer PCBA assembly service at reasonable price.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay PCB Assembly Service


Monday, August 23, 2021

PIC16F818 Simple Clock Using Multiplexing Display

 

Introduction

An electronics digital clock usually equipped with a Real Time Clock (RTC) IC – for example DS3231 RTC. However we can build a non-complex one’s using internal timer of a microcontroller. This feature doesn’t have time keeping as RTC chip. It lost all its previous timing when it’s powered off.

PIC16F818 Simple Clock Using Multiplexing Display

PIC16F818 Simple Clock Using Multiplexing Display
A commercial sample of DS3231 RTC module from Ali Express

Digital Clock made from Timer0

Timer0 module creates a precise timing when it’s running in timer mode. Timing tick period is configurable by user. A a simple programming example we start with showing timing data on a multiplexing display.

Hardware Preparation

Main controller powered by PIC16F818 microcontroller. It’s suitable for this simple project. Display is assumed to be a dedicated digital clock display in multiplexing type. It’s common anode type as there’s no other option.

PIC16F818 Simple Clock Using Multiplexing Display
Schematic diagram

We don’t use external reset on RA5 pin. Higher nibble of Port A is reserved for digital inputs. These four inputs are minute and second adjustment. Controller clocks from its internal 8MHz oscillator.

Program Preparation

Blueprint of this digital clock project is Timer0 interrupt. Timer0 clock source is internal microcontroller clock with 1:2 prescaler. Timer0 interrupt creates timing tick of 100us. Each time the interrupt occurs Timer0 register is preloaded with 100 to get this timing interval.

Display

Multiplexing display is activated for every 5ms for each digit. A counting register schedule this task. It runs from 0 to 20ms before it rolls back to 0.

Buttons

Four input buttons are,

  • Increasing minute on RA4
  • Decreasing minute on RA5
  • Increasing second on RA6
  • Increasing second on RA7

Each button pressing will be accept by controller after 200ms. This 200ms timer tick create by buttonTime counting variable. Whenever any button is pressed time adjustment is made, and this time counting variable is reset to 0.

Timer0 Interrupt

ISR of PIC16F818 keeps track of Timer0 overflow interrupt. Each time interrupt occurs Timer0 Register (TMR0) preload with value of 100 to gain a 100us timer tick.

/*Interrupt Service Routine*/
void interrupt _myISR(void){
    /*Check Timer0 Interrupt Flag*/
    if(TMR0IE&&TMR0IF){
        TMR0=-100;   
        t0Counter+=1;
        micro_100+=1;
        
        TMR0IF=0;
    }
}

There are two additional timer variable to multiplex display and create a one millisecond time.

Programming

Overall XC8 program made of about 168 lines of code including white spaces and comments.

/*
 * PIC16F818 Simple 7-Segments
 * multiplexing display clock
 */
#include <xc.h>
#include "pic16f818Config.h"
#define MININC RA4
#define MINDEC RA5
#define SECINC RA6
#define SECDEC RA7
#define maxPress 200
void ioInit(void);
void timer0Init(void);
void ssdDisplay(void);
void timeAdjust(void);
unsigned long getOneSecond(void);
unsigned long t0Counter=0;
unsigned long micro_100=0;
unsigned char oneSecond=0;
unsigned char buttonTime=0;
unsigned char minute=12;
char blinker=0xFF;
void main(void){
    unsigned long oneSecond=0;
    ioInit();
    timer0Init();
    while(1){
        oneSecond=getOneSecond();
        timeAdjust();
        ssdDisplay();
    }
}
/*Digital IO and Clock Set Up*/
void ioInit(void){
    /*Clear IO*/
    PORTA=0x00;
    PORTB=0x00;
    /*Port A higher nibble is digital input*/
    TRISA=0xF0;
    /*Port B as output*/
    TRISB=0x00;
    /*Turn on Pull Up Resistors*/
    nRBPU=0;
    /*Clear Analog function on Port A*/
    ADCON1=0x06;
    /*Set up internal oscillator*/
    OSCCONbits.IRCF=0x07;
}
/*Timer 0 Set Up Section*/
void timer0Init(void){
    /*Select internal timer mode*/
    T0CS=0;
    /*Select Timer0 Prescaler*/
    PSA=0;
    /*Select 1:2 Timer0 Rate*/
    OPTION_REGbits.PS=0x00;
    /*Enable Timer0 Interrupt*/
    TMR0IE=1;
    /*Turn On Global Interrupt*/
    GIE=1;
    /*Clear Timer0 Interrupt Flag*/
    TMR0IF=0;
    /*Clear Timer0*/
    TMR0=0;
}
/*Get one second routine*/
unsigned long getOneSecond(void){
    
    if(t0Counter>=10000){
        oneSecond+=1;
        blinker^=0x80;
        blinker|=0b01111111;
        t0Counter=0;
    }
    return oneSecond;
}
/*Multiplexing Display Routine*/
void ssdDisplay(void){
    /*common anode display pattern*/
 char anodePattern[16]={192,249,164,176,153,146,130,248,128,144,136,131,198,161,134,142};
    static unsigned char oneMilli=0;
    if(micro_100>=10){
        oneMilli+=1;
        micro_100=0;
        buttonTime+=1;
    }
    if(oneMilli>20){
        oneMilli=0;
    }
    if(oneSecond>=60){
        oneSecond=0;
        minute+=1;
        if(minute>=60) minute=0;
    }
    /*Driving multiplexing display*/
    switch(oneMilli){
        case 0:
            PORTA=0x00;
            PORTB=anodePattern[oneSecond%10]&blinker;
            PORTA=0x08;
            break;
        case 5:
            PORTA=0x00;
            PORTB=anodePattern[oneSecond/10]&blinker;
            PORTA=0x04;
            break;
        case 10:
            PORTA=0x00;
            PORTB=anodePattern[minute%10]&blinker;
            PORTA=0x02;
            break;
        case 15:
            PORTA=0x00;
            PORTB=anodePattern[minute/10]&blinker;
            PORTA=0x01;
            break;
    }
}
/*Adjusting Time*/
void timeAdjust(void){
    /*Checking digital inputs*/
    if(buttonTime>=maxPress){
        if(MININC==0){
            if(minute<60) minute++;
            buttonTime=0;
        }
        if(MINDEC==0){
            if(minute>0) minute--;
            buttonTime=0;
        }
        if(SECINC==0){
            if(oneSecond<60) oneSecond++;
            buttonTime=0;
        }
        if(SECDEC==0){
            if(oneSecond>0) oneSecond--;
            buttonTime=0;
        }
    }
}
/*Interrupt Service Routine*/
void interrupt _myISR(void){
    /*Check Timer0 Interrupt Flag*/
    if(TMR0IE&&TMR0IF){
        TMR0=-100;   
        t0Counter+=1;
        micro_100+=1;
        
        TMR0IF=0;
    }
}

PIC16F818 C configuration settings store in  “pic16f818Config.h” file.

// PIC16F818 Configuration Bit Settings
// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2      // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

Click here to download source file. Its statistic shown below.

PIC16F818 Simple Clock Using Multiplexing Display
Dashboard in MPLABX



Monday, August 16, 2021

PIC16F818 ADC Read and Display Voltage on 7-Segments Display

 

Introduction

Analog-to-Digital Converter (ADC) operates with analog signal input to microcontroller. Input signal from any device is converted to analog voltage before it’s fed to analog input pin.

Typical reference voltage of ADC is 5V. Maximum direct input voltage to analog input channel must not exceed +5V. For a 10-bit resolution ADC the step voltage is 0.048V.

In this example the controller is programmed to read and show input voltage to ADC input channel 0 – AN0 of PIC16F818. The result will show on a single common anode 7-Segments display.

Programming in MPLABX XC8

There are some additional codes over previous post that convert ADC result to analog voltage, and displaying. A display is one inch in digit size.

PIC16F818 ADC Read and Display Voltage on 7-Segments Display
One inch red common anode seven-segments display

Circuit Design

System runs without external crystal oscillator as it comes with internal oscillator with maximum 8MHz frequency.

PIC16F818 ADC Read and Display Voltage on 7-Segments Display
Schematic Design

AN0 reads input voltage while Port B display the result. Input voltage is varied due to the adjustment of RV1 POT.

Programming

Main program loop keeps track of ADC reading and result updating. Most of source code here is often seen in some previous posts relate to PIC16F818 ADC programming in MPLABX XC8.

/*
 * PIC16F818 Analog Voltage Reading
 */
#include <xc.h>
// PIC16F818 Configuration Bit Settings
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2      // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
void readVoltage(void){
        /*Seven-Segment output data*/
         char displayAnode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
        /*Start the conversion*/
        ADCON0bits.GO_nDONE=1;
        /*When GO_nDONE is clear A/D conversion is completed*/
        while(GO_nDONE);
        /*Wait for some microseconds*/
        for(int i=0;i<1000;i++);
        /*Make a 10-bit A/D converter result*/
        int _L=ADRESL;
        int _H=ADRESH;
        unsigned int adcResult=(_H<<8)+_L;
        /*convert to voltage with +0.1V offset*/
        adcResult=(float)adcResult*5.1/1024;
        /*Show voltage reading*/
        PORTB=displayAnode[adcResult];
}
void main(void){
    /*Select 8MHz internal oscillator*/
    OSCCONbits.IRCF=0x07;
    /*Clear Port A*/
    PORTA=0x00;
    /*Clear Port B*/
    PORTB=0x00;
    /*RA0 analog input*/
    TRISA=0x01;
    /*Port B digital output*/
    TRISB=0x00;
    /*Select internal RC oscillator of A/D converter*/
    ADCON0bits.ADCS=0x01;
    /*Select analog channel 0 - AN0*/
    ADCON0bits.CHS=0x00;
    /*RA0-AN0 analog input, AVDD and AVSS voltage references*/
    ADCON1bits.PCFG=14;
    /*Result is right justified*/
    ADCON1bits.ADFM=1;
    /*Turn on A/D converter module*/
    ADCON0bits.ADON=1;
    /*Main Program Loop*/
    while(1){
        readVoltage();
    }
}

Click here to download zip file of this working example.

Sunday, August 15, 2021

PIC16F818 A/D Converter Bar-graph Example in XC8

 

Introduction

In previous article we have shown about A/D converter module of PIC16F818, and its programming example in MPLABX XC8. We are going to make more programming example using this analog input peripheral module inside this PIC device.

LED bar-graph is a popular LED display that show analog level status of any quantity – analog voltage, water level, and VU indicator. For example an bar-graph display indicating level of remaining energy of a smart phone power bank.

PIC16F818 A/D Converter Bar-graph Example in XC8
A simulation sample of this example

LED Bar-graph Programming Example With A/D Converter

PIC microcontroller will be programmed to display bar-graph output with nine value – from null to its maximum display on. Analog input connects to RA0/AN0 while its analog representation will be displayed on Port B.

Circuit Design

Resistor network and LED bar-graph are more convenience in this programming example. They are packed in one package making an ease of circuit wiring on breadboard.

PIC16F818 A/D Converter Bar-graph Example in XC8
Circuit Diagram

This controller operates from its 8MHz internal oscillator due to economics issue and ease of design. An external reset on MCLR is needed as an aid of controller being stuck.

XC8 Programming for A/D Converter

Most of programming source code is similar to previous example. It excepts an additional lines of code that process bar-graph LED display. C program convert A/D converter 8-bit result pair to its 10-bit resolution.

An additional step converts this 1024 decimal value to 9 value range to fit 8-LED bar-graph display.

/*
 * PIC16F818 A/D Converter Example 2
 * A/D reading bargraph display
 */
#include <xc.h>
#include "pic16f818_config.h"
/*Set oscillator to 8MHz*/
#define _XTAL_FREQ  8000000
void main(void){
    /*LED Bar Graph Representation*/
    char barGraph[9]={0,0b00000001,0b00000011,0b00000111,0b00001111,
        0b00011111,0b00111111,0b01111111,0b11111111};
    /*Select 8MHz internal oscillator*/
    OSCCONbits.IRCF=0x07;
    /*Clear Port A*/
    PORTA=0x00;
    /*Clear Port B*/
    PORTB=0x00;
    /*RA0 analog input*/
    TRISA=0x01;
    /*Port B digital output*/
    TRISB=0x00;
    /*Select internal RC oscillator of A/D converter*/
    ADCON0bits.ADCS=0x01;
    /*Select analog channel 0 - AN0*/
    ADCON0bits.CHS=0x00;
    /*RA0-AN0 analog input, AVDD and AVSS voltage references*/
    ADCON1bits.PCFG=14;
    /*Result is right justified*/
    ADCON1bits.ADFM=1;
    /*Turn on A/D converter module*/
    ADCON0bits.ADON=1;
    /*Main Program Loop*/
    while(1){
        /*Start the conversion*/
        ADCON0bits.GO_nDONE=1;
        /*When GO_nDONE is clear A/D conversion is completed*/
        while(GO_nDONE);
        /*Wait for some microseconds*/
        for(int i=0;i<1000;i++);
        /*Make a 10-bit A/D converter result*/
        int _L=ADRESL;
        int _H=ADRESH;
        unsigned int barValue=(_H<<8)+_L;
        /*Convert A/D result to 9 values*/
        barValue=(float)barValue*9.0/1024;
        /*Display bargraph on Port B*/
        PORTB = barGraph[barValue];
    }
}

Configuration bits keep in C header file “pic16f818_config.h” in the same project directory.

// PIC16F818 Configuration Bit Settings
// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2      // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

User can write these configuration codes within C main program.

Program Testing

This embedded controller program was primarily tested in software simulator.

PIC16F818 A/D Converter Bar-graph Example in XC8
Microcontroller simulation in Proteus 8


Click here to get zip file of this working example.

320x50

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (57) AVR (58) CCS PICC (28) DAC (1) DHT11 (2) Display (106) Distance Sensor (3) DS18B20 (3) dsPIC (3) dsPIC30F1010 (3) dsPIC30F2010 (1) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (68) Interrupt (19) Keil (5) Keypad (10) LCD (48) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (5) 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) PWM (11) RTC (9) Sensor (11) SH1106 (1) Shift Register (11) Shift Registers (3) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (31) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)

tyro-728x90