|
|
View previous topic :: View next topic |
Author |
Message |
Benny Dijk Guest
|
problem with delay_ms/us |
Posted: Sat Aug 23, 2003 7:08 am |
|
|
Hello,
In the project I'm working on I recently had to switch from a Microchip 16F870 to a controller which has more ROM. The 16F876 was an obvious choice, since it is completeley pin compattible.
When I transfered my code to a project for the chip, it started running veeeeeeeryyyyy slowly. Especially the delay_us/ms function seems to function at a fraction of the speed it did on my 16f870. To test this I wrote this test code:
#include "C:\school\16f876\tes8.h"
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,5,5);
enable_interrupts(INT_TIMER2);
enable_interrupts(global);
while(true) {
output_bit(PIN_A2,0);
output_b(0x55);
output_bit(PIN_A2,1);
delay_ms(1000);
output_bit(PIN_A2,0);
output_b(0xAA);
output_bit(PIN_A2,1);
delay_ms(1000);
}
}
The 1sec. delays take up to 15 secconds to complete sometimes! I tried changing this by lowering the "#use delay(clock=20000000)" statement (20 Mhz clock). This works, but since I need very exact timing this is not a sufficient solution...
Can anybody please help me? I have a deadline next monday...
Thanks in advance!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517175 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: problem with delay_ms/us |
Posted: Sat Aug 23, 2003 7:55 am |
|
|
You don't say what you crystal speed is nor do you show where you setup the configuration bits. These are very important. Also, if you enabled any interrupts make sure that you have an interrupt handler for that int or else your code might be continually executing the int since the int flag bit will never get cleared.
Regards,
Mark
:=Hello,
:=
:=In the project I'm working on I recently had to switch from a Microchip 16F870 to a controller which has more ROM. The 16F876 was an obvious choice, since it is completeley pin compattible.
:=
:=When I transfered my code to a project for the chip, it started running veeeeeeeryyyyy slowly. Especially the delay_us/ms function seems to function at a fraction of the speed it did on my 16f870. To test this I wrote this test code:
:=
:=#include "C:\school\16f876\tes8.h"
/* Assuming your are using a 20MHz xtal use HS */
/* used to setup device specifications for programming the chips
HS - oscillator type
WDT- watchdog timer
NOPROTECT - do not protect code
PUT - power up timer on
BROWNOUT - brownout detect on
NOLVP - No low voltage program */
#fuses HS, WDT, NOPROTECT, PUT, BROWNOUT, NOLVP
/* Initialize all RAM locations to 0 */
#ZERO_RAM
/* Assuming your are using a 20MHz xtal */
#define CLOCK_FREQUENCY 20000000
/* the following are compiler options for delay loops, interrupt priorities */
/* io methods */
#USE DELAY(CLOCK = CLOCK_FREQUENCY)
#PRIORITY TIMER2
:=
:=void main() {
:=
:= setup_adc_ports(NO_ANALOGS);
:= setup_adc(ADC_OFF);
:= setup_spi(FALSE);
:= setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
:= setup_timer_1(T1_DISABLED);
:= setup_timer_2(T2_DIV_BY_1,5,5);
:= enable_interrupts(INT_TIMER2);
:= enable_interrupts(global);
:=
:= while(true) {
:=
:= output_bit(PIN_A2,0);
:= output_b(0x55);
:=
:= output_bit(PIN_A2,1);
:=
:= delay_ms(1000);
:=
:= output_bit(PIN_A2,0);
:= output_b(0xAA);
:= output_bit(PIN_A2,1);
:=
:= delay_ms(1000);
:= }
:=}
/* Important to include this since you enabled the int */
#INT_TIMER2
void Timer2_ISR(void)
{
// Do whatever
}
:=
:=The 1sec. delays take up to 15 secconds to complete sometimes! I tried changing this by lowering the "#use delay(clock=20000000)" statement (20 Mhz clock). This works, but since I need very exact timing this is not a sufficient solution...
:=
:=Can anybody please help me? I have a deadline next monday...
:=Thanks in advance!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517177 |
|
|
Benny Dijk Guest
|
still got a problem with delay_ms/us |
Posted: Sat Aug 23, 2003 8:56 am |
|
|
<font face="Courier New" size=-1>Thank you for the reply.
I have implemented your advice (timer routine was already there, forgot to copy/paste it), but still no good reslut. My crystal works at 20 Mhz. This is in the header file:
#include <16F876.h>
#device adc=8
#use delay(clock=20000000)
#fuses HS, WDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#ZERO_RAM
#PRIORITY TIMER2
The timer routine only increments a counter, so that doesn't take very long.
I'm wandering if it could have something to do with the chip I'm using... It's a brand new one and I haven't done anything spooky with it...
Thanks again!</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517178 |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
Re: still got a problem with delay_ms/us |
Posted: Sat Aug 23, 2003 11:20 am |
|
|
:=<font face="Courier New" size=-1>Thank you for the reply.
:=
:=I have implemented your advice (timer routine was already there, forgot to copy/paste it), but still no good reslut. My crystal works at 20 Mhz. This is in the header file:
:=
:=#include <16F876.h>
:=#device adc=8
:=#use delay(clock=20000000)
:=#fuses HS, WDT, NOPROTECT, PUT, BROWNOUT, NOLVP
:=#ZERO_RAM
:=#PRIORITY TIMER2
:=
:=The timer routine only increments a counter, so that doesn't take very long.
:=
:=I'm wandering if it could have something to do with the chip I'm using... It's a brand new one and I haven't done anything spooky with it...
:=
:=Thanks again!</font>
Are you sure you want the WDT Watch dog timer enabled?
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517179 |
|
|
Benny Dijk Guest
|
Re: still got a problem with delay_ms/us |
Posted: Sat Aug 23, 2003 11:35 am |
|
|
<font face="Courier New" size=-1>I've tried some things and just found out that timer 2 is the problem. I don't know why, but as soon as I enable it, the problem occurs. This is the new source code:
#include <16F876.h>
#device adc=8
#use delay(clock=20000000)
#fuses HS,NOWDT, NOLVP, NOBROWNOUT
#ZERO_RAM
#int_TIMER2
TIMER2_isr() {
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,5,5);
enable_interrupts(INT_TIMER2); // This line causes the problem
enable_interrupts(global); // but removing this one helps aswell (logical since it will not permitt any interrupts then)
while(1) {
output_bit(PIN_A2,0);
output_b(0x55);
output_bit(PIN_A2,1);
delay_ms(1000);
output_bit(PIN_A2,0);
output_b(0xAA);
output_bit(PIN_A2,1);
delay_ms(1000);
}
}
As you can see I have indeed disabled the watchdogtimer...
Thank you again...</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517180 |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
Re: still got a problem with delay_ms/us |
Posted: Sat Aug 23, 2003 8:06 pm |
|
|
What PIC16F876 are you using? They usually come in PIC16F876-04 and PIC16F876-20 models.
PIC16F870 is a 20MHz device, but not all PIC16F876 are. Maybe you are using a PIC16F876-04 (which is a 4MHz device) with a 20MHz crystal?
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517185 |
|
|
Benny Dijk Guest
|
Re: still got a problem with delay_ms/us |
Posted: Sun Aug 24, 2003 1:06 pm |
|
|
Thank you for your reply.
I'm using the model that says 041/SP, and cannot find any modelspecific information on the website... Can anyone tell me if this a 20 Mhz model?
Regards,
Benny
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517195 |
|
|
schlosser Guest
|
Re: still got a problem with delay_ms/us |
Posted: Sun Aug 24, 2003 2:27 pm |
|
|
The timer routine takes 4 cycles, but the ISR takes about 48!!
If timer2 generates an interrupt every 25 cycles (5*5) the delay_ms will run very slow, because it is always interruptet by timer2.
Greetings
RS
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517197 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: still got a problem with delay_ms/us |
Posted: Sun Aug 24, 2003 3:09 pm |
|
|
On the chip it should read
PIC16F876-20/SP
Note that the SP is the package type and the 20 is the maximum speed.
:=Thank you for your reply.
:=
:=I'm using the model that says 041/SP, and cannot find any modelspecific information on the website... Can anyone tell me if this a 20 Mhz model?
:=
:=Regards,
:=
:=Benny
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517198 |
|
|
R.J.Hamlett Guest
|
Re: still got a problem with delay_ms/us |
Posted: Mon Aug 25, 2003 2:57 am |
|
|
:=<font face="Courier New" size=-1>I've tried some things and just found out that timer 2 is the problem. I don't know why, but as soon as I enable it, the problem occurs. This is the new source code:
:=
:=#include <16F876.h>
:=#device adc=8
:=#use delay(clock=20000000)
:=#fuses HS,NOWDT, NOLVP, NOBROWNOUT
:=
:=#ZERO_RAM
:=
:=
:=#int_TIMER2
:=TIMER2_isr() {
:=
:=}
:=
:=void main() {
:=
:= setup_adc_ports(NO_ANALOGS);
:= setup_adc(ADC_OFF);
:= setup_spi(FALSE);
:= setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
:= setup_timer_1(T1_DISABLED);
:= setup_timer_2(T2_DIV_BY_1,5,5);
I'm not surprised...
Two comments. The chip you have is the nominally 4MHz part, but
will probably work at 20MHz, _provided_ the supply is 5v, and the temperature range is fairly low. However it is not guaranteed, and you really need the -20 part.
The big problem though is this interrupt. The chip is running at 20MHz, and the command above, is telling it to call the timer2 interrupt service routine, every 100 machine cycles (25 instruction times). The 'overhead' for the interrupt handler, is typically 20-30 instruction times (remember the interrupt routine is not directly called, instead the 'int_global' routine is called, which has to save several registers, then check which interrupt has occured, call the handler routine, wait for it to return, then reset the interrupt flag, restore the registers, and exit. It is probably only working at all, because it is actually 'missing' every other interrupt, and then managing to get back to the main code, and execute a couple of instructions before the interrupt occurs again. You are trying to interrupt 200000 times/second. Realistically, even on a 20MHz part, with a very short interrupt handler routine, I'd set a limit at perhaps 10000 interrupts/second, as a 'practical max', to leave some time for other things to be done...
Best Wishes
:= enable_interrupts(INT_TIMER2); // This line causes the problem
:= enable_interrupts(global); // but removing this one helps aswell (logical since it will not permitt any interrupts then)
:=
:=
:= while(1) {
:=
:=output_bit(PIN_A2,0);
:=output_b(0x55);
:=
:=output_bit(PIN_A2,1);
:=
:=delay_ms(1000);
:=
:=output_bit(PIN_A2,0);
:=output_b(0xAA);
:=output_bit(PIN_A2,1);
:=
:=
:=delay_ms(1000);
:=
:=}
:=
:=}
:=
:=
:=As you can see I have indeed disabled the watchdogtimer...
:=
:=Thank you again...</font>
___________________________
This message was ported from CCS's old forum
Original Post ID: 144517209 |
|
|
|
|
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
|