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 support@ccsinfo.com

Timer interrupt does not work properly

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



Joined: 12 May 2006
Posts: 3

View user's profile Send private message

Timer interrupt does not work properly
PostPosted: Fri May 12, 2006 12:16 pm     Reply with quote

Hello.
I`m trying to send samples to a PC over RS232 at maximum speed. The fastest sample rate for 10 bit samples is about 5760HZ (115200bps constraint). The problem occurs in the Timer1 ISR that set the desired sampling frequency. The: setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); means that 1 count in timer1 represents 1.6us. So, when the timer1 interrupts the code is executed in about 72.8 us(Calculated using timers and then some corrections via ASM list), then the timer is set to interrupt every 64*1,6uS=102.4us....Summing that time to the 72.8us already elapsed it gives 175,2uS, thts gives a Fs of approx. 5707hz...
Here the things get messy...at this speed in the PC I`m only geting about 4 to 6 Bytes per second..the same it happens when i set the timer at -100 -150 -200(that's it decrasing the sample rate)..only when I reach about -270 I`m able to get all the samples, and -270 means a sample rate of 1/(270*1,6uS + 72.8us)=1980Hz that`s not even close to 5700hz...
If it's possible I want to be able to reach at least 5000Hz samples.
Thanks in advance.
Nicolas.


#include <16f877a.h>
#device adc=10
#fuses HS,NOWDT,PUT,NOPROTECT,BROWNOUT,NOWRT,LVP
#use delay (clock=20000000)

#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8)
#org 0x0F00, 0x0FFF void loader16F877(void) {}
unsigned long muestra;
char adc_ALTO, adc_BAJO;

#int_TIMER1
Timer_test(){

disable_interrupts(INT_TIMER1); |
delay_us(20); |
muestra=read_adc(); |
adc_ALTO = (char)(((muestra >> 5)& 0x1f)|0xe0);|
adc_BAJO = (char)(muestra & 0x1f); } This lines takes about 72.8uS to
putc(adc_ALTO); | complete
putc(adc_BAJO); |
delay_us(20); |
enable_interrupts(INT_TIMER1); |
set_timer1(-64);// set_timer1(-64) + 72.8uS(Already elapsed)=> Fs=5707Hz or Ts=175uS

}

void main(){

setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
set_timer1(0);
while(1){
output_high(PIN_D3);
delay_ms(1000);
output_low(PIND_D3);
delay_ms(500);
}
}
rwyoung



Joined: 12 Nov 2003
Posts: 563
Location: Lawrence, KS USA

View user's profile Send private message Send e-mail

PostPosted: Fri May 12, 2006 12:30 pm     Reply with quote

Why are you delaying 20us inside your interrupt? That doesn't seem like a good idea. Also, the enable/disable timer interrupt calls are probably not necessary inside the ISR.

Consider using the ADC interrupt to let you know when a sample is completed, use the timer interrupt to schedule the start of the next acquisition and use your main loop to push new data out the RS232 port.

Also, as displayed, your code will not compile as there are extraneious "|" (pipe) symbols and at least one extra closing bracket "}" in the interrupt code. Use the Code button when posting code.
_________________
Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 12, 2006 12:42 pm     Reply with quote

I see one possible bug. I think your intention is to load Timer1
with -64 so it will overflow and cause an interrrupt in 64 counts.
Here is the problem: Timer1 is a 16-bit timer, but you are loading
it with an 8-bit value. You need to put an "L" after the -64 to tell
the compiler that this is a 16-bit constant. Example: -64L

Notice the difference in the .LST file between the two methods:
Code:

.................... set_timer1(-64);
0016:  CLRF   0F
0017:  MOVLW  C0
0018:  MOVWF  0E
.................... 
.................... set_timer1(-64L);
0019:  MOVLW  FF
001A:  MOVWF  0F
001B:  MOVLW  C0
001C:  MOVWF  0E
nicogorr



Joined: 12 May 2006
Posts: 3

View user's profile Send private message

PostPosted: Fri May 12, 2006 12:53 pm     Reply with quote

Thanks rwyoung,

The interrupt code is this:
Code:

#int_TIMER1
Timer_test(){

disable_interrupts(INT_TIMER1); 
delay_us(20); 
muestra=read_adc(); 
adc_ALTO = (char)(((muestra >> 5)& 0x1f)|0xe0);
adc_BAJO = (char)(muestra & 0x1f);   
putc(adc_ALTO);   
putc(adc_BAJO); 
delay_us(20); 
enable_interrupts(INT_TIMER1); 
set_timer1(-64);

}


I been trying without enable/disable timer interrupt calls, thats does not make any difference..
I cannot deal with the ADC interrupt idea because in the main loop I need to do some others things...
Rwyoung, forget about the ADC problem..The next code has the same problem:
Code:


#int_TIMER1
muestra_adc(){

   disable_interrupts(INT_TIMER1);
   putc(69);
   putc(67);
   enable_interrupts(INT_TIMER1);
   set_timer1(-200);

}

I been trying that code without enable/disable timer ..same results.
Sorry for my poor english I'm from chile.
Any suggestions????
nicogorr



Joined: 12 May 2006
Posts: 3

View user's profile Send private message

PostPosted: Fri May 12, 2006 1:00 pm     Reply with quote

PCM programmer, your totally right!!. Thank you very much.
I have been looking for errors in the code for about 2 days "You can't see the forest for the trees"..
Well that fix it, Thanks again.
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