CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC16F877A Two segment display
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PIC16F877A Two segment display
PostPosted: Wed Nov 10, 2021 9:55 pm     Reply with quote

Code:
const int yazi[5]={0x50,0x5C,0x7C,0x5C,0x78};


void main()
{
     output_low(pin_a2);
     output_low(pin_a3);
   
   while(TRUE)
   {
   
      output_high(pin_a2);     
      output_d(0x00);       // .r
      delay_ms(10);
      output_low(pin_a2);         
      output_high(pin_a3);
      output_d(yazi[0]);
      delay_ms(1000);
     
     
      output_low(pin_a3);   
      output_high(pin_a2);
      output_d(yazi[0]);
      delay_ms(10);      //ro
      output_low(pin_a2);
      output_high(pin_a3);
      output_d(yazi[1]);
      delay_ms(1000);
     
     
     
      output_low(pin_a3);
      output_high(pin_a2); 
      output_d(yazi[1]);
       delay_ms(10);      //ob
      output_low(pin_a2);
      output_high(pin_a3);
      output_d(yazi[2]);
      delay_ms(1000);
     
     
     
     
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[2]);
      delay_ms(10);         //bo
      output_low(pin_a2);
      output_high(pin_a3);
      output_d(yazi[3]);
      delay_ms(1000);
     
     
     
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[3]); 
      delay_ms(10);         //ot
      output_low(pin_a2);
      output_high(pin_a3);     
      output_d(yazi[4]);
      delay_ms(1000);
     
     
       output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[4]);
      delay_ms(10);           //t.
      output_low(pin_a2);
      output_high(pin_a3);     
      output_d(0x00);
      delay_ms(1000);
     
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(0x00);
      delay_ms(10);            //..
      output_low(pin_a2);
      output_high(pin_a3);     
      output_d(0x00);
      delay_ms(1000);
     
     
     
   }

}



Hi! I want to do it.What's wrong?

First display { _r } ( display time 1s)
Second display- { ob } ( display time 1s)
Third display-- {bo } ( display time 1s)
fourth display--- { ot } ( display time 1s)
fifth display---- { t_ } ( display time 1s)
sixth display----- { __ } ( display time 1s)
gaugeguy



Joined: 05 Apr 2011
Posts: 288

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 7:07 am     Reply with quote

electrons on back-order?

comment your code and describe what you are seeing when it runs.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 7:25 am     Reply with quote

and particularly what the connections actually 'are'. Guessing that A2, and A3
are the common pins, and portD drives the segments. If so, A2 is on for
10mSec when A3 is on for 1000mSec. Rather a difference in brightness...
Also the loop leaves A3 'on; when it loops back, so at the start next time
round, both digits will be turned on...
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 2:40 pm     Reply with quote

Code:
const int yazi[5]={0xAF,0x23,0x03,0x23,0x07};


void main()
{
     output_low(pin_a2);
     output_low(pin_a3);
   
   while(TRUE)
   {
     
      output_high(pin_a3);
      output_d(yazi[0]);
      delay_ms(5);
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[1]);
      delay_ms(5);
      output_low(pin_a2);
     
      output_high(pin_a3);
      output_d(yazi[1]);
      delay_ms(5);
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[2]);
      delay_ms(5);
      output_low(pin_a2);
     
      output_high(pin_a3);
      output_d(yazi[2]);
      delay_ms(5);
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[3]);
      delay_ms(5);
      output_low(pin_a2);
     
      output_high(pin_a3);
      output_d(yazi[3]);
      delay_ms(5);
      output_low(pin_a3);
      output_high(pin_a2);
      output_d(yazi[4]);
      delay_ms(5);
      output_low(pin_a2);
     
      output_high(pin_a3);
      output_d(yazi[4]);
      delay_ms(5);
      output_low(pin_a3);
     
     
   }

}


Yes A2 and A3 common. D port displays two segments.
I see "rr" ,"oo","bb","oo","tt". How do I can see ".r","ro", "bo","ot","t."(dot=blank)
Could you explain the logic that I should follow?
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 3:16 pm     Reply with quote

