|
|
View previous topic :: View next topic |
Author |
Message |
nick_18
Joined: 22 May 2010 Posts: 2
|
I need help with two interrupts |
Posted: Sat May 22, 2010 1:40 am |
|
|
hi I'm a newby programing in CCS and I have a problem, but first sorry for my bad english and I hope you understand.
Ok. I use the timer0 to control a countdown timer (00 to 99) that show in two 7 segment. I use the timer2 to set a pwm at 64khz. The problem is when both interrupts are enabled (the pwm and the countdown timer), the seven segment display begin flashing and the pic crash, pic stops responding and for example I can not use the buttons for setting the time.
Thanks for your help.
Here is the code and Proteus simulation.
Code: |
#include<16F876A.h>
#fuses XT,NOPUT,NOWDT,NOLVP,NOPROTECT
#use delay(clock=8000000)
#byte TRISA=0x85
#byte TRISB=0x86
#byte TRISC=0x87
#byte PORTA=0x05
#byte PORTB=0x06
#define max_duty 124
signed int d1,d2;
int16 duty_cicle;
long overflow;
// array with numbers 0 to 9
int show[]={0b00111111,0b00000110,0b01011011,0b01001111,
0b01100110,0b01101101,0b01111101,0b00000111,
0b01111111,0b01100111};
void config(void){
TRISA=0x00;
TRISB=0x00;
TRISC=0x00;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16|RTCC_8_BIT);
setup_timer_2(T2_DIV_BY_1,30,1);
set_timer0(214);
}
void reset(void){
disable_interrupts(GLOBAL);
disable_interrupts(INT_RTCC);
disable_interrupts(INT_TIMER1);
}
#INT_RTCC
void RTCC(){
//countdown
overflow++;
if(overflow>10000){ overflow=0; D2--;}
if(D2<0){D2=9;D1--;}
if(d1==0 && d2==0){break; reset();}
set_timer0(214);
}
#int_timer2
void timer2_isr(void) //PWM
{
static int8 increment = TRUE;
if(increment)
{
duty_cicle++;
if(duty_cicle == max_duty){
increment = FALSE;
}
}
else
{
duty_cicle--;
if(duty_cicle == 0)
increment = TRUE;
}
set_pwm1_duty(duty_cicle);
}
void main()
{
disable_interrupts(global);
disable_interrupts(INT_RTCC);
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
config();
for(;;){
if(input(pin_a5)){ if(d1!=0 || d2!=0){ //pin_a5 button to begin the count time and pwm
delay_ms(60);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_timer2);
setup_ccp1(CCP_PWM);
}}
if(input(PIN_A3)){ //Increase time
delay_ms(60);
D2++;
if(D2>=10){ D2=0; D1++;}
if(D1>9){D1=0;D2=0;}
}
if(input(PIN_A4)){if(d1!=0 || d2!=0){ //decrease time
delay_ms(60);
D2--;
if(D2<0){ D2=9; D1--;}
if(D1<0){D1=0;D2=0;}
}}
output_high(pin_a1); // show time in display
PORTB=show[D1];
output_low(pin_a0);
delay_ms(10);
output_high(pin_a0);
PORTB=show[D2];
output_low(pin_a1);
delay_ms(10);
}
}
|
The Proteus simulation is here
http://rapidshare.com/files/390237258/test.rar |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat May 22, 2010 2:53 pm |
|
|
For timer2, if all you want is just pure pwm that doesn't change in any sort of time crticial way, you don't need to enable the interrupt. Just set the timer to run and your period values and the PWM will operate.
The only "interrupt" you need to really service is timer0. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat May 22, 2010 3:01 pm |
|
|
First a small problem. XT fuse selected. Max frequency recommended for this fuse, 4MHz....
Then, a comment. You select RTCC as 8bit, but the 876, _only_ has an 8bit RTCC. This option does nothing on this chip.
Your big problem is _time_.
The RTCC, is effectively counting in '8 instruction' ticks. You set it to 214. It'll then try to trigger every 336 instructions. Your Timer2 interrupt though, is set to reset at just 31 counts, and is counting in instructions. So, just 31 instructions between triggers. It takes typically 60 instructions to get into, and out of an interrupt. Add the code in the interrupt itself (perhaps another dozen instructions), and this interrupt will continuously trigger...
You need to slow down this interrupt to have any hope at all of the code working. The last value in the timer2 setup, is the number of PWM cycles between interrupt triggers, and is there just for this reason.
Realistically, drop the PWM to perhaps 20KHz, and interrup every fourth cycle, and you will have a 'chance'...
Best Wishes |
|
|
nick_18
Joined: 22 May 2010 Posts: 2
|
|
Posted: Sat May 22, 2010 5:13 pm |
|
|
Thank you very much for you help. |
|
|
|
|
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
|