View previous topic :: View next topic |
Author |
Message |
young
Joined: 24 Jun 2004 Posts: 285
|
how to produce PWM in 12f675? |
Posted: Wed Jul 28, 2004 9:12 am |
|
|
16f877 has
Code: |
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_16, 127, 1);
|
and
Code: |
set_pwm1_duty(duty);
|
to produce PWM signals, how to do it in 12f675 does 12f675 has a ccp1 and 12f675 does not have timer2 at least? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Jul 28, 2004 9:19 am |
|
|
You would have to roll your own. The 12F675 is a very simple device with not much peripherals. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Jul 28, 2004 9:34 am |
|
|
Thank you:
like
#define timeperiod 40
main()
{
while(1)
{
output_high(A4)
delay_us(30);
output_low(10);
delay_us(10);
}
}
right? |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Jul 28, 2004 9:35 am |
|
|
this way the minimum time period should be 1us which is 1mhz, so there is no way to produce higher frequency right? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Wed Jul 28, 2004 9:49 am |
|
|
There is the delay_cycles() function which will give you the smallest time increment possible, but you have to do the math with clock speed. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 28, 2004 10:59 am |
|
|
young wrote: | this way the minimum time period should be 1us which is 1mhz, so there is no way to produce higher frequency right? |
If you are running the chip at 20MHz, you could use 'delay_cycles(1)', to give 200nSec delay. However you then have the time to set the pin, the time to clear the pin, and the time to loop, on top of the delay...
Best Wishes |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Jul 28, 2004 2:50 pm |
|
|
Code: |
void produce_pwm(int8 duty)
{
output_high(PIN_A4);
delay_cycles(duty);
output_low(PIN_A4);
delay_cycles(255-duty);
}
|
when I compile this program, an "A numerical expression must appear here" in delay_cycles(duty); line at duty parameter, what is wrong with my program? |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Wed Jul 28, 2004 3:12 pm |
|
|
As per the manual entry for delay_cycles:
Quote: | DELAY_CYCLES( )
Syntax:
delay_cycles (count)
Parameters:
count - a constant 1-255
Returns:
undefined
Function:
Creates code to perform a delay of the specified number of instruction clocks (1-255). An instruction clock is equal to four oscillator clocks.
The delay time may be longer than requested if an interrupt is serviced during the delay. The time spent in the ISR does not count toward the delay time.
Availability:
All devices
Requires
Nothing
|
The parameter must be a constant between 1 and 255. A variable is not allowed as a parameter. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Wed Jul 28, 2004 3:37 pm |
|
|
so I have to use loop to get what I want, right?
for(i=0;i<duty;i++)
{
delay_cycles(1);
} |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Jul 29, 2004 7:00 am |
|
|
Why do you have to run so fast? Are you looking for cycle speed or resolution? If you tell us more about your application we may be able to suggest alternatives. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Guest
|
|
Posted: Fri Jul 30, 2004 6:43 am |
|
|
Thank you, I am trying to produce 0-5v analog output. |
|
|
Guest
|
|
Posted: Fri Jul 30, 2004 6:44 am |
|
|
and also, I want to simulate it at a high resolution, so that I can control the output device at very precise steps. |
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 30, 2004 10:39 am |
|
|
Anonymous wrote: | and also, I want to simulate it at a high resolution, so that I can control the output device at very precise steps. |
Unfortunately, you are probably not going to get what you want, without spending a lot of time 'tweaking'. The problem is that (for instance), the delay_cycles code does not support a variable, since it is allmost impossible to code this. Loops themselves take time. The 'constant' version, works out how many loops you need of a much slower loop, and 'pads' this with nop cycles to give an accurate time. using a variable, would still result in a delay in much larger steps (effectively delay_us).
You can get good accuracy with much lower frequencies, if you use a slower integration constant. The problem is if you want high rates of change, and good accuracy, then you need accurate timing, which is probably not really achievable in a software PWM.
I'd say you need to look at your chip choice. A 16F628/648, gives you a hardware PWM, and is a much better choice for an application like this (though bigger).
You are rather trying to use a nut to crack a sledgehammer... :-)
Best Wishes |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri Jul 30, 2004 12:06 pm |
|
|
Or look at adding a DAC chip. Maxim makes some good tiny ones with serial control. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
Hans Wedemeyer
Joined: 15 Sep 2003 Posts: 226
|
Here is a variable Cycle delay function |
Posted: Fri Jul 30, 2004 12:14 pm |
|
|
Ttelmah wrote: | Anonymous wrote: | and also, I want to simulate it at a high resolution, so that I can control the output device at very precise steps. |
Unfortunately, you are probably not going to get what you want, without spending a lot of time 'tweaking'. The problem is that (for instance), the delay_cycles code does not support a variable, since it is allmost impossible to code this. Loops themselves take time. The 'constant' version, works out how many loops you need of a much slower loop, and 'pads' this with nop cycles to give an accurate time. using a variable, would still result in a delay in much larger steps (effectively delay_us).
You can get good accuracy with much lower frequencies, if you use a slower integration constant. The problem is if you want high rates of change, and good accuracy, then you need accurate timing, which is probably not really achievable in a software PWM.
I'd say you need to look at your chip choice. A 16F628/648, gives you a hardware PWM, and is a much better choice for an application like this (though bigger).
You are rather trying to use a nut to crack a sledgehammer... :-)
Best Wishes |
I needed a variable cycle delay and like everyone I found the function delay_cycle() requires a constant argument.
There is a solution to variable cycle delay;
This is not pretty, but it gets the job done.
The switch has about 8 cycles overhead, so the minimum cycle delay is about 8.
This works well for variable cycle delay from 255 down to about 8.
just for fun... (C)Copyright 1997 Hans Wedemeyer, All Rights Reserved.... !
Best regards
Hans Wedemeyer
void CycleDelay(int Delay)
{
switch(i)
{
case 255:
#asm nop #endasm
case 254:
#asm nop #endasm
case 253:
#asm nop #endasm
case 252:
#asm nop #endasm
... fill in the blanks
case 100:
#asm nop #endasm
case 99:
#asm nop #endasm
case 98:
#asm nop #endasm
case 97:
#asm nop #endasm
case 96:
#asm nop #endasm
case 95:
#asm nop #endasm
case 94:
#asm nop #endasm
case 93:
#asm nop #endasm
case 92:
#asm nop #endasm
case 91:
#asm nop #endasm
... fill in the blanks
case 10:
#asm nop #endasm
case 9:
#asm nop #endasm
case 8:
#asm nop #endasm
Stop the case statements at about 8 because there is approximately 8 cycle overhead regardless.
Check the lst file to calculate the exact cycles.
}
} |
|
|
|