|
|
View previous topic :: View next topic |
Author |
Message |
CMatic
Joined: 11 Jan 2012 Posts: 69
|
PWM Problem on PIC16F1825 |
Posted: Sun Nov 01, 2015 12:22 am |
|
|
I can't switch PWM outputs from RA5 to RC0 pins.
My compiler version is 5.026
Here is my code, thanks very much for your help.
Code: |
#include <16F1825.h>
#use delay(internal=8000000)
#FUSES NOCLKOUT //I/O function on OSC2
#FUSES NOWDT //Watch dog timer
#FUSES INTRC_IO //Internal RC Osc
#FUSES NOPROTECT //Code Protection
#FUSES NOBROWNOUT //Brown-out
#FUSES NOCPD //Data Protection
#FUSES NOFCMEN //Fail-Safe Clock Monitor Enable Bit
#FUSES NOIESO //Internal External Switchover bit
#FUSES NOPUT //Power Up Timer
#FUSES NOMCLR //Memory Clear
#FUSES NOWRT //No Program Memory write Protected
#FUSES NOSTVREN //No Stak full/underflow reset
#FUSES NODEBUG // No Debug mode for ICD
#FUSES NOLVP //No Low Voltage Programming
#FUSES NOCLKOUT //No Clock Out on pin A4
#include <stdio.h>
//////////////////////////////////////////////////////////
// //
// PROTOTYPES //
// //
//////////////////////////////////////////////////////////
void Initialize();
//////////////////////////////////////////////////////////
// //
// DEFINES / VARIABLES //
// //
//////////////////////////////////////////////////////////
#define BUZ PIN_A5
#bit CCP2SEL = getenv("BIT:CCP2SEL")
#bit P2BSEL = getenv("BIT:P2BSEL")
#bit P1CSEL = getenv("BIT:P1CSEL")
#bit P1DSEL = getenv("BIT:P1DSEL")
#byte APFCON0=getenv("SFR:APFCON0")
#byte APFCON1=getenv("SFR:APFCON1")
//////////////////////////////////////////////////////////
// //
// FUNCTIONS //
// //
//////////////////////////////////////////////////////////
//**************************************
// Initialize
// Function to initialize uC and LCD
//**************************************
void Initialize() {
setup_ccp1(CCP_PWM);
P1DSEL = 1;
output_drive(PIN_C0);
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(128);
//clear_interrupt(INT_TIMER0);// Clear Timer 0 interrupt
clear_interrupt(INT_TIMER2);//PWM
clear_interrupt(INT_CCP1); //PWM
enable_interrupts(INT_CCP1);//PWM
enable_interrupts(INT_TIMER2);//PWM
//enable_interrupts(int_timer0);// Enable Timer 0 interrupt
enable_interrupts(GLOBAL); // enable all interrupts
} //End of Init routine
//////////////////////////////////////////////////////////
// //
// INTERRUPTS //
// //
//////////////////////////////////////////////////////////
/*********************************************************
* TIMER0_ISR
*
* Generates Beep tones
**********************************************************/
#INT_TIMER0//TIMER0 Interrup overflows
void Timer0_isr() {
clear_interrupt(INT_TIMER0); //Clear Interrupt Flag
}
#INT_TIMER2//TIMER2 Interrup overflows
void Timer2_isr() {
output_toggle(BUZ);
clear_interrupt(INT_TIMER2);
}
#INT_CCP1 // CCP1 Interrupt
void CCP1_isr() {
output_toggle(BUZ);
clear_interrupt(INT_CCP1);//
}
//////////////////////////////////////////////////////////
// //
// MAIN PROGRAM //
// //
//////////////////////////////////////////////////////////
void main() {
Initialize();
int m;
for (m=0; m<=500; m++)
{
set_pwm1_duty(m);
delay_ms(50);
}
while(TRUE) {
}// While loop
}// Main Loop |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19494
|
|
Posted: Sun Nov 01, 2015 4:45 am |
|
|
Some comments:
1) The clear_interrupt calls in the interrupt routines are pointless. The compiler automatically clears interrupts _unless told not to, by using NOCLEAR_.
2) You really want STVREN selected. NOSTVREN, requires (to have any hope of working at all reliably if the stack does overflow), that you add code to check the stack status. Otherwise 'anything can happen in the next half hour'....
3) The actual movements you can do, are only those allowed by the chip. C0, is the default location for P1D. No re-mapping needed. However you then have to see how to get the output from P1D. The answer to this is 'pulse steering'. This is controlled by the PSTRxCON register. In CCS, this is setup in the setup_CCP function:
Code: |
setup_ccp1(CCP_PWM | CCP_PULSE_STEERING_D);
|
This routes the single CCP PWM output,, to it's D output.
No need to touch CCPSEL, APFCON, or any other register. |
|
|
CMatic
Joined: 11 Jan 2012 Posts: 69
|
|
Posted: Sun Nov 01, 2015 7:47 am |
|
|
Ttelmah wrote: | Some comments:
1) The clear_interrupt calls in the interrupt routines are pointless. The compiler automatically clears interrupts _unless told not to, by using NOCLEAR_.
2) You really want STVREN selected. NOSTVREN, requires (to have any hope of working at all reliably if the stack does overflow), that you add code to check the stack status. Otherwise 'anything can happen in the next half hour'....
3) The actual movements you can do, are only those allowed by the chip. C0, is the default location for P1D. No re-mapping needed. However you then have to see how to get the output from P1D. The answer to this is 'pulse steering'. This is controlled by the PSTRxCON register. In CCS, this is setup in the setup_CCP function:
Code: |
setup_ccp1(CCP_PWM | CCP_PULSE_STEERING_D);
|
This routes the single CCP PWM output,, to it's D output.
No need to touch CCPSEL, APFCON, or any other register. |
Thanks for the reply. Your points 1 and 2 are great and I have fixed the code for these. However, here is what I tried with my program
setup_ccp1(CCP_PWM | CCP_PULSE_STEERING_D);
output_drive(PIN_C0); //from some previous PWM posts in this forum
setup_timer_2(T2_DIV_BY_1, 255, 1);
My PWM output seems to be stuck on RA5 pin when I last configured the PWM CCP2 module using the following code lines:
setup_ccp2(CCP_PWM);
CCP2SEL = 1;
output_drive(PIN_A5);
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm2_duty(128);
Thanks for looking into this. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19494
|
|
Posted: Sun Nov 01, 2015 9:54 am |
|
|
Apologies. The data sheet has an error, it lists P1D, as defaulting to C0, but it defaults to C2 (it should be coming out here after it is selected).
You need to add:
Code: |
#bit P1DSEL=getenv("BIT:P1DSEL")
//and use:
setup_ccp1(CCP_PWM | CCP_PULSE_STEERING_D); //C2
P1DSEL=TRUE; //Now C0
output_float(PIN_C2); //The compiler will have set this as output
output_drive(PIN_C0); //and you need to set this as output
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(128);
|
Beware also, 'm' needs to be an int16. Currently the loop will never exit.... |
|
|
CMatic
Joined: 11 Jan 2012 Posts: 69
|
|
Posted: Sun Nov 01, 2015 2:23 pm |
|
|
Ttelmah wrote: | Apologies. The data sheet has an error, it lists P1D, as defaulting to C0, but it defaults to C2 (it should be coming out here after it is selected).
You need to add:
Code: |
#bit P1DSEL=getenv("BIT:P1DSEL")
//and use:
setup_ccp1(CCP_PWM | CCP_PULSE_STEERING_D); //C2
P1DSEL=TRUE; //Now C0
output_float(PIN_C2); //The compiler will have set this as output
output_drive(PIN_C0); //and you need to set this as output
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(128);
|
Beware also, 'm' needs to be an int16. Currently the loop will never exit.... |
Thank you so much, its now working. Ttelmah I appreciate your help very much. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19494
|
|
Posted: Mon Nov 02, 2015 3:34 am |
|
|
Good |
|
|
|
|
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
|