You really see that with the last code you posted?
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 3:38 pm     Reply with quote

I see this:
https://www.dropbox.com/s/051ypwkoi1c1sxz/Screen%20Recording%20%2811.%2011.%202021%2022-25-49%29.wmv?dl=0

I know and share the feelings of the most prominent members about Proteus. I don't have those displays and I trust that it can simulate a program this simple :-)


Admins please delete this if Dropbox is untrustworthy.
gaugeguy



Joined: 05 Apr 2011
Posts: 288

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 4:02 pm     Reply with quote

Comment your code.
At each section make comments about what you expect to see and how long each section should take to execute.
temtronic



Joined: 01 Jul 2010
Posts: 9098
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 6:29 pm     Reply with quote

sigh.....
sadly another Proteus PROBLEM....
Original 'problem' is with a PIC16F877 BUt if you download the dropbox file, the PIC has become an 18F46K22, that according to the schematic ,can never,ever work in the real world.

Proteus cannot properly 'simulate', should NOT be used, ever.

YES, ADD comments !!!
EVERY line should have // this line does something added to it !
While you may know what it does, we don't. This is especially true for the YAZI array. While 5 characters are coded, we don't know what they should look like on a 7 segment display.

1st one is 0x50 which is 0b01010000. But...HOW is that related to the display ?
0b0101000 could be nu,dp,g,f,e,d,c,a
or it could be a,b,c,d,e,f,g,dp,nu

where nu means unused, dp is decimal point , a-g the 7 segments.
gets even more confusing as there are common anode AND common cathode displays, so 'sink or source' the segments ??

I understand English is not an easy language to learn, I'm a 68 year old Canadian, and STILL have trouble with it..yet it amaze me the Worldwide appeal for PICs !!
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Nov 11, 2021 7:21 pm     Reply with quote

This schematic live? Never ever. Not with 16f877 nor with 18f46k22 or any micro ever made. No crystal, no caps, nothing. Current supply for the LED segments,... As many have said before, Proteus is very gullible. Took my settings for clock and all as a gospel. I'd do it live, but I don't have those displays. I just wanted to see what this code does. For the code that uses no special resources of the micro, I trust it (it is the first time after maybe 5 years I used it to simulate anything). And it doesn't display what OP claimed. No matter what PIC. I had a blank test project in CCS and Proteus using 18f46k22 and it saved me 5 minutes of setting up a new one with 16f877. Since they both have PortA and PortD, it doesn't really change anything, the same main function would run on both.
temtronic



Joined: 01 Jul 2010
Posts: 9098
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Nov 12, 2021 6:57 am     Reply with quote

Looking at the schematic , and the code..
It appears that the displays are 'common anode' 7sd units.
Can't read the segment resistors, either 2k20 or 2020. Both would only pass maybe 2ma, so may not light up the display....
The array of character bit patterns has changed !
Last one was 0x78 is now 0x07, the inverse
but without an example, still can't decide on how the bits relate to segments.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Nov 12, 2021 8:34 am     Reply with quote

From the original post I figured common anode displays are used. Which in itself could be a problem, since all the current is drawn from pins A2 and A3. How OP handles that, I have no idea. Common cathode would be way easier, two transistors would take care of that. Resistors in the sim are 220R, even though Proteus would happily work without them, which I very much doubt for the real displays, at least not for long :-). Anyway this should work, if the hardware is ok. The example below assumes TMR0 interrupt every 13ms and text shifting every second.

main.c
Code:

#include <main.h>
// ****************************************************************************
// COMMON ANODE TYPE DISPLAY
// LOW ON PORTD PIN TURNS THE LED ON. SEGMENTS AND PIN ASSIGMENT:
// d0 top middle
// d1 top right
// d2 bottom right
// d3 bottom middle
// d4 bottom left
// d5 top left
// d6 middle
//
// SYMBOLS:
// _: 01111111   - blank
// R: 00001000
// O: 01000000
// B: 00000000
// T: 01111000
// ****************************************************************************

