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

use timer0 to gen 400KHz - need help

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



Joined: 06 Jan 2009
Posts: 15

View user's profile Send private message

use timer0 to gen 400KHz - need help
PostPosted: Tue Jan 27, 2009 10:33 pm     Reply with quote

hi all,

I'm trying to create a PPM ultrasonic pulse at 200KHz using timer0. So, what it's in my mind is:

- provide a character
- use timer0 as a counter to toggle a pin high and low until the character is done.

problem:
I've used 18F4431 and 16F88, but I've encountered the exact same problem: timer0 is stuck at 9.7KHz and no matter what value I've put into set_timer0(value), nothing happens. The only thing that changes the frequency is by changing the RTCC_div_#.

here's the code:
what it does at the moment is to check the frequency of the timer0. It has nothing to do with PPM. It just toggles PIN_B3, or pin9 of 16F88 to high and low so it generates a 50% duty_cycle square wave.

compiler: 4.038

Code:

#include <16F88.h>

#fuses hs,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOWRT
#use delay(clock=20000000)
//
//#id 0x0819

//include files here..........
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//#include <brianlcd.c>
#include <string.h>
//#include <lcd_menu.c>

//#use rs232 (baud = 115200, xmit = UART_TX, rcv = UART_RX, bits = 8, parity = N,errors)

//**************************************************************************************************************
//define global variables
//**************************************************************************************************************
int8 num;
int16 sensor1_time=0, sensor2_time=0;
int1 calc_distance = 0;
int1 PPM_flag=0, detection=0, test_timer0=0, test_timer1=0, test_timer2=0;
int8 timer_overflow=0;

//**************************************************************************************************************
//**************************************************************************************************************
//set timer0 as the 1st priority


//**************************************************************************************************************
//Timer0 interrupt routine
//**************************************************************************************************************
#int_timer0
void Timer0_isr()
{
   //PPM_flag = 1;
   output_bit(PIN_B3,test_timer0);
   if(test_timer0==0)
      test_timer0 = 1;
   else
      test_timer0 = 0;
   
}

     
//**************************************************************************************************************
// MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN
//**************************************************************************************************************
void main ()
{
   int16 period, duty_max, duty_value;
   int8 state=0;
   
   setup_adc_ports(NO_ANALOGS); //= 0x06; //00000110   all digital to start
   
 
   //****************************************************************************************
   //setup timer0
   //****************************************************************************************
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT);
   set_timer0(243);   
 
   //****************************************************************************************
   //Setup interrupts
   //****************************************************************************************
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
   
   //Frequency = Fosc / (4 * (period+1) *postscale)   

 
//**************************************************************************************************************
// WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP WHILE LOOP
//**************************************************************************************************************
   while (1)
   {       
     
   }
}
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: use timer0 to gen 400KHz - need help
PostPosted: Tue Jan 27, 2009 11:00 pm     Reply with quote

Setting Timer 0 has nothing to do with the frequency with which Timer 0 interrupts occur. You call set_timer0() just once during setup. From that point on, Timer 0 counts up and overflows from 0xff to 0x00. On each overflow, you get an interrupt where you toggle the output pin. But Timer 0 does not reload that initial value again. It just continues counting up from 0x00. If you want to change the frequency, you will have to set Timer 0 every time in the interrupt routine. But this won't work for you either because 400,000 interrupts per second means 2.5 usec. per interrupt. That's only 12.5 instruction times. That is not enough to get into the interrupt, do something, at get back out.

You have a better chance of generating the signal you want using Timer 2 and PWM.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Briany



Joined: 06 Jan 2009
Posts: 15

View user's profile Send private message

Re: use timer0 to gen 400KHz - need help
PostPosted: Tue Jan 27, 2009 11:09 pm     Reply with quote

