I would like to find some code on internet for variable software PWM regulation for 16F84(A).
For example i would use 2 buttons one for increasing and other for decrasing duty cycle.
Anybody hlp me?
Variable software PWM 16F84(a)
Nobody I have written many many PWM programs in mikroBASIC which are posted in the forums. JPC has written much about it in the forums in mikroPASCAL. We both have PWM projects posted in mikroElektronika's Project Wepage.N_Tesla wrote:Im yust testing your knowlage and as i can see nobody knows how.
But PWM is a big word and the PIC has its capabilities and its limits. You need to be more specific about your PWM request....such as what period are you after? What is the range of your duty-cycle?.....and so on.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
Im a beginer so i would like to do that:
2 push buttons (one for up and one for down) one transistor conected to pic 16f84A an one DC motor controled by the PWM signals from pic microcontrolers wich are "driving" the transistor that is driving the DC motor.
So when i push one butn PWM signals (duty cycles) are longer and are incrising all the time the button is pressed up to full speed. And other button when its pressed the duty cycle lowers and so does the speed and power of DC motor.
I know this is wery simple but if u are a bigginer its hard.
I found on internet examples of PWM but in all the frequency is fix and the only way to change the duty cycle is to rewrite program and flash it again. I would like to use buttons and have a program for it.
So far i know how to produce PWM pulses and control I/O pins i know how to write a program that reads "button presed" but i dont know how to write the program that would combine button presed with increasing/decreasing duty cycle of PWM produced.
2 push buttons (one for up and one for down) one transistor conected to pic 16f84A an one DC motor controled by the PWM signals from pic microcontrolers wich are "driving" the transistor that is driving the DC motor.
So when i push one butn PWM signals (duty cycles) are longer and are incrising all the time the button is pressed up to full speed. And other button when its pressed the duty cycle lowers and so does the speed and power of DC motor.
I know this is wery simple but if u are a bigginer its hard.
I found on internet examples of PWM but in all the frequency is fix and the only way to change the duty cycle is to rewrite program and flash it again. I would like to use buttons and have a program for it.
So far i know how to produce PWM pulses and control I/O pins i know how to write a program that reads "button presed" but i dont know how to write the program that would combine button presed with increasing/decreasing duty cycle of PWM produced.
These are in mikroBASIC but they may give you some ideas:
http://www.mikroe.com/forum/viewtopic.php?t=4994
This one also uses pushbuttons to change the duty cycle:
http://www.mikroe.com/forum/viewtopic.php?t=5667
http://www.mikroe.com/forum/viewtopic.php?t=4994
This one also uses pushbuttons to change the duty cycle:
http://www.mikroe.com/forum/viewtopic.php?t=5667
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]
[url=http://circuit-ed.com]CircuitED -[/url]
Hi N Tesla,
I wrote some code for software PWM using interrupts about a month ago for mikroPascal. You can easily convert it to mikroC
Here is the code:
This code is working on a PIC16F88 at 8MHz.
Anton
I wrote some code for software PWM using interrupts about a month ago for mikroPascal. You can easily convert it to mikroC
Here is the code:
This code is working on a PIC16F88 at 8MHz.
Code: Select all
//*****************************************************************************
// This program will enable you to use 4 software PWM channels on the PIC16
// The PWM frequency is about 400Hz using a 8 MHz crystal, but can go up to
// 1kHz with a 20MHz crystal.
// The PWM resolution is in 100 steps, from 1 to 100
//
// Anton Rieckert anton.rieckert@gmail.com www.riecktron.za.net
// mikroPascal v5.03
// 5 June 2006
//*****************************************************************************
program Software_PWM;
const
___PWM1 : byte = 0; // Output pin for first channel
___PWM2 : byte = 1; // Output pin for second channel
___PWM3 : byte = 2; // Output pin for third channel
___PWM4 : byte = 3; // Output pin for forth channel
var
DutyCycle : array[4] of byte; // This is where each channel's duty cycle
// is stored
IntCycle : byte; // Variable for the interrupt
Procedure Interrupt;
Begin
asm
// PWM Channel 1
BSF STATUS, C
MOVF main_global_dutycycle, W
SUBWF main_global_intcycle, W
BTFSS STATUS, C
BSF PORTB, ___PWM1
BTFSC STATUS, C
BCF PORTB, ___PWM1
// PWM Channel 2
BSF STATUS, C
MOVF main_global_dutycycle + 1, W
SUBWF main_global_intcycle, W
BTFSS STATUS, C
BSF PORTB, ___PWM2
BTFSC STATUS, C
BCF PORTB, ___PWM2
// PWM Channel 3
BSF STATUS, C
MOVF main_global_dutycycle + 2, W
SUBWF main_global_intcycle, W
BTFSS STATUS, C
BSF PORTB, ___PWM3
BTFSC STATUS, C
BCF PORTB, ___PWM3
// PWM Channel 4
BSF STATUS, C
MOVF main_global_dutycycle + 3, W
SUBWF main_global_intcycle, W
BTFSS STATUS, C
BSF PORTB, ___PWM4
BTFSC STATUS, C
BCF PORTB, ___PWM4
// Inc the counter
INCF main_global_intcycle, F
MOVF main_global_intcycle, W
SUBLW 100
BTFSC STATUS, Z
CLRF main_global_intcycle
BCF PIR1, TMR2IF
end;
End;
Procedure Init;
Begin
ADCON1 := 6; // Turn off the ADC
CMCON := 7; // Turn off the comparators
PORTB := 0; // Make PortB 0
TRISB := 0; // Make PortB output
// This is only for the P18F88, uncomment the next to lines if
// you are using the P16F88!!!
//OSCCON := $7E;
//OSCTUNE := $1F;
// Set the initial Duty Cycle
IntCycle := 1;
// Enable the TMR2 interrupt
INTCON := $C0; // enable TMR2 interrupt
SetBit(PIE1, TMR2IE);
SetBit(T2CON, TMR2ON);
PR2 := 5;
End;
Begin
Init;
// Just an example, you can see the brightness of LEDs
DutyCycle[0] := 1; // Set the first duty cycle to 1%
DutyCycle[1] := 25; // Set the second duty cycle to 25%
DutyCycle[2] := 50; // Set the third duty cycle to 50%
DutyCycle[3] := 80; // Set the forth duty cycle to 80%
Repeat Until 1 = 0;
End.
Another proud user of LV 24-33A Development System and mikroPascal PRO for dsPIC :)
PortA not working? Add CMCON := 7; PortD not working? Add ADCON1 := 6;
To paste code on the forum, please use the [b] Code [/b] button !! ;)
PortA not working? Add CMCON := 7; PortD not working? Add ADCON1 := 6;
To paste code on the forum, please use the [b] Code [/b] button !! ;)
Re: Variable software PWM 16F84(a)
Hi,
I don't if someone still read this post, but I have a trouble: I converted the anton small program for MikroPascal to MikroC, but if the program in Pascal works perfectly, I can't say the same stuff for the program in C.
where's my fault ??
Cheers
Angelo
I don't if someone still read this post, but I have a trouble: I converted the anton small program for MikroPascal to MikroC, but if the program in Pascal works perfectly, I can't say the same stuff for the program in C.
Code: Select all
short __PWM1 = 0; // Output pin for first channel
short __PWM2 = 1; // Output pin for second channel
short __PWM3 = 2; // Output pin for third channel
short __PWM4 = 3; // Output pin for forth channel
short dutycycle[4]; // This is where each channel's duty cycle
// is stored
short intcycle; // Variable for the interrupt
void interrupt() {
asm {
// PWM Channel 1
BSF STATUS, C;
MOVF _dutycycle, W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM1 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM1 ;
// PWM Channel 2
BSF STATUS, C ;
MOVF _dutycycle+1, W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM2 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM2 ;
// PWM Channel 3
BSF STATUS, C ;
MOVF _dutycycle+2 , W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM3 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM3 ;
// PWM Channel 4
BSF STATUS, C ;
MOVF _dutycycle+3 , W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM4 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM4 ;
// Inc the counter
INCF _intcycle, F ;
MOVF _intcycle, W ;
SUBLW 100 ;
BTFSC STATUS, Z ;
CLRF _intcycle ;
BCF PIR1, TMR2IF ;
}
}
void Init() {
// ADCON1 = 6; // Turn off the ADC
CMCON = 7; // Turn off the comparators
PORTB = 0; // Make PortB 0
TRISB = 0; // Make PortB output
// This is only for the P18F88, uncomment the next to lines if
// you are using the P16F88!!!
//OSCCON := $7E;
//OSCTUNE := $1F;
// Set the initial Duty Cycle
IntCycle = 1;
// Enable the TMR2 interrupt
INTCON = 0xC0; // enable TMR2 interrupt
pie1.tmr2ie=1;
t2con.TMR2ON=1;
PR2 = 255;
}
void main() { Init(); // Just an example, you can see the brightness of LEDs
dutycycle[0] = 1; // Set the first duty cycle to 1%
dutycycle[1] = 25; // Set the second duty cycle to 25%
dutycycle[2] = 50; // Set the third duty cycle to 50%
dutycycle[3] = 80; // Set the forth duty cycle to 80%
do {} while (1);
}
Cheers
Angelo
Re: Variable software PWM 16F84(a)
teicors wrote:Hi,
I don't if someone still read this post, but I have a trouble: I converted the anton small program for MikroPascal to MikroC, but if the program in Pascal works perfectly, I can't say the same stuff for the program in C.
where's my fault ??Code: Select all
// This is only for the P18F88, uncomment the next to lines if // you are using the P16F88!!! //OSCCON := $7E; //OSCTUNE := $1F;
Cheers
Angelo
Hi Angelo,
you have to uncomment the above lines if you are using a 16F88 and then change them to
Code: Select all
OSCCON = 0x7E;
OSCTUNE = 0x1F;
thanks,
madhu
Re: Variable software PWM 16F84(a)
How can i change this code to generate a PWM frequency more than 22kHz with a 25MHZ crystal?
Thank you!
Code: Select all
short __PWM1 = 0; // Output pin for first channel
short __PWM2 = 1; // Output pin for second channel
short __PWM3 = 2; // Output pin for third channel
short __PWM4 = 3; // Output pin for forth channel
short dutycycle[4]; // This is where each channel's duty cycle
// is stored
short intcycle; // Variable for the interrupt
void interrupt() {
asm {
// PWM Channel 1
BSF STATUS, C;
MOVF _dutycycle, W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM1 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM1 ;
// PWM Channel 2
BSF STATUS, C ;
MOVF _dutycycle+1, W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM2 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM2 ;
// PWM Channel 3
BSF STATUS, C ;
MOVF _dutycycle+2 , W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM3 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM3 ;
// PWM Channel 4
BSF STATUS, C ;
MOVF _dutycycle+3 , W ;
SUBWF _intcycle, W ;
BTFSS STATUS, C ;
BSF PORTB, ___PWM4 ;
BTFSC STATUS, C ;
BCF PORTB, ___PWM4 ;
// Inc the counter
INCF _intcycle, F ;
MOVF _intcycle, W ;
SUBLW 100 ;
BTFSC STATUS, Z ;
CLRF _intcycle ;
BCF PIR1, TMR2IF ;
}
}
void Init() {
// ADCON1 = 6; // Turn off the ADC
CMCON = 7; // Turn off the comparators
PORTB = 0; // Make PortB 0
TRISB = 0; // Make PortB output
// This is only for the P18F88, uncomment the next to lines if
// you are using the P16F88!!!
//OSCCON := $7E;
//OSCTUNE := $1F;
// Set the initial Duty Cycle
IntCycle = 1;
// Enable the TMR2 interrupt
INTCON = 0xC0; // enable TMR2 interrupt
pie1.tmr2ie=1;
t2con.TMR2ON=1;
PR2 = 255;
}
void main() { Init(); // Just an example, you can see the brightness of LEDs
dutycycle[0] = 1; // Set the first duty cycle to 1%
dutycycle[1] = 25; // Set the second duty cycle to 25%
dutycycle[2] = 50; // Set the third duty cycle to 50%
dutycycle[3] = 80; // Set the forth duty cycle to 80%
do {} while (1);
}
Thank you!