#DEFINE  BLANK    0b01111111
#DEFINE  R_SIGN   0b00001000
#DEFINE  O_SIGN   0b01000000
#DEFINE  B_SIGN   0b00000000
#DEFINE  T_SIGN   0b01111000

enum {_R,RO,OB,BO,OT,T_};        // states for display
unsigned int8 DisplayState = 0;  // state variable
unsigned int8 Counter = 0;
int8 GO = 0;

#INT_TIMER0
void  TIMER0_isr(void)
{
   GO = 1;                       // go through the switch 76x/s
}

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT);      //13,1 ms overflow


   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   while(TRUE){
      if (GO == 1) {                            // execute every 13,1ms
         GO = 0;
         
//  Every state lights each display for 50% of the time  for a second               
         switch (DisplayState) {
// -------------------------------- _R ----------------------------------------         
            case _R:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(BLANK);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(R_SIGN);                 
               }
               Counter++;                       
               if(Counter == 76){               // one second?
                  Counter = 0;
                  DisplayState = RO;            // yes, move to the next pattern after approx. one second
               }
               break;
            }
// ----------------------------------------------------------------------------           
            case RO:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(R_SIGN);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(O_SIGN);                 
               }
               Counter++;
               if(Counter == 76){
                  Counter = 0;
                  DisplayState = OB;            // move to the next symbol after approx. one second
               }           
           
               break;
            }
// ----------------------------------------------------------------------------           
            case OB:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(O_SIGN);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(B_SIGN);                 
               }
               Counter++;
               if(Counter == 76){
                  Counter = 0;
                  DisplayState = BO;            // move to the next symbol after approx. one second
               }             
           
               break;
            }
// ----------------------------------------------------------------------------
            case BO:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(B_SIGN);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(O_SIGN);                 
               }
               Counter++;
               if(Counter == 76){
                  Counter = 0;
                  DisplayState = OT;            // move to the next symbol after approx. one second
               }             
           
               break;
            }
// ----------------------------------------------------------------------------
            case OT:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(O_SIGN);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(T_SIGN);                 
               }
               Counter++;
               if(Counter == 76){
                  Counter = 0;
                  DisplayState = T_;            // move to the next symbol after approx. one second
               }             
           
               break;
            }
// ----------------------------------------------------------------------------
            case T_:{
               if(bit_test(Counter,0) == 0){    // test if counter is an even number.If it is, display symbol on the left display
                  output_low(pin_A3);
                  output_high(pin_A2);                             
                  output_d(T_SIGN);
               }
               else{                            // else display symbol on the right display
                  output_low(pin_A2);
                  output_high(pin_A3);               
                  output_d(BLANK);                 
               }
               Counter++;
               if(Counter == 76){
                  Counter = 0;
                  DisplayState = _R;            // move to the next symbol after approx. one second
               }             
           
               break;
            }
// ----------------------------------------------------------------------------
         }        // switch
     
      }           // GO
 



   }

}


main.h
Code:

#include <16F877A.h>
#device ADC=10
#use delay(crystal=20000000)
temtronic



Joined: 01 Jul 2010
Posts: 9098
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Nov 12, 2021 9:13 am     Reply with quote

nice...


for the old guys like me...

// d0 top middle 'a' segment
// d1 top right 'b'
// d2 bottom right 'c'
// d3 bottom middle 'd'
// d4 bottom left 'e'
// d5 top left 'f'
// d6 middle 'g'

..allows d7 to be the decimal point

sad thing is I have some Numitrons laying about here from the 'single digit clock building dayze'....
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Nov 12, 2021 9:34 am     Reply with quote

Can't believe I actually forgot about the default names and placements of the segments :-) Last time I used them was more than 20 year ago, when I tried to replicate a Microchip appnote for a clock using 16f84.
Khansokhua



Joined: 06 Nov 2021
Posts: 88

View user's profile Send private message

PostPosted: Sat Nov 13, 2021 2:12 pm     Reply with quote

Code:
#include <ROBOT.h>

