View previous topic :: View next topic |
Author |
Message |
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Thu Jan 12, 2012 6:36 pm |
|
|
Hie everyone. Please help check my program. It initially seemed to work, with the microchip switching on and off outputs B_5 accordingly. I was in the process of checking my PWM code when on re-installation, the chip seemed to have stopped responding to inputs. When I checked for PWM pulses on the scope only one set had a signal. I use PICkit 2 for loading the program compiled with the CCS compiler. Unfortunately I have no in circuit debugger and besides, this is my first ever task with a PIC. I also suspect I changed one of the declarations but after so many attempts I don't remember much. I have tried several PIC16F690 with the same result.
Here is the code ... and thank you all in desperate anticipation.
Code: | //source code file: control.c ......18/12/2011
//Program function: controls dc bus, battery charging and inverter... Basic UPS control setup
#include "16f690.h"
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer ON
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES IESO //Internal switch over mode ON
#FUSES FCMEN //Fail safe clock monitor enabled
#FUSES NOCPD //No code protection from EE
#FUSES NOPROTECT //No code read protection
#use delay(int=32000)
#use FIXED_IO( B_outputs=PIN_B5 )
#define charge_control PIN_B5 //output to control battery charging Mos
#define mains_detect PIN_C0 //input to signal mains power failure
#define low_charge PIN_C6 //input to signal deep battery discharge
#define max_charge PIN_C7 //input to signal maximum battery charge level
void main()
{
while(True) //loop always....stop processor from going to sleep
{
if((!input(PIN_C7))&&(input(PIN_C0))) //this block controls the battery charging circuit: charge up for as long as mains is available
output_high(pin_B5);
else output_low(pin_B5);
{
while((input(PIN_C6)) && (input(PIN_C0))) //set condition for ECCP1 >>PWM parameter setting:
{setup_timer_2(T2_DIV_BY_1,154,1); //prescaler and post scaler set>> 1,
setup_ccp1(CCP_PWM|CCP_PWM_FULL_BRIDGE|CCP_SHUTDOWN_AC_L|CCP_SHUTDOWN_BD_L); //set shutdown mode
set_pwm1_duty((int16)1); //98% duty cycle
setup_comparator(NC_NC_NC_NC); //not used>> no comparator.
}
}
} |
Last edited by chrismdube on Fri Jan 13, 2012 1:36 pm; edited 1 time in total |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Jan 13, 2012 12:15 pm |
|
|
I would need to see the schematic to know
but I bet one of your "sense" inputs damaged the PIC and thats why it worked and did not later.
Pulling a pic pin above its Vcc without an appropriate series protection resistor can wreck the part in millisecs. |
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS Code |
Posted: Fri Jan 13, 2012 1:17 pm |
|
|
Probably. However, I have since tried a different chip and the same happened. My inputs are all below Vcc @4.5V. My Vcc comes off a 5V fixed regulator. I will attach the schematic later when I get home. I was actually trying to refine my code to get my PWM working. In the process of uninstalling and reprograming the chip (several times), it just stopped working and I can't get back on my feet again. Kinda desperate too because it's a near overdue assignment. What are the chances of the compiler playing tricks on me?
Thanks for the response. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Jan 13, 2012 1:54 pm |
|
|
I see the code you want to use to shut down the PWM section.
( and sorry but don't like the way it is structured at all )
But where is the code that initializes and adjusts the PWM when you ARE charging ?? That seems MIA.
This feels like you left out too much for me to get a real handle on the TOTAL function here. |
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Fri Jan 13, 2012 3:32 pm |
|
|
Thanks again. I generated the PWM code using the Wizard. PMW drives an inverter during a power failure only and gets powered by the batteries (UPS). I have a sensor that detects power failure, another one detect slow battery voltage. As long as mains power is switched off (failed) and the battery voltage is ok, PMW should run.
When mains is available, the controller stops PMW and monitors battery charging.The circuit looks like this ... failed to attach[img][/img] |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jan 13, 2012 5:36 pm |
|
|
Several comments:
1) The program as posted has a terrible layout. Indentation is going all ways and makes it difficult to read.
2) After fixing the indentation it is immediately clear the program as posted will not compile as there is an '{' too many. Meaning you show us not the same program as you are testing with, a big no-no.
3) Why are you setting fixed_io for pin_B5? And then when you do set fixed_io, it becomes _your_ responsibility to set the TRIS register, which you don't and is most likely the cause for the B5 output to do nothing.
4) A #delay of 32kHz in combination with INTRC_IO? According to the datasheet this is not supported, 31kHz is. Funny, on my 4.077 compiler both variations generate the same code without a warning for the 32kHz setting being wrong.
5) Code: | setup_comparator(NC_NC_NC_NC); //not used>> no comparator. | Make your code more efficient by moving this outside the loop to the start of main. It is initialization code and needs to be executed only once at startup.
6) It is good practice to write constants in full capital letters. Had you used the #case specifier (as is default in all other compilers) you would have received errors for you mixing of 'True', 'PIN_C7' and 'pin_B5'.
7) Nice, you have defined constants explaining the function of each I/O-pin. Too bad you don't use them.
Here is your code again with the above mentioned issues corrected: Code: | //source code file: control.c ......18/12/2011
//Program function: controls dc bus, battery charging and inverter... Basic UPS control setup
#include "16f690.h"
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES PUT //Power Up Timer ON
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES IESO //Internal switch over mode ON
#FUSES FCMEN //Fail safe clock monitor enabled
#FUSES NOCPD //No code protection from EE
#FUSES NOPROTECT //No code read protection
#use delay(internal=31kHz)
#define CHARGE_CONTROL PIN_B5 //output to control battery charging Mos
#define MAINS_DETECT PIN_C0 //input to signal mains power failure
#define LOW_CHARGE PIN_C6 //input to signal deep battery discharge
#define MAX_CHARGE PIN_C7 //input to signal maximum battery charge level
void main()
{
setup_comparator(NC_NC_NC_NC); //not used>> no comparator.
while(TRUE) //loop always....stop processor from going to sleep
{
//this block controls the battery charging circuit: charge up for as long as mains is available
if ( !input(MAX_CHARGE) && input(MAINS_DETECT) )
output_high(CHARGE_CONTROL);
else
output_low(CHARGE_CONTROL);
while(input(LOW_CHARGE) && input(MAINS_DETECT)) //set condition for ECCP1 >>PWM parameter setting:
{
setup_timer_2(T2_DIV_BY_1, 154, 1); //prescaler and post scaler set>> 1,
setup_ccp1(CCP_PWM | CCP_PWM_FULL_BRIDGE | CCP_SHUTDOWN_AC_L | CCP_SHUTDOWN_BD_L); //set shutdown mode
set_pwm1_duty((int16)1); //98% duty cycle
}
}
} |
Open issues:
8) As Asmboy already mentioned, the code for switching off the PWM is still missing.
9) Always post your compiler version number, some compiler versions are known to have problems and this makes bug finding a lot easier.
10) Posting pictures is a bit difficult on this forum. You have to upload the picture to another place on the internet (your own web page or a website like imageshack.us) and then with the [img] tags you post the link to your picture.
11) Quote: | I use PICkit 2 for loading the program compiled with the CCS compiler. Unfortunately I have no in circuit debugger and | In Microchips MPLAB the Pickit2 can be used as an In Circuit Debugger. I'm happily setting breakpoints and single stepping the code with my Pickit2.
12) Repeatedly configuring the PWM in a while-loop is terrible! I haven't checked the datasheet but it is very well possible some of the registers will be initialized on each call, causing your PWM not to work as desired. Setup the PWM once and then do your checkin in a loop. |
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Fri Jan 13, 2012 9:00 pm |
|
|
Thanks loads for the advice. I apologize for the indentation but that happened on uploading. The code is as is and I have been compiling it with no errors and no warning but then it doesn't work, at least not as expected. For the PIC16F690 I understand I need a header to debug.
I have since downloaded the latest compiler version off the CCS site, updated MPLAB and re-programmed the chip. My outputs are now working apart from the PWM. P1A remains high always while the other terminals remain dead. I even tried my scope and there is nothing there, which makes me think there is something wrong with the code. I'm practically losing my marbles with this. I will try the corrections mentioned here next.
Please can someone confirm if the while condition is enough to initialise the PWM setup. Also, is this not enough to turn off the PWM module, i.e while TRUE...RUN PWM, while FALSE...STOP PWM? I hope this doesn't sound daft. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Jan 14, 2012 7:44 am |
|
|
For Timer2 the datasheet page 91 says: Quote: | The prescaler and postscaler counters are cleared
when:
• A write to TMR2 occurs.
• A write to T2CON occurs.
• Any device Reset occurs (Power-on Reset, MCLR
Reset, Watchdog Timer Reset or Brown-out
Reset). | As you are writing the T2CON register in a really fast loop this means the Timer2 will never overflow and trigger the PWM module, hence nothing happens. Easiest thing would be to configure the Timer2 at program startup and then let it running free forever, that is assuming you want to use a constant PWM rate and not change it during the charging process.
Quote: | Please can someone confirm if the while condition is enough to initialise the PWM setup. | At quick glance the configuration looks ok except that you shouldn't do it inside a while loop.
Quote: | Also, is this not enough to turn off the PWM module, i.e while TRUE...RUN PWM, while FALSE...STOP PWM? | No, this won't work. To start the PWM you enable it _once_, not in a loop. Then when ready you write other code to explicitly disable the PWM: Code: | setup_ccp1(CCP_OFF); |
Sorry, no complete example code as this is a (school) assignment. With the given hints you should be able to restructure your code to make it work. All code pieces are there, except the sequence is wrong. |
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Sat Jan 14, 2012 12:23 pm |
|
|
Thanks to everyone for your contribution. Since re-installing my compiler I have had some progress. The only glitch now is that I only get the forward mode output only. I was of the mind that to generate an AC output, I have to activate the reverse mode too. Does this mean I have to modify the code to accommodate both modes ? I appreciate the patience of all contributors, it's not easy dealing with a novice.
Please, please, can someone advice how to implement direction . |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Mon Jan 16, 2012 5:58 pm |
|
|
Thanks PCM programmer. Actually I've been struggling with that to get 50Hz output for near two days now. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
chrismdube
Joined: 30 Dec 2011 Posts: 20 Location: UK
|
CCS code |
Posted: Mon Jan 16, 2012 6:10 pm |
|
|
Thanks again. I'm looking now. |
|
|
|