| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| pauken 
 
 
 Joined: 24 Apr 2004
 Posts: 3
 
 
 
			    
 
 | 
			
				| timerx interrupt of 18F448 |  
				|  Posted: Sat Apr 24, 2004 8:10 am |   |  
				| 
 |  
				| 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Apr 24, 2004 9:45 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Apr 24, 2004 12:08 pm |   |  
				| 
 |  
				| 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
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Sat Apr 24, 2004 2:34 pm |   |  
				| 
 |  
				|  	  | 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Apr 24, 2004 3:36 pm |   |  
				| 
 |  
				| ///////////////  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.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |