View previous topic :: View next topic |
Author |
Message |
Khansokhua
Joined: 06 Nov 2021 Posts: 92
|
Two Digit 7 Segment Display with 74LS48 BCD DECODER |
Posted: Fri Apr 26, 2024 4:35 pm |
|
|
Greetings,
I am trying to indicate some numbers that I declared for each digit simulteneaously.However, both digit indicate same value.I could not succed it trying below suggested method.Can someone explain how can I solve this issue? I am using PIC18f46k22
With regards...
Code: | #include <18F46K22.h>
#DEVICE ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(internal=16000000)
void main()
{
set_tris_c(0x00);
while(1)
{
output_c((0b00011000)); //4.bit enables second digit , 5.bit equivalent to
// '1'(0001)
//ABCD inputs alongs 5.bit to 8.bit
delay_ms(5);
output_c((0b01000100)); //3.bit enables first digit , 7.bit equivalent to
// '4' (0100)
delay_ms(5);
}
} | [/list] |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Fri Apr 26, 2024 6:58 pm |
|
|
Perhaps just think of the high nibble of the port to be the 'left' display(10s), and the lower nibble to be the 'right' display(1s) ?
Sending 0b00010010 should be displayed as '12', the high nibble(10s digit) goes to the 'left' 74LS48, the low nibble to the 'right' 74LS48(units digit).
be sure to wire LT- high though. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sat Apr 27, 2024 6:49 am |
|
|
You need to tell us how the display is actually wired?.
You refer to a 74LS48, and seem to say this is on bits 4 to 7 of
PORTC (bits are normally numbered 0....7). You then seem to be saying
that bits 2 and 3 are the enables for the digits. If so, then what you post
should probably work.
Post the actual circuit. Put a picture of this up on a picture hosting site,
and post the link to this here. Hopefully you have actually got driver
transistors for the digits with current limiting resistors for the drive
connections to these, and current limiting resistors for the segment
drives from the 74LS48.
That is doesn't work, suggests there is a wiring problem of some sort.
Possibly too much current is being drawn and the PIC is actually resetting.
How are the ripple blanking connections made on the chip?.
Can you actually cycle through displaying 0...9 on one digit of the
display?. Can you do the same on the second digit?. Until this works,
therte is no point in trying to output the two digits. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Sat Apr 27, 2024 8:20 am |
|
|
hmm, re-reading his post I now think that
Bits 7,6,5,4 are the data
Bit 4 enables a 74LS48
Bit 3 enables the other 74LS48
Bits 2,1,0 not used
Seems very complicated to me as he needs to rapidly send data (faster than 50Hz+-) so both digits get seen. This also consumes a lot of PIC time 'multiplexing' the displays.
I think my 'old skool' way is easier to code and digits STAY on, allowing PIC to do a zillion other things. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Sun Apr 28, 2024 6:48 am |
|
|
Yes, that is what I think is meant to be happening. However if so, that
it doesn't work, suggests a wiring problem.
It could be made to work quite well simply by using a timer interrupt
to do the switching. However the hardware needs to be working first.
He needs to simply operate the second digit _only_, and verify this shows
correctly. If it foes not then there is something wrong in how the wiring
is done. |
|
|
Khansokhua
Joined: 06 Nov 2021 Posts: 92
|
|
Posted: Mon Apr 29, 2024 8:43 am |
|
|
I tried countering(0-9) both digit and it works properly.Here the circuit diagram https://freeimage.host/i/JgJ1oS2
Also, RBI blank, LT and BI/RB0 are high. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Mon Apr 29, 2024 10:59 am |
|
|
OK.
So it should work:
Code: |
#include <18F46K22.h>
#DEVICE ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(internal=16000000)
#define DIG0 4
#define DIG1 8
void main(void)
{
int count;
int sub;
while(TRUE)
{
for(count=0;count<100;count++)
{
for(sub=0;sub<50;sub++)
{
output_c((count%10)<<4 | DIG0; //low digit
delay_ms(10);
output_c((count/10)<<4 | DIG1); //high digit
delay_ms10);
}
}
}
}
|
Though as I said much nicer to use an interrupt for the multiplexing. |
|
|
Khansokhua
Joined: 06 Nov 2021 Posts: 92
|
|
Posted: Mon Apr 29, 2024 8:41 pm |
|
|
Thank you Mr.Ttelmah, I appreciate but it did not make any difference.It was still unuseful and I tried to use timer0 to observe something that makes any difference.Now the indicator numbers are more smooth,sharp than they were, but they are shown one by one .And my instinct told me that it won't work in different values on timers.I do not know, any suggest? Why did the numbers had been seen concurrently while using delay function?Do I really need to increase frequnecy more and more ?
Code: | #include <18F46K22.h>
#DEVICE ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(internal=16000000)
int a=0;
#int_timer0
void timer_int()
{
set_timer0(6);
if(a==0)
{
output_c((0b00011000));
a++;
}
else if(a==1)
{
output_c((0b01000100));
a=0;
}
}
void main()
{
set_tris_c(0x00);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32);
set_timer0(6);
enable_interrupts(INT_timer0);
enable_interrupts(GLOBAL);
while(1);
} |
|
|
|
Khansokhua
Joined: 06 Nov 2021 Posts: 92
|
|
Posted: Fri May 03, 2024 9:24 am |
|
|
After I set RBI 'low'(active low) .Flickering is no more a problem.Another issue is implementing it using timer but it seems too slow.Do I need to increase frequency more to implement same thing using timer instead of delay function?
Now it indicates one by one unlike delay function. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri May 03, 2024 9:47 am |
|
|
OK.
Timer0, by default is a 16bit timer. So counting to 65535. You set it to 6,
so it does 65530 counts between interrupts. You are setting the prescaler
to /32, so it interrupts every 1/2 seconds!......
16000000/(4*32*65530) = 1.907 times per second
You want the display digits to be drawn at least 25* per second.
So:
Code: |
#include <18F46K22.h>
#DEVICE ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(internal=16000000)
#int_timer0
void timer_int(void)
{
static int a=0; //always better to avoid global variables
if(a==0)
{
output_c((0b00011000));
a=1;
}
else //no point in testing here
{
output_c((0b01000100));
a=0;
}
}
void main(void)
{
set_tris_c(0x00);
setup_timer_0(T0_INTERNAL | T0_8_BIT | T0_DIV_256);
//The RTCC names are for reverse compatibility. Use T0 instead
enable_interrupts(INT_timer0);
enable_interrupts(GLOBAL);
while(1)
;
}
|
This will give the interrupt at:
16000000/(4*256*256) = 61 times per second |
|
|
|