Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

7-segment digits display only "8"

Status
Not open for further replies.

sanjoy

Member
I made a real time clock using 16f628A+ds3231. The display pattern is like hh:mm:ss. In proteus simulation it is everything ok, the 7-segment displaying as programmed. But when i make the circuit in a real PCB, the all 7-segment digits display "8" in all display, seems digits are blind. To get rid of it i increase the delay from 2ms to 5ms for each digit, but problem persists, in addition to that each individual digits starts to blinks after increasing delay to 5ms.

How this problem of displaying "8" can be solved? if anyone there pls help me. thanks
 
A schematic would help.
Also give us your code.
It is hard to know that is happening with out information.
 
you got a common anode display not a common cathode....,.or you dropped your display and mixed up the numbers......
as ronsimpson stated, reread post #2
 
Thank you for reply. here i attached the proteus schematic and code in the folder named review.
The schematic for PCB drawing is in the schematic_PCB folder. thanks
 

Attachments

  • review.rar
    89.1 KB · Views: 276
  • schematic_PCB.rar
    44.5 KB · Views: 273
Converted from .rar to .zip here.
 

Attachments

  • review.zip
    101.7 KB · Views: 255
  • schematic_PCB.zip
    44.7 KB · Views: 248
Here is the schematics...

schematic pcb.PNG


and here's the code..

Code:
void display_segment(short int b);
void display (unsigned short a, unsigned short p);
void init_ds3231(void);
void write_ds3231(unsigned short address, unsigned short data1);
void select_digit(unsigned short mn, unsigned short hr);
void Buzzer(void);
unsigned short read_ds3231(unsigned short address);
unsigned short read_button(void);
unsigned int ADCRead(unsigned char channel);
unsigned int read_display_temp(void);


void main(){
     unsigned short a, hr, mn, a100, a10, a1, i, key, sec;
     unsigned int tmp_C, Val1;

      TRISA = 0x01;
      TRISB = 0x01;     //INT input at RB0
      TRISC = 0X00;   //SCL-RC3, SDA-RC4
      PORTB = 0xff;
      CMCON = 0x07;               //disable comperators
      ADCON1 = 0b11001110;
      I2C1_Init(100000);
      init_ds3231();

      for(;;){ sec = 0x00;
              if((read_ds3231(0x0F) & 0x01)==0b1) {
                      mn = (0x7F & read_ds3231(0x01));
                      hr = (0x1F & read_ds3231(0x02));

                      //if((read_ds3231(0x0E) & 0b00100000)==0b00100000){
                         tmp_C = read_display_temp();
                         a100 = tmp_C/100;
                         a10 = (tmp_C/10)%10;
                         a1 = tmp_C%10; //}
                   write_ds3231(0x0F, (read_ds3231(0x0F) & 0b11111110));}     //clear flag 0x0F.F0
                   do
                   {
                    display(hr, 1);
                    display(mn, 3);
                   
                    PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
                    PORTA.F4 = 0; PORTA.F5 = 1; PORTC.F2 = 1;
                    display_segment(a100);           //T100(1st digit of TT.T)
                    delay_ms(5);

                    PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
                    PORTA.F4 = 1; PORTA.F5 = 0; PORTC.F2 = 1;
                   display_segment(a10);             //T10  (2nd digit of TT.T)
                   delay_ms(5);

                   PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
                    PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 0;
                    display_segment(a1);             //Tf  (Fraction digit of TT.T)
                    delay_ms(5);

                  if(abs((read_ds3231(0x00))-sec)>0) PORTC.F6=~PORTC.F6; //blinking LED every second
                    sec=read_ds3231(0x00);
                   if(read_button()==1)select_digit(mn, hr);
                   if (mn == 0x00) Buzzer();
                  if((read_ds3231(0x0F) & 0b00000001)==0x01) break;
            } while((read_ds3231(0x0F) & 0b00000001)==0x00);}
              }

void display (unsigned short a, unsigned short p){
             switch(p){
         case 1 :{
                    PORTC.F0 = 0; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 1;
                    PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
                  display_segment(a>>4);  //Hr10
                  delay_ms(5);

                   PORTC.F0 = 1; PORTA.F1 = 0; PORTA.F2 = 1; PORTA.F3 = 1;
                   PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
                  display_segment(a & 0x0F); //Hr1
                  delay_ms(5);} break;
         case 3 : {
                  PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 0; PORTA.F3 = 1;
                  PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
                  display_segment(a>>4);    //mn10
                  delay_ms(5);

                   PORTC.F0 = 1; PORTA.F1 = 1; PORTA.F2 = 1; PORTA.F3 = 0;
                   PORTA.F4 = 1; PORTA.F5 = 1; PORTC.F2 = 1;
                  display_segment(a & 0x0F);      //mn1
                   delay_ms(5); } break;
                   }}
     
