On a recent China order I bought five 16F72 PIC microcontrollers in 16-SOIC for very cheap, thinking I could find some use for them. They sat in a box for a long time. Lately I've finally got somewhat caught up with work and have a little time for electronics tinkering again, so I decided to wire one up and make sure it wasn't junk or fake.

I used the last of my dipmicro electronics PB1 boards for this project. It appears that these great little boards may have been discontinued. I liked them so much that I may just have to draw up my own and have some made.

Here's the board early on with only RA0 and RA1 wired up. I was blinking some LEDs to make sure the MCU was running. All good so far.

The 20MHz crystal is there because the 16F72 is an old PIC design. It has no internal oscillator, and its onboard peripheral selection is very limited. Not much memory either. It's quite primitive.

Later I'll take the chip off with my hot air rework and put on either a 18F2620 or a 18F27K40, or maybe one of the two "future" 28-pin chips that Microchip has in their list. All these newer chips are really impressive, and they're all pretty much pin-compatible with the old 16F72. Might have to do a little rework on the board, but mostly it'll just work. And I can remove the crystal and run the newer chips much faster with the onboard oscillator.

Starting from left the pinout is RA0-RA5, RB0-RB5 and RC0-RC7. If I change to the modern chips I'll probably move all the RB and RC wires over two pins to open up space for RA6 and RA7.

Here's the board pretty much finished, still gooped with flux. Works perfect. I'll clean it later.

And the bottom side.

Here it is running my LED display board (74HC595 driving anodes and A6276 driving cathodes).

And here it is driving a Shift1 1-wire LCD circuit with RA0 (code below).

1_w_lcd.c

(Scroll down for .h file)

#include "1_w_lcd.h"

char buff[16];

void main(void)
{
  int x;
  adcon1 = 0x06;        //PortA all digital IO
    trisa = trisc = 0x00; //PortA PortC all outs
    porta.0 = 1;
    lcd_init();
  lcd_cls();
  line1;
    lcd_string("PIC 16F72       ");

  while(1){
    for(x=0;;x++){
      itoa(x,buff,16);
      line2;
      lcd_string(buff);
      delay_ms(250);
    }
    }
}

void lcd_cmd(unsigned char letter){
  unsigned char d;
  d = letter;             //do high nybble first
  d = d & 0xf0;           //mask out lower nybble
  d = d | 0b00001000;     //set E bit (3) high and rs bit (2) low
  lcd_nybble(d);          //send first time
  d = d & 0b11110111;     //set E bit (3) low
  lcd_nybble(d);          //send second time

  d = letter << 4;        //now do low nybble
  d = d & 0xf0;           //mask out lower nybble
  d = d | 0b00001000;     //set E bit (3) high and rs bit (2) low
  lcd_nybble(d);          //send first time
  d = d & 0b11110111;     //set E bit (3) low
  lcd_nybble(d);          //send second time
}

void lcd_char(char letter){
  unsigned char d;
  d = letter;             //do high nybble first
  d = d & 0xf0;           //mask out lower nybble
  d = d | 0b00001100;     //set E bit (3) high and rs bit (2) high
  lcd_nybble(d);          //send first time
  d = d & 0b11110111;     //set E bit (3) low
  lcd_nybble(d);          //send second time

  d = letter << 4;        //now do low nybble
  d = d & 0xf0;           //mask out lower nybble
  d = d | 0b00001100;     //set E bit (3) high and rs bit (2) high
  lcd_nybble(d);          //send first time
  d = d & 0b11110111;     //set E bit (3) low
  lcd_nybble(d);          //send second time
}

void lcd_cls()
{
    line1;
    lcd_string("                ");
    line2;
    lcd_string("                ");
}

void lcd_nybble(unsigned char nyb){
  unsigned char x;
  for(x=0;x<7;x++){         //clock out 7 bits
    if((nyb.7 && 0x80) == 1){   //bit 7 high?
      porta.0 = 0;          //yes, clock out a 1
      asm{                  //delay 1us
        nop
        nop
        nop
        nop
      }
      porta.0 = 1;
      delay_us(11);         //delay 15us
    }
    else{                   //bit 7 low
      porta.0 = 0;          //clock out a 0
      delay_us(14);         //delay 15us
      porta.0 = 1;
      delay_us(27);         //delay 30us
    }
    nyb <<= 1;              //shift next bit to bit 7 position
  }
  porta.0 = 0;              //send 8th latch bit
  delay_us(200);            //delay 200us
  porta.0 = 1;
  delay_10us(30);           //delay 300us
}

void lcd_string(char *senpoint)
{
    while(*senpoint != '\0')
    {
        lcd_char(*senpoint);
        senpoint++;
    }
}

void lcd_init(void){
  delay_ms(250);
  lcd_nybble(0x38);     //E high - RS low - send first time
  lcd_nybble(0x30);     //E low - RS low - send second time
  delay_ms(5);
  lcd_nybble(0x38);     //E high - RS low - send first time
  lcd_nybble(0x30);     //E low - RS low - send second time1_w_lcd/E low - RS low - send second time
  delay_us(160);
  lcd_nybble(0x28);     //E high - RS low - send first time
  lcd_nybble(0x20);     //E low - RS low - send second time
  delay_us(160);

  lcd_cmd(0x28);        //set 4-bit mode and 2 lines
  delay_us(160);
  lcd_cmd(0x10);        //cursor move & shift left
  delay_us(160);
  lcd_cmd(0x06);        //entry mode = increment
  delay_us(160);
  lcd_cmd(0x0c);        //display on - cursor blink off
  delay_us(160);
  lcd_cmd(0x01);        //clear display
  delay_ms(30);
}

1_w_lcd.h

#include <system.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#pragma CLOCK_FREQ 20000000
#pragma DATA _CONFIG, _WDTEN_OFF & _HS_OSC & _CP_OFF & _BOREN_OFF

#define line1   lcd_cmd(0x80);
#define line2   lcd_cmd(0xc0);

//function prototypes
void lcd_cmd(unsigned char);
void lcd_char(char);
void lcd_init(void);
void lcd_string(char *);
void lcd_cls(void);
void lcd_nybble(unsigned char);

Next Post Previous Post