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

PIC24 running at 80MHz and Timer1 is too slow?

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







PIC24 running at 80MHz and Timer1 is too slow?
PostPosted: Wed Dec 17, 2008 9:58 am     Reply with quote

Hi all,

I use a PIC24HJ238GP306. Now I discovered 2 problems.

Problem no. 1:
As it looks like I can not use the FUSES to speed up my 16MHz oscillator with a PLL to 80MHz automaticly. So I use this code in my .h-File

Code:
#WORD OSCCON = 0x742            //Definieren der Oszillatorregister
#WORD CLKDIV = 0x744            //Definieren der Oszillatorregister
#WORD PLLFBD = 0x746            //Definieren der Oszillatorregister
#BIT  CLKDIV6 = CLKDIV.6         //Definieren der zu ändernden Oszillatorregisterpins
#BIT  CLKDIV12 = CLKDIV.12      //Definieren der zu ändernden Oszillatorregisterpins
#BIT  CLKDIV13 = CLKDIV.13      //Definieren der zu ändernden Oszillatorregisterpins
#BIT  PLLFBD1  = PLLFBD.1         //Definieren der zu ändernden Oszillatorregisterpins
#BIT  PLLFBD5  = PLLFBD.5         //Definieren der zu ändernden Oszillatorregisterpins

#use delay(clock=16000000)

In my main-file I set my missing bits to 80MHz operation.
Code:
CLKDIV6  = 0;
   CLKDIV12 = 0;
   CLKDIV13 = 0;
   PLLFBD1  = 1;
   PLLFBD5  = 0;


The problem is that all timings now have to be divided by 5 to work at the desired speed. Is there a method to get the timings right? I found no fuse where I can set the PLL to x5 my external osc so I did it manually.
This problem is more about good looking and not a real one.

problem no. 2:
I want to use my timer1 to generate Interrupts with a frequency of about 1.6MHz. With a 80MHz of clock-cycle I get 40MIPS. This is my code to check the maximum speed of Timer1:
Code:
setup_timer1(TMR_INTERNAL|TMR_DIV_BY_1,1);

enable_interrupts(INT_TIMER1);

#int_Timer1
void timer1_ISR(void) {
     static int a = 0;
     if (a == 0) {
          output_high(PIN_C2);
          a = 1;
     }
     else {
          output_low(PIN_C2);
          a = 0;
     }
}

The result is a frequency of about 388kHz (388.348kHz) at Pin C2. Using code like this
Code:
while(true) {
     output_high(PIN_C2);
     delay_us(1);
     output_low(PIN_C2);
     delay_us(1);
}

I can reach frequencies of more than 1 MHz at Pin C2. Due to my Module Block Diagram Timer1 can be feeded with Tcy (which should have at least a speed of around 10MHz) with a prescaler of 1. What is wrong with my timer1?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 17, 2008 12:08 pm     Reply with quote

I don't have the PCD compiler, but if the interrupt handling is done similar
to the PCH compiler, then 388 KHz is about right. Here's my reasoning:

It takes roughly 40 instruction cycles for the interrupt dispatcher code to
get in and out of your isr. Then let's say another 10 instructions for your
actual isr code, giving 50 instruction cycles total. This gives:
Code:
 40 MHz
-------- = 800 KHz
   50   

But, each pass through the isr only creates a rising or falling edge on
pin C2, so the actual frequency would be half of that:
Code:

 800 KHz
-------- = 400 KHz
   2

You'll have to look at the .LST file to confirm the length of the interrupt
dispatcher code, but I suspect that my thinking is correct.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Dec 17, 2008 12:16 pm     Reply with quote

Quote:
As it looks like I can not use the FUSES to speed up my 16MHz oscillator with a PLL to 80MHz automaticly.
Yes, the PLL isn't set from config bits, so CCS C has no #fuses statement for it. Generally, the compiler expects the real fosc value in the #use delay statement, so you have to write clock=80000.
Guest








PostPosted: Thu Dec 18, 2008 5:08 am     Reply with quote

Quote:
#use delay statement, so you have to write clock=80000


i did that but then my PIC isn't starting because i can set my bits later in my code only. When i try to set them before #use delay ... then i get a compiler error.
Matthias
Guest







PostPosted: Thu Dec 18, 2008 5:15 am     Reply with quote

edit:

this is the code form the .lst file for timer 1:

....................
.................... #int_Timer1 level=2
.................... void timer1_ISR(void) {
*
00200: PUSH 42
00202: PUSH 36
00204: MOV W0,[W15++]
00206: MOV #2,W0
00208: REPEAT #C
0020A: MOV [W0++],[W15++]
.................... static int a = 0;
*
00320: MOV #0,W4
00322: MOV W4,3F38
.................... if (a == 0 && schalter_an == 1) {
*
0020C: MOV 3F38,W0
0020E: CP0 W0
00210: BRA NZ,224
00212: MOV 3F36,W0
00214: CP W0,#1
00216: BRA NZ,224
.................... output_high(PIN_C2);
00218: BCLR.B 2CC.2
0021A: BSET.B 2D0.2
.................... a = 1;
0021C: MOV #1,W4
0021E: MOV W4,3F38
.................... }
.................... else {
00220: GOTO 22C
.................... output_low(PIN_C2);
00224: BCLR.B 2CC.2
00226: BCLR.B 2D0.2
.................... a = 0;
00228: MOV #0,W4
0022A: MOV W4,3F38
.................... }
.................... }
....................
0022C: BCLR.B 84.3
0022E: MOV #1A,W0
00230: REPEAT #C
00232: MOV [--W15],[W0--]
00234: MOV [--W15],W0
00236: POP 36
00238: POP 42
0023A: RETFIE

This is what i was measuring for different timer counter values:

counter -- frequency in kHz

1 -- 377

2 -- 377

3 -- 377

5 -- 377

10 -- 377

20 -- 377

30 -- 322

40 -- 325

50 -- 356

60 -- 328

70 -- 281

80 -- 247

90 -- 220

100 -- 198

150 -- 132

200 -- 99

300 -- 66

400 -- 50

500 -- 40

600 -- 33.3

700 -- 28.5

1000 -- 20

2000 -- 10

3000 -- 6.66

4000 -- 5

5000 -- 4

10000 -- 2

15000 -- 1.33

20000 -- 1.00

As you can see up to 200kHz it is no problem for the timer but above there are strange things happening whatever my counter value is (in that specific area).
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Dec 18, 2008 6:19 am     Reply with quote

Quote:
When i try to set them before #use delay ... then i get a compiler error.
No reason, to do that.

Quote:
i did that but then my PIC isn't starting because i can set my bits later in my code only.
I don't see a relation. #use delay is only informing the compiler, how to calculate constants, it's not configuring the CPU.
Matthias
Guest







PostPosted: Thu Dec 18, 2008 6:45 am     Reply with quote

Quote:
I don't see a relation. #use delay is only informing the compiler, how to calculate constants, it's not configuring the CPU.


I tested it again and now it worked. Perhaps i had another error before.

But my main problem still remains
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Dec 18, 2008 1:22 pm     Reply with quote

Your code is exactly behaving as expectable. The present version takes 49 respectively 54 instruction cycles, depending on the state of variable a. If the configured timer period is lower than 54 (period register value of 53) the interrupt execution stays behind timer events and you loose some interrupts, resulting in the interrupt frequencies as observed. An interrupt frequency of 1.6 MHz can't be achieved at all.

The most illustrative way, to visualize this behaviour is MPLAB simulator, using the stopwatch.

By the way, you didn't tell, what you exactly want to achieve, there may be better ways.

Best regards,
Frank
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