void init_ds3231(){
       I2C1_Start();
       I2C1_Wr(0xD0); //address of ds3231 setting 15/4/2015 11:20:20AM,sunday
       I2C1_Wr(0X00);       //address of sec register, 00h
       I2C1_Wr(0x50);       //data of sec register, 50h
       I2C1_Wr(0x59);       //data for minute register at 01h address 59-0101 1001
       I2C1_Wr(0x51);      //data of hr register,0101 0001 =11 at 02h
       I2C1_Wr(0x01);    //data of day register, 01-07,sunday=01 at 03h ok
       I2C1_Wr(0x15);    //data of date register, 01-31, day-15=0001 0101 at 04h
       I2C1_Wr(0x06);    //data of month register, 01-12, june=0000 0110 at 05h
       I2C1_Wr(0x15);    //data of yr register, 00-99, 15=0001 0101 at 06h
       I2C1_Wr(0x00);    //data of alarm1 at 07h
       I2C1_Wr(0x80);    //data of alarm1 at 08h
       I2C1_Wr(0x80);    //data of alarm1 at 09h
       I2C1_Wr(0x80);    //data of alarm1 at 0Ah
       I2C1_Wr(0x00);    //data of alarm2 at 0Bh
       I2C1_Wr(0x00);    //data of alarm2 at 0Ch
       I2C1_Wr(0x00);    //data of alarm2 at 0Dh
       I2C1_Wr(0x25);    //osc running, conv enable, alarm at 00 sec 0010 0101 address 0Eh
       I2C1_Stop(); }
void write_ds3231(unsigned short address, unsigned short data1){
        I2C1_Start();
        I2C1_Is_Idle();
       I2C1_Wr(0xD0);
       I2C1_Is_Idle();
       I2C1_Wr(address);
       I2C1_Is_Idle();
       I2C1_Wr(data1);
       I2C1_Is_Idle();
       I2C1_Stop();}

unsigned short read_ds3231(unsigned short address) {
          unsigned short data1=0;
          unsigned short i;
          I2C1_Start();
          I2C1_Wr(0xD0);
          I2C1_Wr(address);
          I2C1_Repeated_Start();
           I2C1_Wr(0xD1);
           data1 = I2C1_Rd(0u);
           I2C1_Start();
           for(i=0;;i++) {
           if (I2C1_Wr(0xD1)==1){I2C1_start();}
         else break; }
       I2C1_Is_Idle();
       I2C1_Stop();
       return(data1);}
      
void display_segment(short int u){
     switch(u){
         case 0 : PORTB = 0b01111110; break;     //0  ; segment a=PortB.F1, g=PORTB.F7
         case 1 : PORTB = 0b00001100; break;
         case 2 : PORTB = 0b10110110; break;
         case 3 : PORTB = 0b10011110; break;
         case 4 : PORTB = 0b11001100; break;
         case 5 : PORTB = 0b11011010; break;
         case 6 : PORTB = 0b11111010; break;
         case 7 : PORTB = 0b00001110; break;
         case 8 : PORTB = 0b11111110; break;
         case 9 : PORTB = 0b11011110; break;}}   //9
        
void select_digit(unsigned short mn, unsigned short hr){
      unsigned short key;
     PORTA.F4 = PORTA.F5 =PORTC.F2=1;
       for(;;){
       display(mn, 3);
      //PORTA.F3 = PORTA.F2 = 0;
      Delay_ms(1000); //blinking mn10, mn1
      if(PORTA.F0==0){
                      key = read_button();
                     while(key==2){
                            mn = Bcd2Dec(mn);
                            mn++;
                            if(mn > 59) mn = 0;
                            mn = Dec2Bcd(mn);
                            display(mn, 3);
                            delay_ms(300);
                            key = read_button();}}
      display(hr, 1);
      Delay_ms(1000);
      //PORTC.F0 = PORTA.F1 = 0;
      //PORTC.F0 = PORTA.F1 = 1; Delay_ms(1000);  // blinking hr10, hr1
       if(PORTA.F0==0){
                       key = read_button();
                     while(key==2){
                            hr = Bcd2Dec(hr);
                            hr++;
                            if(hr > 12)hr = 0;
                            hr = Dec2Bcd(hr);
                            display(hr, 1);
                            delay_ms(300);
                            key = read_button();}
                    if(key==3){
                             hr=0b00011111&hr;
                             hr=0b01000000|hr;
                             write_ds3231(0x02, hr);
                             write_ds3231(0x01, mn);}}
                    if(key==3)break;}}
                            
unsigned short read_button(void){
         unsigned int Vin=0;
         unsigned short val=0;
         TRISA = 0x01;
         ADCON1 = 0b11001110;
         Vin = ADCRead(0);
         if((Vin > 30) && (Vin < 250)) val = 1;               // select hr or min
         if((Vin > 410) && (Vin < 470)) val = 2;               // increase value of hr or min
         if((Vin > 600) && (Vin < 670)) val = 3;              // come out from change loop
         return val;}
 
