PIC 16F88 project for birthday gift

Thread Starter

absf

Joined Dec 29, 2010
1,968
I am doing this simple project to display some message on 2x 7 segment LED. But before I did that I decided to use a pic16f88 to display some counting values from 00 to FF in Hex. Once that works I'd continue to modify it to display text.

The schematic looks as follows:
my birthday project.PNG

The software is attached below

C:
#include <pic.h>
/* c2x7seg.c
roll through 16 digit on a dual 7 segment LED display
Display HEX 16 digits on 2x CA LED display.

RB6    -    seg a
RB5 -    seg b
RB4 -    seg c
RB3 -    seg d
RB2 -    seg e
RB1 -    seg f
RB0 -    seg g
RA0 -    Right 7 seg disp
RA1 -    Left  7 seg disp
*/
__CONFIG (WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & CCPRB3 & LVPDIS);
//LVPDIS is needed so that RB3 will not be used by Low voltage programming to use it as I/O
//pin and also be used by CCP1 control.**
//see CONFIG word on datasheet.

unsigned int i,j;
unsigned int disp_value, disp_LED;

const char LEDdigit []=
{
//abcdefg  -    LED segments
0b0000001,        //0
0b1001111,        //1
0b0010010,        //2
0b0000110,        //3
0b1001100,        //4
0b0100100,        //5
0b0100000,        //6
0b0001111,        //7
0b0000000,        //8
0b0000100,        //9
0b0001000,        //"A"
0b1100000,        //"b"
0b0110001,        //"C"
0b1000010,        //"d"
0b0110000,        //"E"
0b0111000};     //"F"

void main()
{
PORTA=0;
PORTB=0;
CMCON=7;        //TURN OFF COMPARATOR
CCP1CON=0;        //disable CCP1 functions ON RB0 & RB3
ANSEL=0;        //TURN OFF ADC
TRISA=0b111110;
TRISB=0b00000000;
disp_value = 0x00;    //start disp at 0x00
disp_LED = 0;        //disp the first digit

while (1==1)
{
    if (disp_LED == 0)
    {
    PORTB=LEDdigit[disp_value & 0x0F] & 0x7F;
    }
    else
    {
    PORTB=LEDdigit[(disp_value >> 4) & 0x0F] & 0x7F;
    }    //fi
  
    TRISA = TRISA ^ 0b000011;    //XOR RA0 and RA1
    PORTA = PORTA & 0b111100;  
    disp_LED = disp_LED ^ 1;    //alternate btw first and second digit

NOP();        // subroutine for 10 ms delay
for (i=0; i<660; i++);    //10ms delay

NOP();
    j=j+1;
    if (25 == j)    //display for 25 times
    {
    disp_value++;    //increment display value
    j = 0;
    }    //fi
}        //end while
}        //end c2x7seg
The problem is that the contents of both digits are the same all the time. It was supposed to display HEX from "00" to "FF"

Any idea what's wrong with the program?

Allen
 

hexreader

Joined Apr 16, 2011
581
Why are you messing around with TRISA so much? Set TRISA = 0bxxxxxx00; at start of code then leave TRISA bits 0 and 1 alone. This makes RA0 and RA1 as outputs and leaves them that way.

For one digit, PORTA = 0bxxxxxx01; for the other digit PORTA = 0bxxxxxx10;

Your logic looks totally illogical to me.

...oh .. and as MaxHeadRoom says, add a delay after display of each individual digit to give your eye time to see each digit.

100 Ohms seems like a very low value for base resistor.

On the plus side.... Thank you for commenting the code well. Not many programmers bother. You get 9/10 just for the good commenting - in my book.
 
Last edited:

MrChips

Joined Oct 2, 2009
30,707
Are you correctly enabling RA0 and RA1 to be active LOW in the proper sequence as required for multiplexing?
It doesn't seem so with lines 67 and 68.
Besides, lines 67 and 68 are in the wrong place in the code.
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
@hexreader
Why are you messing around with TRISA so much? Set TRISA = 0bxxxxxx00; at start of code then leave TRISA bits 0 and 1 alone. This makes RA0 and RA1 as outputs and leaves them that way.

For one digit, PORTA = 0bxxxxxx01; for the other digit PORTA = 0bxxxxxx10;

Your logic looks totally illogical to me.

100 Ohms seems like a very low value for base resistor.

On the plus side.... Thank you for commenting the code well. Not many programmers bother. You get 9/10 just for the good commenting - in my book.
At first glance, TRISA seems weird. But the scope trace confirmed that it works. How should I do it if I freeze the TRISA and just manipulate the RA0/1?

The resistor value of 100R was too low? Would 1K be ok?

Thanks for your compliments on comments I made.

@MrChips-
From the scope trace on RA0 and RA1, I think they are properly lined up or else both of them wouldn't be complementing.

Can you believe that it was actually copied from the book "123 PIC microcontroller experiments for the evil genius" on page 123?

The original PIC used was 16F684 with segment a on RA5 and segment b-g on portC RC5-0. I replaced it with 16F88 so I dont have to split the 7 segments onto 2 ports thus simplifying the HW and SW.

Allen
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
I Don't C but if you showing a changing sequence are you updating too fast maybe?
Max.
From the scope trace, each digit was displayed for 10mS for 25 times before it switches to the next value for displaying.

