|
|
View previous topic :: View next topic |
Author |
Message |
Khansokhua
Joined: 06 Nov 2021 Posts: 92
|
PIC16F877A Two segment display |
Posted: Wed Nov 10, 2021 9:55 pm |
|
|
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: 303
|
|
Posted: Thu Nov 11, 2021 7:07 am |
|
|
electrons on back-order?
comment your code and describe what you are seeing when it runs. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Nov 11, 2021 7:25 am |
|
|
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: 92
|
|
Posted: Thu Nov 11, 2021 2:40 pm |
|
|
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: 480 Location: Montenegro
|
|
Posted: Thu Nov 11, 2021 3:16 pm |
|
|
You really see that with the last code you posted? |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Thu Nov 11, 2021 4:02 pm |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Thu Nov 11, 2021 6:29 pm |
|
|
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: 480 Location: Montenegro
|
|
Posted: Thu Nov 11, 2021 7:21 pm |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Fri Nov 12, 2021 6:57 am |
|
|
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: 480 Location: Montenegro
|
|
Posted: Fri Nov 12, 2021 8:34 am |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Fri Nov 12, 2021 9:13 am |
|
|
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: 480 Location: Montenegro
|
|
Posted: Fri Nov 12, 2021 9:34 am |
|
|
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: 92
|
|
Posted: Sat Nov 13, 2021 2:12 pm |
|
|
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: 480 Location: Montenegro
|
|
Posted: Sat Nov 13, 2021 3:29 pm |
|
|
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. |
|
|
|
|
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
|