|
|
View previous topic :: View next topic |
Author |
Message |
kevin5059
Joined: 29 Nov 2006 Posts: 3
|
Newbie for CCS on interrupt |
Posted: Wed Nov 29, 2006 1:24 pm |
|
|
Hi, I'm currently using PIC16F877A to do some coding for the Seven SEgments display to display 00 to 99 (two seven segments). However, my seven segments keep stand at "00" though i try to apply Low to High trigger to the pin RB0/INT (pin33).
What I wish to get for this code is when there is an interrupt at INT, the number of the seven segments will increase for 1 step. Example, 00, 01,02,03...95,96,97,98,99,00,01.
For your information, my seven segments are connected to the seven segments driver and a Demultiplexer before the PIC.
The code is attached as below:
[code]#include "C:\Documents and Settings\Beng Lee\Desktop\Testing\B0Seven.h"
#include <stdio.h>
#include <stdlib.h>
int R_Variable=0x00;
int L_Variable=0x00;
#int_EXT // interrupt routine
void EXT_isr()
{
if (R_Variable!=0x90)
{
R_Variable=R_Variable+16;
}
else
{
if (L_Variable==0x90)
{
R_Variable=0x00;
L_Variable=0x00;
}
else
{
R_Variable=0x00;
L_Variable=L_Variable+16;
}
}
}
void L_Segment_On() // turning on the left seven segment
{
output_c(0x20); // 0010,0000 - Turn On the demultiplexer and
// left seven segment
}
void R_Segment_On() // tuning on the right sevensegment
{
output_c(0x00); // 0000,0000 - Turn On the Dex and right segment
}
void L_Segment_Off()
{
output_c(0x10); // turning the Left segment Off
}
void R_Segment_Off()
{
output_c(0x10); // turning the Right segment Off
}
void Display ()
{
L_Segment_On();
output_d(L_Variable); // output the number to Left segment
L_Segment_Off();
R_Segment_On();
output_d(R_Variable); // output the number to right segment
R_Segment_Off();
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge(L_to_H); // Low to High trigger detection
enable_interrupts(INT_EXT); // enable the external interrupt
enable_interrupts(GLOBAL); // enable the global interrupt
loop:
Display();
delay_ms(2000);
goto loop;
[/code]
For your information,
the I/O RD4, RD5, RD6,RD7 are connected to the input of seven segment driver. If RD7,RD6,RD5,RD4 = 0000, "0" will be display on the segment.
If RD7,RD6,RD5,RD4 = "0001, "1" will be displayed and so on until 1001, "9" will be display.
RD7,RD6,RD5, and RD4 are connected to both of the segment (Left and Right). Therefore, a demultiplexer is required to decide which segment is activated and which one is deactivated.
RC4 ---> E (active low) enable the demultiplexer
RC5---->A0
RC6---->A1
A0 and A1 use to decide which output of demultiplexer
will be actived.
A1A0 = 00 (Right Seven Segment will be activated)
A1A0 = 10 (Left seven segment will be activated)
RC7----> Not connect |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Nov 29, 2006 5:40 pm |
|
|
Right now your program is to complex for easy debugging. You don't know if the interrupt is failing or a problem in driving the display, or a combination of both.
Try to narrow down the cause of the error by splitting the program in two smaller programs, one program to prove the interrupts are working as expected (for example by blinking a led) and a second program displaying an automatic increasing number on the display.
Code: | void L_Segment_On() // turning on the left seven segment
{
output_c(0x20); // 0010,0000 - Turn On the demultiplexer and
// left seven segment
} | According to your given information you would have to write a 0x40 in order to activate the left segment.
Which seven segments driver are you using? How is it connected to the multiplexer? Do you have added pull-up / pull-down resistors to prevent floating inputs? |
|
|
kevin5059
Joined: 29 Nov 2006 Posts: 3
|
|
Posted: Wed Nov 29, 2006 7:10 pm |
|
|
[quote="ckielstra"]Right now your program is to complex for easy debugging. You don't know if the interrupt is failing or a problem in driving the display, or a combination of both.
Try to narrow down the cause of the error by splitting the program in two smaller programs, one program to prove the interrupts are working as expected (for example by blinking a led) and a second program displaying an automatic increasing number on the display.
[code]void L_Segment_On() // turning on the left seven segment
{
output_c(0x20); // 0010,0000 - Turn On the demultiplexer and
// left seven segment
}[/code]According to your given information you would have to write a 0x40 in order to activate the left segment.
Which seven segments driver are you using? How is it connected to the multiplexer? Do you have added pull-up / pull-down resistors to prevent floating inputs?[/quote]
I think the segments should be OK since I tried it separately. For this code, the seven segments just gave me "0" "0" for both of the display even I applied Low to High voltage at B0/INT.
and for the left segment activation code.. it should be0x20.. Sorry my mistake on the explaination above.
RC7, RC6, RC5, RC4
NC A1 A0 E(active low)
so it should be "0010000" or 0x20 in HEX |
|
|
kevin5059
Joined: 29 Nov 2006 Posts: 3
|
|
Posted: Wed Nov 29, 2006 7:30 pm |
|
|
This the draft circuit on how I connect the Demultiplexer and Seven SEgment drivers.
[IMG]http://i16.tinypic.com/2weja8i.jpg[/IMG]
http://i16.tinypic.com/2weja8i.jpg
assume that the seven segments are connected with pull-down resistors. Just I lazy to draw it. And also ignore the Temperature sensor on the left hand side.. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 29, 2006 11:17 pm |
|
|
Forget about the interrupt for now. Just try incrementing the variables in the main loop and see if you can get the display to work correctly. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 29, 2006 11:25 pm |
|
|
Have you noticed that none of your quote blocks, code blocks, or IMG
blocks are working ? I think that's because you have "BBCode"
disabled, either in your individual posts or in your user profile.
You should enable "BBCode", but disable HTML in your posts. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Nov 30, 2006 6:10 am |
|
|
PCM programmer wrote: | Have you noticed that none of your quote blocks, code blocks, or IMG
blocks are working ? I think that's because you have "BBCode"
disabled, either in your individual posts or in your user profile.
You should enable "BBCode", but disable HTML in your posts. | You stay up too late |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 30, 2006 6:33 am |
|
|
I agree with Mark, forget about the interrupts for the moment and make sure your display is working as expected by creating a small program displaying increasing numbers.
Note: your current program counts up to 90 and not to 99, is this intentional? You program is easier to understand and problems like this will be avoided when you get rid of the R_Variable and L_Variable values. Change the Display function by adding a parameter with the value to be displayed and then have the Display function figure out how to send this value.
Then a few notes on your schematic:
- Vcc of the multiplexer, LT and BI of the driver are all connected but the connection to the +5V is missing.
- For the PIC16F877A it is not recommended to connect MCLR directly to Vdd. Read chapter 14.4 of the datasheet for an explanation and schematic.
- Add decoupling capacitors of 100nF as close as possible between all Vss-Vdd pins of the processor. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Nov 30, 2006 7:05 am |
|
|
ckielstra wrote: | I agree with Mark, forget about the interrupts for the moment and make sure your display is working as expected by creating a small program displaying increasing numbers.
Note: your current program counts up to 90 and not to 99, is this intentional? You program is easier to understand and problems like this will be avoided when you get rid of the R_Variable and L_Variable values. Change the Display function by adding a parameter with the value to be displayed and then have the Display function figure out how to send this value.
Then a few notes on your schematic:
- Vcc of the multiplexer, LT and BI of the driver are all connected but the connection to the +5V is missing.
- For the PIC16F877A it is not recommended to connect MCLR directly to Vdd. Read chapter 14.4 of the datasheet for an explanation and schematic.
- Add decoupling capacitors of 100nF as close as possible between all Vss-Vdd pins of the processor. |
Vcc is connected in the schematic. Look above the segment drivers. It also looks to me that the code will count to 99.
Try moving the interrupt code inside the main loop and see if this counts. If not, then the problem is not with the interrupt but with something else. Also, why are you using a line decoder? Is there other parts of the circuit that you are not showing? You are actually using 3 outputs to only control 2 plus the extra expense of the '139.
Code: |
#include "C:\Documents and Settings\Beng Lee\Desktop\Testing\B0Seven.h"
#include <stdio.h>
#include <stdlib.h>
int R_Variable=0x00;
int L_Variable=0x00;
void L_Segment_On() // turning on the left seven segment
{
output_c(0x20); // 0010,0000 - Turn On the demultiplexer and left seven segment
}
void R_Segment_On() // tuning on the right sevensegment
{
output_c(0x00); // 0000,0000 - Turn On the Dex and right segment
}
void L_Segment_Off()
{
output_c(0x10); // turning the Left segment Off
}
void R_Segment_Off()
{
output_c(0x10); // turning the Right segment Off
}
void Display ()
{
L_Segment_On();
output_d(L_Variable); // output the number to Left segment
L_Segment_Off();
R_Segment_On();
output_d(R_Variable); // output the number to right segment
R_Segment_Off();
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while (1)
{
Display();
if (R_Variable!=0x90)
{
R_Variable=R_Variable+16;
}
else
{
if (L_Variable==0x90)
{
R_Variable=0x00;
L_Variable=0x00;
}
else
{
R_Variable=0x00;
L_Variable=L_Variable+16;
}
}
delay_ms(2000);
}
} |
Last edited by Mark on Thu Nov 30, 2006 8:53 am; edited 1 time in total |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Nov 30, 2006 7:17 am |
|
|
Quote: | Vcc is connected in the schematic. Look above the segment drivers. It also looks to me that the code will count to 99. | Sorry, you are right. Not my best day today.
Allow me to make a correction to your example: disable the interrupts or add an interrupt handler function. As it is now an accidental interrupt will not be cleared and causes an endless loop. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Nov 30, 2006 8:53 am |
|
|
ckielstra wrote: | Quote: | Vcc is connected in the schematic. Look above the segment drivers. It also looks to me that the code will count to 99. | Sorry, you are right. Not my best day today.
Allow me to make a correction to your example: disable the interrupts or add an interrupt handler function. As it is now an accidental interrupt will not be cleared and causes an endless loop. |
Yep, did that a little carelessly. I fixed it above. |
|
|
|
|
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
|