10mS * 25 *2 = 500mS for each number. Would that be too fast ?

Allen
 

hexreader

Joined Apr 16, 2011
581
Scope trace says that all is OK, but your eyes seem to show a problem.

I can well believe that messing with TRIS will acheive required outputs in a perverse way, but I would need to spend a lot of time trying to work out WHY it works. My brain is simple and wonders why you (or the author) want to do it the hard way.

How are you testing this? Proteus only (good luck with that!) or real hardware, or both?

What is it that you would like from us now?

Might be willing to re-write code (if you tell me which compiler you use) but don't know how soon. Not willing to try to fix what was provided in that book. Too much like trying to polish a turd :)

1K sounds like a good choice of base resistor to me, and is what I would choose, but I am a hobbyist, not an expert.
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,617
From the scope trace, each digit was displayed for 10mS for 25 times before it switches to the next value for displaying.
10mS * 25 *2 = 500mS for each number. Would that be too fast ?
Allen
As I mentioned I don't use C but Usually you have to ensure you turn off the previous digit before displaying the next otherwise you get ghosting of digits.
Max.
 

hexreader

Joined Apr 16, 2011
581
@hexreader
I have seen toggling TRIS used, particularly when sinking current from an LED (e.g., common anode configuration). Here are a couple of Microchip threads that give other examples too.

https://www.microchip.com/forums/m400041.aspx
https://www.microchip.com/forums/m569575.aspx

John
I am fully aware that there are times when manipulating TRIS bits is a sensible thing to do. I just don't see that this is one of those occasions. I am willing to provide simpler solution given time (probably). Seems to me that the PIC is sinking transistor base current, not LED current in this case.

Too lazy to follow those links - so willing to admit to being wrong.
 
Last edited:

Ian Rogers

Joined Dec 12, 2012
1,136
Allen.... I had to put pulldown resistors on that 7 seg module anode connections... Must have a fault in the sim module.

BUT!! You need to rewrite and blank the digits, as its looks crazy!!
 

MMcLaren

Joined Feb 14, 2010
861
I agree... blank the display by either turning off the active-low digit driver lines or the active-low segment driver lines at the beginning of each digit refresh cycle. example;
C:
   void main()
   { static int bumptimer = 0;      // 1-second interval timer
     CMCON=7;                       // TURN OFF COMPARATOR
     CCP1CON=0;                     // disable CCP1 functions ON RB0 & RB3
     ANSEL=0;                       // TURN OFF ADC
     PORTB=0b01111111;              // LED segments 'off'
     PORTA=0b00000001;              // RA1 (tens) digit on (0)
     TRISA=0b11111100;              // RA1-RA0 outputs
     TRISB=0b00000000;              //
     disp_value = 0x00;             // start disp at 0x00

     while(1)                       //
     { PORTB |= 0b01111111;         // blank the display (segments off)
       PORTA ^= 0b00000011;         // toggle digit select lines
       if(PORTA & 1)                // if 'tens' digit selected
         PORTB = LEDdigit[disp_value/16];
       else                         // if 'ones' digit selected
         PORTB = LEDdigit[disp_value%16];
       __delay_ms(2);               // 2-ms on time (250-Hz refresh rate)
       if(bumptimer++ == 499)       // if ~1-second interval
       { bumptimer = 0;             // reset interval timer and
         disp_value++;              // bump display value, 0x00..0xFF
       }                            //
     }                              //
   }                                //
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
Jogging with my friends now. Will change the codes according to Mike's this afternoon.

Will try to breadboard it too. Report back tonight if working.

Thanks all who helped.

Allen
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
@Ian Rogers,
Yes after putting in the pull-down resistors, proteus seems to work better with 2 differnt digits being displayed. Though I cannot make up what they are.:(:D

@MMcLaren,
After replacing the faulty part of the display routine with yours, adding "#define _XTAL_FREQ 4000000", the simualtor finally worked like a star just as described by Ian.

Here is the sim in proteus. The hardware is under construction and should be ready by tomorrow.
Thank you all for helping. I'll start phase 2 as soon as the hardware is working.

iris project 16F88 #2.PNG

Allen
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
As I mentioned I don't use C but Usually you have to ensure you turn off the previous digit before displaying the next otherwise you get ghosting of digits.
Max.
I am actually a beginner in C. The next project I'd do is to make 8x8 matrix LED version of the same project for my wife whose birthday is 2 months away.

This time I would like to use Atmel 40C51 20 pin scalled down 8051 chip and I'd use assembly for this one. Hope 2 months is not to short for me to complete this project.

I also have another traffic light project on TTL chips with count-down timer for my grandson and it was just completed.

Allen
 

Ian Rogers

Joined Dec 12, 2012
1,136
@absf I have code for the pic in C for matrices (plural ) I'll dig it out and you can port it to 8051...I have done a bit on the intel platform (as you know)..
 

Thread Starter

absf

Joined Dec 29, 2010
1,968
I have both 5x7 large matrix as well as the 8x8 small matrix with MAX7219 chip on a PCB.

Which one does your program support?

Allen

20180627_151712.jpg
 

Ian Rogers

Joined Dec 12, 2012
1,136
Any amount...

I use three pins as a serial connection to as many 74hc595 latches for column drivers... Then use a port for common row drivers..

I have managed 32 x 64 pixels without issue...
 
Top