const int yazi[5]={0xAF,0x23,0x03,0x23,0x07};  // r,o,b,o,t
  //   7 Segment Two Digits LED Display Common Anode
  //     1  0101111=r                                       
  //   (dp) gfedcba        zero bit  makes on led
  //     1  0100011=o   
  //     1  0000011=b
  //     1  0000111=t
// d0 top middle 'a' segment
// d1 top right 'b'
// d2 bottom right 'c'
// d3 bottom middle 'd'
// d4 bottom left 'e'
// d5 top left 'f'
// d6 middle 'g'
void main()
{
     output_low(pin_a2); //  left digit off
     output_low(pin_a3); //  right digit off
   
    while(TRUE)
   {
     
      output_high(pin_a3); //right digit on
      output_d(yazi[0]);   // displays "r"
      delay_ms(1000);      // I wanto to see this,yes:) ".r"
     
      output_low(pin_a3);  // right digit off
      output_high(pin_a2); //  left digit on
      output_d(yazi[1]);   // displays "o."
      delay_ms(1000);      // I want to see "ob"
      output_low(pin_a2);  //  left digit off
     
      output_high(pin_a3);  //right digit on
      output_d(yazi[1]);    // displays ".o"
      delay_ms(1000);       // I want to see "bo"
      output_low(pin_a3);   //  right digit off
      output_high(pin_a2);  //  left digit on
      output_d(yazi[2]);    // displays "b."
      delay_ms(1000);       // I want to see "ot" 
      output_low(pin_a2);   //  left digit off
     
      output_high(pin_a3);  //right digit on
      output_d(yazi[2]);    // displays ".b"
      delay_ms(1000);       // I want to see "t." 
      output_low(pin_a3);   //  right digit off
      output_high(pin_a2);  //  left digit on
      output_d(yazi[3]);    // displays "o."
      delay_ms(1000); 
      output_low(pin_a2);   //  left digit off
     
      output_high(pin_a3);   //right digit on
      output_d(yazi[3]);     // displays ".o"
      delay_ms(1000);        // I want to see ".."
      output_low(pin_a3);    //  right digit off
      output_high(pin_a2);   //  left digit on
      output_d(yazi[4]);     //  displays "t."
      delay_ms(1000); 
      output_low(pin_a2);    //  left digit off
     
      output_high(pin_a3);   // right digit on
      output_d(yazi[4]);     // displays ".t"
      delay_ms(1000);        // Here I want loop to go beginning (I want to see ".r",also I see ".r")
      output_low(pin_a3);    // right digit off
     
     
      // I want to see each of them with 1s delay ".r" 1s "ob" 1s "bo" 1s "ot" 1s "t." 1s ".."
   }

}


Sorry for complication.Here , I want to see this just using those basic codes, for now.It can be done in this way but I didn't make it happen.After solving this issue,I will work on includes timer one .Also, I am very glad to see that.Thank you PrinceNai and others who can try to help me, respects.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Sat Nov 13, 2021 3:29 pm     Reply with quote

You can also do it like that, no problem. The way you wrote it only "lights" one display at a time for a second, which is not cool at all. It blinks. You will not get what you want. The way you do it would work on a lcd display, because they are persistent, meaning they don't turn off or change unless you tell them to. Here you are working with actual LED diodes. When you turn them off, they are dead. No light. The trick here is to turn them on and off so fast that your eye doesn't see the difference when they are off. I believe that frequency is somewhere above 25 Hz. The cost, if you drive two displays from just PORTD directly is brightness. But your eye does the rest.

Anyway, if you don't want to use timers, you still need some reference to "real" time to go through the patterns. Timers are just the easiest way to do it. I mean, that's why they call them timers. You can of course count how long any of the patterns should last using any other method. But given the speed of the instructions, you might have to code way more than just do a simple setup of a timer and than using interrupts or reading it.

And far from the last thing. You are supplying data for two displays from the same port. That means that inside time for each "pattern" you have to split the time in half and feed the data to each display 50:50. Only not so slow. That is what the code I posted does, doing it at 38Hz per display.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group