unsigned int ADCRead(unsigned char channel){
        unsigned char l_byte, h_byte;
        unsigned int ADR;
         l_byte=h_byte=ADR=0;
        ADCON0 = 0b01000101;
        delay_us(40); //Acquisition Delay
        GO_DONE_bit = 1; //Set GO_DONE bit to start conversion
        while (GO_DONE_bit == 1); //Wait for bit to be cleared
        //If bit is cleared, this means conversion is over
        l_byte = ADRESL;
        h_byte = ADRESH;
        ADR = (h_byte<<8)|l_byte;
        return ADR;}

unsigned int read_display_temp(void){
unsigned short T_fraction, tempU, tempL, test;
unsigned int tmp_C;
T_fraction=tempU=tempL=test=tmp_C = 0;

  tempU = read_ds3231(0x11);
  tempL = (read_ds3231(0x12)) >> 6;
   if (tempU & 0x80){
              tempU = ~tempU + 1;
              PORTC.F5 = 1;}        //whether tmp is negitive
            else PORTC.F5 = 0;
         if (tempL == 0b00) T_fraction = 0;
    else if (tempL == 0b01) T_fraction = 2;
    else if (tempL == 0b10) T_fraction = 5;
    else T_fraction = 7;
         tmp_C  = tempU*10 + T_fraction;
            return (tmp_C);}
           
void Buzzer(){
short int i;
Sound_Init(&PORTC, 1);
  for (i = 0; i < 5; i++) {
    Sound_Play(800, 1000);
         Sound_Play(0, 700);
              if(i==4) Sound_Play(800, 1400);
  }}

Allen
 
This section seems to missing a brace, yes, no?

Code:
unsigned short read_ds3231(unsigned short address) {
          unsigned short data1=0;
          unsigned short i;
          I2C1_Start();
          I2C1_Wr(0xD0);
          I2C1_Wr(address);
          I2C1_Repeated_Start();
           I2C1_Wr(0xD1);
           data1 = I2C1_Rd(0u);
           I2C1_Start();
           for(i=0;;i++) {
           if (I2C1_Wr(0xD1)==1){I2C1_start();}      <-- buried in here
         else break; }
       I2C1_Is_Idle();
       I2C1_Stop();
       return(data1);}

Also, the large select_digit() function seems to be an orphan.

Is this supposed to be working code?

<edit>
Ah... I found it... an example of why I prefer braces on the left...
Code:
unsigned short read_ds3231(unsigned short address)
{ unsigned short data1=0;
  unsigned short i;
  I2C1_Start();
  I2C1_Wr(0xD0);
  I2C1_Wr(address);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1);
  data1 = I2C1_Rd(0u);
  I2C1_Start();
  for(i=0;;i++)
  { if (I2C1_Wr(0xD1)==1)
    { I2C1_start();
    }
    else break;
  }
  I2C1_Is_Idle();
  I2C1_Stop();
  return(data1);
}
 
Last edited:
In proteus....the LED displays 'properties' have a minimum trigger time. Usually 1 to 5mS works ok. This is somewhat forgiving of mistimed updates, which might show up as a flicker rather than an '8'. If u vary that 'property' you can get an effect where it just shows '8' when updated.
Real LED displays can respond faster and thus display '8' even when your code doesn't cause an '8' in proteus displays.
The solution is to 'latch' or buffer the digit being displayed by ensuring that a digit (to be displayed) cannot be changed during your LED refresh scan code cycle. Limiting digit changes to perhaps once per 0.25 second should be suitable.

Caveat: I didn't read your code, but I have run into this before.
 
In proteus....the LED displays 'properties' have a minimum trigger time. Usually 1 to 5mS works ok. This is somewhat forgiving of mistimed updates, which might show up as a flicker rather than an '8'. If u vary that 'property' you can get an effect where it just shows '8' when updated.
Real LED displays can respond faster and thus display '8' even when your code doesn't cause an '8' in proteus displays.
The solution is to 'latch' or buffer the digit being displayed by ensuring that a digit (to be displayed) cannot be changed during your LED refresh scan code cycle. Limiting digit changes to perhaps once per 0.25 second should be suitable.

Caveat: I didn't read your code, but I have run into this before.

the proteus simulation shows the correct digit. the problem is with real LED 7-seg display that shows '8'.
 
Yes. well you need to probably buffer the digits going to the LED. Something is changing too fast ...take a flash picture of your LED and see if it is showing the correct digit.
 
Post #1 says the PIC used is a PIC16F628A but the schematic in post #7 shows a PIC16f876A. Which information is correct ?

Les.
 
in proteus simulation this schematic below run well as programmed. the Poteus simulated file is attatched #3. the image of that as below:
upload_2015-12-6_23-42-2.png
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top