|
|
View previous topic :: View next topic |
Author |
Message |
energetic007
Joined: 10 Nov 2013 Posts: 10
|
7 segment flickering problem |
Posted: Sun Nov 10, 2013 10:46 pm |
|
|
hello everyone i am a newbie ......
ccs compiler version 4.108
pic 16f877a interfacing with two 7 segment ANODE displays.
7 pins of segment connected from RD0 to RD6 on PORT-D.
Two enable pins i.e. base of bc547 transistors connected via 200 ohm resistor to PINS RB3 and RB4.
Interrupts of timer 0 to RB3 and RB4.
But the segment flickers a lot ... i am confused ....can anyone give a look to it....
Code: |
#include <16f877a.h>
#fuses NOPROTECT,NOCPD,XT
#use delay(clock=4m)
const char LED_DIGIT[10]={
0b01000000, // zero
0b01111001, //one
0b00100100, //two
0b00110000, //three
0b00011001, //four
0b00010010, //five
0b00000010, //six
0b01111000, //seven
0b00000000, //eight
0b00010000}; //nine
void first()
{
output_d(LED_DIGIT[0]);
}
void sec()
{
output_d(LED_DIGIT[1]);
}
#INT_TIMER0
void isr()
{
output_toggle(PIN_B3);
delay_ms(10);
output_toggle (PIN_B4);
}
void main()
{
setup_adc(ADC_OFF);
setup_comparator(NC_NC_NC_NC);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
do
{
first();
sec();
}
while(1==1);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Mon Nov 11, 2013 2:58 am |
|
|
Your approach is slightly flawed. You don't want to pulse RB3, then RB4 in the interrupt. What needs to happen is that the pattern for the first digit is sent, and RB3 turned on. _Then_ at the next interrupt, the pattern for the next digit is sent, and RB4 turned on. The pattern, and the drive must work together. Currently they are separate. So:
Code: |
#include <16f877a.h>
#fuses NOPROTECT,NOCPD,XT
#use delay(clock=4m)
#include <stdlib.h>
const char LED_DIGIT[10]={
0b01000000, // zero
0b01111001, //one
0b00100100, //two
0b00110000, //three
0b00011001, //four
0b00010010, //five
0b00000010, //six
0b01111000, //seven
0b00000000, //eight
0b00010000}; //nine
int8 digits[2]={0,0};
#INT_TIMER0
void isr()
{
static int8 digit=0;
output_low(PIN_B3);
output_low(PIN_B4); //ensure both drives are off before changing
if (digit==0)
{
output_d(LED_DIGIT[digits[0]]);
output_high(PIN_B3); //drive the first digit
digit=1;
}
else
{
output_d(LED_DIGIT[digits[1]]);
output_high(PIN_B4); //drive the second digit
digit=0;
}
}
void main()
{
int8 count;
div_t idiv;
setup_adc(ADC_OFF);
setup_comparator(NC_NC_NC_NC);
output_low(PIN_B3);
output_low(PIN_B4); //ensure both drives are off
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4; //slower
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
do
{
for (count=0;count<100;count++)
{
idic=div(count,10); //generate quotient, and remainder
digits[0]=idiv.quot;
digits[1]=idiv.rem;
//put the counter value to display
delay_ms(1000); //wait for a second displaying
}
}
}
|
I've slowed the interrupt to just 244* per second. Anything over perhaps 100* per second is fast enough, and the slower interrupt means less time wasted here.
The code sits in a loop, counting from 0 to 99, and puts this count, split into two digit values, into the array (digits[]), which is the values to be displayed, then waits for a second, and does this again for the next count.
Meanwhile the interrupt alternately displays digits[0], and digits[1], on the two display digits.
Using the fixed 'digits[0]' and 'digits[1]' in the interrupt, is quicker than having an array indexed by another array using a variable. Since there has to be a test to turn on the right drive, this is just a little more efficient.
Note the use if the div function from stdlib, which gives quotient and remainder in a single operation, so is more efficient than % and / here.
Best Wishes |
|
|
energetic007
Joined: 10 Nov 2013 Posts: 10
|
flickering 7 segment |
Posted: Mon Nov 11, 2013 8:02 am |
|
|
thanks a lot Ttelmah ... i don't know why< stdlib.h> is used and where should i find the contents of the header file from .
could you please make me understand its use. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Mon Nov 11, 2013 8:35 am |
|
|
'stdlib', is the 'standard library'. Comes with the compiler (sits in the drivers directory). It contains lots of definitions for standard bits of C, and a few extended bit. It's where the definition of the 'idiv' data type is stored, so you can used the 'div' function. It contains all the functions for doing things like converting ASCII to integer and vice versa.
There are about ten include files like this that are 'standard' parts of C (_every_ C is required to have them). math.h, string.h. stdio.h, stdlib.h, stddef.h, stdarg.h, stdlibm.h, limits.h, float.h, errno.h, ctype.h etc..
Best Wishes |
|
|
edi
Joined: 22 Dec 2003 Posts: 82
|
Making the display light for short period |
Posted: Wed Jan 15, 2014 12:34 am |
|
|
Ttelmah, your code works perfect thanks.
In my project the 7 Seg should light only when the counter is change and only for short period of 2-3 sec.
I will appreciate if you suggest a proper way to turn on the 7 seg for 2-3 sec and then back off.
Thanks. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Jan 15, 2014 2:09 am |
|
|
Add something like a 'display_on' flag.
So:
Code: |
int1 display_on=TRUE;
#INT_TIMER0
void isr()
{
static int8 digit=0;
output_low(PIN_B3);
output_low(PIN_B4); //ensure both drives are off before changing
if (display_on)
{
if (digit==0)
{
output_d(LED_DIGIT[digits[0]]);
output_high(PIN_B3); //drive the first digit
digit=1;
}
else
{
output_d(LED_DIGIT[digits[1]]);
output_high(PIN_B4); //drive the second digit
digit=0;
}
}
}
|
Then when you don't want anything displayed, set 'display_on=FALSE', and the code will stop outputting anything. When you want it displaying, set it TRUE again.
Best Wishes |
|
|
edi
Joined: 22 Dec 2003 Posts: 82
|
|
Posted: Wed Jan 15, 2014 6:33 am |
|
|
Thanks.
Is there an elegant way to perform the 2Sec on time?
Or just add counter that count the timer interrupts and after crossing threshold to turn the display off? |
|
|
|
|
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
|