CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

timerx interrupt of 18F448

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pauken



Joined: 24 Apr 2004
Posts: 3

View user's profile Send private message

timerx interrupt of 18F448
PostPosted: Sat Apr 24, 2004 8:10 am     Reply with quote

My target is to generate four channels of variable frequency sine wave by a prallel input DAC (TI P/N TLC7226) simultaneously.
My idea is to change the timerX value and the frequency of each channnel will change.
Currently, I had completed to use each timer (timer0 through timer3) to generate sine wave separately, one channel at a time but not simultaneously, without significant problem.
However, when I tried to generate two or more channels simultaneously, the problem happened.
When two channels worked, such as timer0 and timer1 worked simultaneously, the interference between the two sine waves is significantly high. If up to three or more, the third or fourth channel could not work.
I suppose that I used the interrupt improperly. But, I am not so clear what error I make.
The C complier version I used is PCH=3.174

My source code is listed as below.

///////////////////////start of program////////////////////////////////////
#include "18F448.h"
#fuses H4,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000) // I use 4MHz xtal

BYTE CONST SINE_WAVE[200] = { // this table copied from ex_sine.c
128,132,136,139,143,147,150,154,158,161,165,169,172,176,179,182,186,189,192,195,199,202,204,207,210,213,215,218,220,223,225,227,229,231,233,235,237,238,240,241,242,243,244,245,246,247,247,247,248,248,248,248,248,247,247,247,246,245,244,243,242,241,240,238,237,235,233,231,229,227,225,223,220,218,215,213,210,207,204,202,199,195,192,189,186,182,179,176,172,169,165,161,158,154,150,147,143,139,136,132,128,124,120,117,113,109,106,102,98,95,91,87,84,80,77,74,70,67,64,61,57,54,52,49,46,43,41,38,36,33,31,29,27,25,23,21,19,18,16,15,14,13,12,11,10,9,9,9,8,8,8,8,8,9,9,9,10,11,12,13,14,15,16,18,19,21,23,25,27,29,31,33,36,38,41,43,46,49,52,54,57,61,64,67,70,74,77,80,84,87,91,95,98,102,106,109,113,117,120,124};

void dac_out(char dac_port, int8 v_dac)
{
switch(dac_port) {
case 'A' : output_bit(PIN_C1, 0); output_bit(PIN_C0, 0);
break;
case 'B' : output_bit(PIN_C1, 0); output_bit(PIN_C0, 1);
break;
case 'C' : output_bit(PIN_C1, 1); output_bit(PIN_C0, 0);
break;
case 'D' : output_bit(PIN_C1, 1); output_bit(PIN_C0, 1);
break;
}
output_bit(PIN_C3,0); // Set DAC outport to transparent
output_d(v_dac);
output_bit(PIN_C3, 1); // Set DAC output to activate
}


#int_timer0 // the idea of this interrupt comes from the ex_sine.c
void isr_a() {
BYTE sine_index_a;
set_rtcc(0xFFEC); // 364us per step, 13.66Hz
dac_out('A', SINE_WAVE[sine_index_a]);
delay_us(10); // delay for DAC rising time.
if(++sine_index_a==200) {
sine_index_a=0;
}
}


#int_timer1
void isr_b() {
BYTE sine_index_b;
set_timer1(0xFFDC); // 620us per step, 8.258Hz
dac_out('B', SINE_WAVE[sine_index_b]);
delay_us(10);
if(++sine_index_b==200) {
sine_index_b=0;
}
}

#int_timer2
void isr_c() {
BYTE sine_index_c;
set_timer2(0xFFDC); // 620us per step, 8.258Hz
dac_out('C', SINE_WAVE[sine_index_c]);
delay_us(10);
if(++sine_index_c==200) {
sine_index_c=0;
}
}


#int_timer3
void isr_d() {
BYTE sine_index_d;
set_timer3 (0xFFDC);// 620us per step, 8.258Hz
dac_out('D', SINE_WAVE[sine_index_d]);
delay_us(10);
if(++sine_index_d==200) {
sine_index_d=0;
}
}

main ()
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );
setup_timer_2( T2_DIV_BY_16,0x99, 3);
setup_timer_3( T3_INTERNAL | T3_DIV_BY_8 );
enable_interrupts(int_timer0);
enable_interrupts(int_timer1);
enable_interrupts(int_timer2);
enable_interrupts(int_timer3);
enable_interrupts(GLOBAL);
}


////////////////// end of program ///////////

Could anybody assitant me or drop me a hint ?
Thanks.
_________________
I am a student.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Sat Apr 24, 2004 9:45 am     Reply with quote

Change this line

enable_interrupts(GLOBAL);

to this

enable_interrupts(GLOBAL);
while(1);

Your puting the chip to sleep between interupts.
pauken



Joined: 24 Apr 2004
Posts: 3

View user's profile Send private message

PostPosted: Sat Apr 24, 2004 12:08 pm     Reply with quote

Could you explain the reason why the line

"while(1)" // an infinite loop after the global interrupt

could cause the sleep between each interrupt ?


I don't understand the flow of this line.

Thank you for your assistance.
_________________
I am a student.
Ttelmah
Guest







PostPosted: Sat Apr 24, 2004 2:34 pm     Reply with quote

pauken wrote:
Could you explain the reason why the line

"while(1)" // an infinite loop after the global interrupt

could cause the sleep between each interrupt ?


I don't understand the flow of this line.

Thank you for your assistance.


It doesn't. You have the reason the 'wrong way round'. The CCS compiler, puts a hidden 'sleep' instruction, off the 'end' of the main routine. Your code, currently allows the main to run 'ff the end', and will therefore be executing this 'sleep'. You want to avoid this. The 'while(true);' (or equivalent statement), prevents the code from droppin off the end.

Best Wishes
pauken



Joined: 24 Apr 2004
Posts: 3

View user's profile Send private message

PostPosted: Sat Apr 24, 2004 3:36 pm     Reply with quote

/////////////// start of program
..... // omit the interrupt part

main ()
{

printf ("\n\r Program Start!\n"); // This line for RS232 working check.
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );
setup_timer_2( T2_DIV_BY_16,0x99, 3);
setup_timer_3( T3_INTERNAL | T3_DIV_BY_8 );
enable_interrupts(int_timer0);
enable_interrupts(int_timer1);
enable_interrupts(int_timer2);
enable_interrupts(int_timer3);
enable_interrupts(GLOBAL);

while(!kbhit())
{ printf ("\n\r Press any key to reset!!\r\n"); }
get(); reset_cpu();
}

///////// End of program


I modify the last few lines of my program as above. And, connect the RS232 properly. The RS232 part is working preperly.

However, at PC side, the last line ("Press any key to reset!!")does not appear. And, the sine wave condition is still the same. Not working at more than one channel.
_________________
I am a student.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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