RLScott wrote:
Setting Timer 0 has nothing to do with the frequency with which Timer 0 interrupts occur. You call set_timer0() just once during setup. From that point on, Timer 0 counts up and overflows from 0xff to 0x00. On each overflow, you get an interrupt where you toggle the output pin. But Timer 0 does not reload that initial value again. It just continues counting up from 0x00. If you want to change the frequency, you will have to set Timer 0 every time in the interrupt routine. But this won't work for you either because 400,000 interrupts per second means 2.5 usec. per interrupt. That's only 12.5 instruction times. That is not enough to get into the interrupt, do something, at get back out.

You have a better chance of generating the signal you want using Timer 2 and PWM.


great thanks. But I have a question: how did you figure out it's 12.5 instruction times? and what is the minimum instruction times needed for timer0, timer1 and timer2 @ 20MHz?

do you mean that I have to set_timer0(243) before the timer0_isr() ends?

Code:

#int_timer0
void Timer0_isr()
{
   //PPM_flag = 1;
   output_bit(PIN_B3,test_timer0);
   if(test_timer0==0)
      test_timer0 = 1;
   else
      test_timer0 = 0;

   set_timer0(243);
   
}



If this is correct, I'll move this to timer2 and test it out.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 28, 2009 2:17 am     Reply with quote

He didn't mean switch to Timer2. He meant you should use the PWM
module in the PIC.

See this thread for the PWM frequency formula and code to setup
the PWM controller.
http://www.ccsinfo.com/forum/viewtopic.php?t=17993

How to get the maximum PWM frequency:
http://www.ccsinfo.com/forum/viewtopic.php?p=99719
Briany



Joined: 06 Jan 2009
Posts: 15

View user's profile Send private message

PostPosted: Wed Jan 28, 2009 3:11 am     Reply with quote

PCM programmer wrote:
He didn't mean switch to Timer2. He meant you should use the PWM
module in the PIC.

See this thread for the PWM frequency formula and code to setup
the PWM controller.
http://www.ccsinfo.com/forum/viewtopic.php?t=17993

How to get the maximum PWM frequency:
http://www.ccsinfo.com/forum/viewtopic.php?p=99719



thanks for the links PCM.

I've another question.
Since PWM via CCP is the only way to generate high frequency, and that I already have 18F4431 with hardware PWM built in it, can I use those to generate 200KHz data stream using that PIC? I've been playing around with the single shot feature, but I don't know how to set it to trigger every time I want it to fire.

I'm trying to create a PPM pulse, without using the CCP pins. I'm reserving the CCP pins for receiving part, and I want to keep the circuit as simple as possible.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Wed Jan 28, 2009 7:18 am     Reply with quote

Briany wrote:

...I'm trying to create a PPM pulse, without using the CCP pins. I'm reserving the CCP pins for receiving part, and I want to keep the circuit as simple as possible.

OK, if you must generate 200 kHz without using the CCP module, another option is to generate it using software:
Code:

  PulseCount = 150;  //..total number of pulses generated
#ASM
  goto PulseGenTop   ; skip over the delay subroutine
DelayShort:
  nop
  nop
  nop
  nop
  nop
  return

PulseGenTop:
  bsf  PORTB,3
  call DelayShort   ; 1.8 uSec
  nop
  nop
  bcf  PORTB,3
  call DelayShort   ; 1.8 uSec
  decfsz PulseCount,f
  goto PulseGenTop
#ENDASM

If you use this method you will have to know in advance how many pulses you want to generate, you must have interrupts disabled, and your software is totally tied up doing this so it can't do anything else while it is generating a pulse stream.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Briany



Joined: 06 Jan 2009
Posts: 15

View user's profile Send private message

PostPosted: Wed Jan 28, 2009 10:18 pm     Reply with quote

thanks a lot RLScott!

I have one last question.

is it possible to set up the hardware PWM off of a 18F4431 and set it to single shot mode to do that?

I've encountered problems with the single shot mode and wasn't able to get it to do the pulse generation. 200KHz is still an awfully lot of time for the PIC. I'm trying to experiment with all of the available methods in my hand.

The best way is to have my software running for something else, because I'll have UART running, but I think the most important thing is to have an accurate pulse generation, which I might have now (just logged on and hasn't tested the code yet).
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