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

33Khz square wave generation with PIC16F676

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



Joined: 21 Oct 2008
Posts: 17

View user's profile Send private message

33Khz square wave generation with PIC16F676
PostPosted: Tue Oct 21, 2008 3:24 am     Reply with quote

Hello everybody,

I am new to this forum. Presently I am using CCS PCH for programming my PIC16F676. Mine is the purely time based project, is this compiler is suitable ? If so how can I program my timers to get 33 KHz frequency wave ? Here I want to use the internal 4Mhz oscillator.

thanks and regards
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: 33Khz square wave generation with PIC16F676
PostPosted: Tue Oct 21, 2008 5:20 am     Reply with quote

Set up Timer 2 so that it is clocked by the Fosc/4 (1 MHz), and set its period to 30. Set the duty cycle (CCPR1L) to 15. Then you will get a 50% duty cycle PWM signal at 33.33 kHz. But I think you will need to use the PCM compiler for the 16F series. The PCH compiler is for the 18F series.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
girichavana



Joined: 21 Oct 2008
Posts: 17

View user's profile Send private message

PostPosted: Sat Oct 25, 2008 1:27 am     Reply with quote

Thanks for ur replay,

Sorry for my mistake, actually I am using PCM compiler. You suggested that to use the Timer 2, but its not there in PIC16f676 . Can i use the Timer1?
Ttelmah
Guest







PostPosted: Sat Oct 25, 2008 3:18 am     Reply with quote

Not really.
Unfortunately, it'll be more complex on this chip. Timer2, has the nice ability for you to program the count where it resets. This allows you to generate quite accurate timings for jobs like this. On the 676, you are going to have to do the job 'in software'. A lot depends on what else you want to do with the chip?. If you only want a 33KHz waveform, with nothing else going on, then the 'simplest' solution, is just:
Code:

#include <16F676.h>
#device adc=8

#FUSES NOWDT,INTRC,NOPROTECT,BROWNOUT,NOMCLR,NOCPD,PUT,BANDGAP_HIGH         
#use delay(clock=4000000)

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_comparator(NC_NC);
   setup_vref(FALSE);

   while (TRUE) {
      output_high(PIN_A0);
      delay_us(11);
      output_low(PIN_A0);
      delay_us(9);
   }
}

This will give 33.33KHz, on pin A0.
You can do it with a timer, by but the arithmetic involved (you will have to add a count to the timer, or read it an perform a subtraction), makesit likely you will 'miss counts', since there is not a lot of time available between pulses....


Best Wishes
girichavana



Joined: 21 Oct 2008
Posts: 17

View user's profile Send private message

PostPosted: Sun Oct 26, 2008 12:07 am     Reply with quote

Thanks,

Your code is working properly, but my application includes some
other tasks. So here I want to use the Timer0 interrupt for this.

I want to calculate the Timer0 loadable value to get a certain frequency.

Regards
Ttelmah
Guest







PostPosted: Sun Oct 26, 2008 3:19 am     Reply with quote

You are not going to have any time.
The pulse width needed for each half cycle, is only _15_ instructions. You can simply run timer0, directly off the master clock (DIV_1), and add 241 to it, when it's interrupt flag is set. By the time you have done this, cleared the flag, and start waiting for it to set again, you are going to be running out of instruction.
You can save work, if you can accept a pulse, rather than a square wave. You then add 226 to the timer, and just pulse the output high, then one cycle latter, low. You then have 28 machine instructions to do things, till the next pulse is needed. Still not enough for anything much. Also, use the 'fast_io' mode, since this will save a couple of instructions on each change to the output.
To do other things, you really need to be clocking a lot faster. Clock the chip at 24MHz, and you have 182 instructions between leading edges (if you can accept a pulse output), for a 32967Hz output. Much better.
Alternatively, use a chip that does have a PWM output. The waveform, can then be generated by the hardware, leaving you time to do your other jobs.

Best Wishes
girichavana



Joined: 21 Oct 2008
Posts: 17

View user's profile Send private message

PostPosted: Sun Oct 26, 2008 7:14 am     Reply with quote

The following is the code that i have written. I have simulated this by using the PROTEUS. But it is giving 6kHz. I tested with oscilloscope also. The result is same.

#include <16F676.h>
#fuses NOWDT,INTRC,NOPROTECT,BROWNOUT,NOMCLR,NOCPD,PUT

#use delay(clock=4000000,type=internal)

#int_timer0
void timer0interrupt()
{
output_toggle(PIN_C4);
set_timer0(0xF1);
}

//=========main======

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
setup_timer_0(RTCC_INTERNAL);
set_timer0(0xF1);
while(1)
{

}

}
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Sun Oct 26, 2008 9:34 am     Reply with quote

girichavana wrote:
The following is the code that i have written. I have simulated this by using the PROTEUS. But it is giving 6kHz. I tested with oscilloscope also. The result is same.

Were you expecting 33kHz maybe? That is impossible. You are setting Timer 0 to 0xF1 because maybe you think it will take 15 more ticks to make 0x00, and that will cause the next interrupt. But you are forgetting that a lot of time went by from the previous overflow to where you are setting Timer 0. If you are seeing a 6 kHz waveform, then the time between transitions is now 83 uSec, where you wanted to see 15 uSec. The extra 68 uSec probably came from the time it takes the CCS interrupt handler to determine that Timer 0 was the source plus the time it took to toggle the output bit. That could easily add up to 68 uSec. If you want to make it faster, then write your own global interrupt handler and access the Timer 0 and PORTC registers directly instead of using CCS functions. But even if you do that, you will never get the output to 33 kHz, as Ttelmah so clearly showed in his last posting.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Ttelmah
Guest







PostPosted: Sun Oct 26, 2008 9:44 am     Reply with quote

Exactly.
You will get closer, if instead of physically interrupting, you _test_ the interrupt bit, and then add the offset, rather than just loading it, but I doubt if even like this, you will have more than one or two instructions 'in hand'. Certainly no time to actually do anything else.
I have posted about using polling of the interrupt bit inside the main code, as an alternative to an actual interrupt on several occassions. A search should find some stuff about this.

Best Wishes
girichavana



Joined: 21 Oct 2008
Posts: 17

View user's profile Send private message

PostPosted: Tue Oct 28, 2008 8:38 am     Reply with quote

Thanks,

I got the 33khz with the ASM. How can I include the ASM routine in the CCS C ?

Regards
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Tue Oct 28, 2008 10:30 am     Reply with quote

girichavana wrote:
Thanks,
I got the 33khz with the ASM. How can I include the ASM routine in the CCS C ?
Regards

Use the #ASM / #ENDASM directives.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
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