|
|
View previous topic :: View next topic |
Author |
Message |
alyeomans
Joined: 26 Feb 2014 Posts: 24
|
PIC18F4620 Will not run program |
Posted: Sun Jun 29, 2014 5:35 pm |
|
|
Hi All
Hoping for some advice on getting my project to run. I have written some simple code for a 18F4620 and it runs in debug when connected via the ICD2 however when programmed the MCU does not run. Note that the code below has been simplified from a project I am working on but my problems still persists.
Interestingly I have enabled the flag INTRC and I can see a square wave output on pin 31 which is at 500kHz.
See code below - any help would be great even if it proves how daft I am!
Code: |
#include <18F4620.h>
#device adc=10
//FUSES
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc, with CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP
#FUSES NOWRT //Program memory not write protected
#FUSES CCP2B3 //CCP2 output on RB3 and not RC1
#use delay(clock=8000000)
#use RS232 (BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7, STREAM = COM_A)
//pin definitions
#define LED2 PIN_A2
#define LED3 PIN_A3
#define LED4 PIN_A4
void main(void) {
//set port i/o
set_tris_a(0b00000011); //Outputs: A2,A3,A4 Inputs: A0, A1
//inital led state
output_low(LED2);
output_high(LED3);
output_low(LED4);
//main program loop
while(1) {
output_toggle(LED2);
output_toggle(LED3);
output_toggle(LED4);
delay_ms(500);
}
}
|
_________________ I type therefore I press buttons |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Sun Jun 29, 2014 5:53 pm |
|
|
On a 18F4520 it runs perfectly.
If you have an output on pin 31 it should be running.
I noticed the pins are also comparators and ADC.
Try disabling the comparators and ADCs.
I didn't have to for the 4520 but you may need to for the 4620.
Also, comment out the TRIS statement. You shouldn't need it. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19482
|
|
Posted: Sun Jun 29, 2014 10:53 pm |
|
|
You have got MCLR pulled up?.
Big difference when connected for debug, is that this pin is pulled up. You haven't got 'NOMCLR' selected, so the chip won't run till this is pulled up. |
|
|
alyeomans
Joined: 26 Feb 2014 Posts: 24
|
|
Posted: Mon Jun 30, 2014 12:11 am |
|
|
Development - after a clean then build this code does run and program without any troubles. However my project code is still not running so I will post the whole code below for comment.
dyeatman: Thanks for checking on your end. Even with the project code there is output on pin 31. I have not yet tried disabling the ADC or comparators yet in case the error is obvious.
Ttelmah: Yep have got 10K pullup and now the sample code above does run so a hardware issue seems to have been ruled out.
Code: |
#include <18F4620.h>
#device adc=10
//FUSES
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc, with CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP
#FUSES NOWRT //Program memory not write protected
#FUSES CCP2B3 //CCP2 output on RB3 and not RC1
#use delay(clock=8000000)
#use RS232 (BAUD = 9600, XMIT = PIN_C6, RCV = PIN_C7, STREAM = COM_A)
//pin definitions
//#define LED1 PIN_B3 //CCP2 output
#define LED2 PIN_A2
#define LED3 PIN_A3
#define LED4 PIN_A4
#define SW1 PIN_B4
#define SW2 PIN_B5
#define SW3 PIN_B6
#define ctrlCC PIN_C1
#define ctrlCV PIN_C2
//prototypes
void WRITE_FLOAT_EEPROM(long int n, float data);
float READ_FLOAT_EEPROM(long int n);
void LedsOff(void);
void ChargeType(int8);
void PwrLed(int8,int8);
void initTimers(void);
void initADC(void);
void adc_isr(void);
void timer1_isr(void);
void rb_isr(void);
//EEPROM memory offsets
long int AmpsX1RawN=0;
long int AmpsX2RawN=4;
long int VoltsX1RawN=8;
long int VoltsX2RawN=16;
//global vars
int16 val,dir,adc0value,adc1value;
char SwitchValue;
byte oldKey1;
byte oldKey2;
void main(void) {
output_high(LED2);
delay_ms(1000);
//interrupts
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
//set port i/o
//set_tris_a(0b00000011); //Outputs: A2,A3,A4 Inputs: A0, A1
//set_tris_b(0b01110000); //Outputs: B3 Inputs: B4,B5,B6
//set_tris_c(0b10000000); //Outputs: C0-C6 Inputs: C7 TX
//int stage;
initTimers(); //Timer 2 module: CCP1 and CCP2 PWM output using timer 2 running at 40 KHz
initADC();
ext_int_edge( H_TO_L );
//power up LED1 and set others low
PwrLed(1,10);
output_low(LED2);
output_low(LED3);
output_low(LED4);
//program start vars inits
SwitchValue='0'; //set in interrupt
ChargeType(0); //default OFF
int8 mode=0; //mode entry into if statements
int8 currentmode=3; //mode set to CHARGING as default
int8 chargeOn=0; //flag for charging
int8 chargeMode; //charging mode CC,CC,OFF
//calibration vars
double BatAmps, AmpsY1Val, AmpsY2Val, AmpsM, AmpsB;
int16 AmpsX1Raw, AmpsX2Raw;
double BatVolts, VoltsY1Val, VoltsY2Val, VoltsM, VoltsB;
int16 VoltsX1Raw, VoltsX2Raw;
//ADC0 AMPS calibration
AmpsX1Raw=READ_FLOAT_EEPROM(AmpsX1RawN);
AmpsY1Val=0;
AmpsX2Raw=READ_FLOAT_EEPROM(AmpsX2RawN);
AmpsY2Val=0.939;
//ADC1 VOLTAGE calibration
VoltsX1Raw=READ_FLOAT_EEPROM(VoltsX1RawN);
VoltsY1Val=0;
VoltsX2Raw=READ_FLOAT_EEPROM(VoltsX2RawN);
VoltsY2Val=8.4;
//send alive message to Coms Port
printf("Battery charger alive. Firmware: V2\n\r");
//main program loop
while(1) {
//Read ADC 0
set_adc_channel(0);
delay_ms(60);
adc0value = read_adc();
//Read ADC 1
set_adc_channel(1);
delay_ms(60);
adc1value = read_adc();
//perform AMPS and VOLTS calculation
AmpsM=(AmpsY2Val-AmpsY1Val)/(AmpsX2Raw-AmpsX1Raw);
AmpsB=AmpsY1Val-(AmpsM*AmpsX1Raw);
BatAmps=(AmpsM*adc0value)+AmpsB;
VoltsM=(VoltsY2Val-VoltsY1Val)/(VoltsX2Raw-VoltsX1Raw);
VoltsB=VoltsY1Val-(VoltsM*VoltsX1Raw);
BatVolts=(VoltsM*adc1value)+VoltsB;
//BUTTON PRESS SECTION
//SW1 BUTTON - incriment through modes OFF/CV/CC
if(SwitchValue=='1'){
if(mode==0){
//output OFF
LedsOff();
ChargeType(0); //charge off
printf("OFF\n\r");
currentmode=mode;
mode++; //inc mode
}
else if(mode==1){
//output CV
LedsOff();
output_high(LED2);
ChargeType(1); //CV
printf("CV\n\r");
currentmode=mode;
mode++; //inc mode
}
else if(mode==2){
//output CC
LedsOff();
output_high(LED3);
ChargeType(2); //CC
printf("CC\n\r");
currentmode=mode;
mode++; //inc mode
}
else if(mode==3){
//Charge Mode
LedsOff();
output_high(LED4);
printf("CHARGE MODE\n\r");
ChargeType(0);
currentmode=mode;
mode=0; //reset inc counter
}
SwitchValue='0'; //reset switch always on exit
}
//SW2 BUTTON - CALIBRATE & START/STOP CHARGE
else if(SwitchValue=='2'){
if(currentmode==0){
//disconnect battery pack and press cal button to lock in ADC at 0V
AmpsX1Raw=adc0value;
WRITE_FLOAT_EEPROM(AmpsX1RawN, AmpsX1Raw);
VoltsX1Raw=adc1value;
WRITE_FLOAT_EEPROM(VoltsX1RawN, VoltsX1Raw);
}
else if(currentmode==1){ //CV
//disconnect battery pack and press cal button to lock in ADC at 8.4V
VoltsX2Raw=adc1value;
WRITE_FLOAT_EEPROM(VoltsX2RawN, VoltsX2Raw);
}
else if(currentmode==2){ //CC
//connect 8R2 resistor raw at 0.836A
AmpsX2Raw=adc0value;
WRITE_FLOAT_EEPROM(AmpsX2RawN, AmpsX2Raw);
}
else if(currentmode==3){ //START or STOP Charging
if(chargeOn==0){
chargeOn=1;
printf("CHARGING STARTED\n\r");
ChargeType(2); //CC
chargeMode=1;
LedsOff();
}
else{
chargeOn=0;
printf("CHARGING STOPPED\n\r");
ChargeType(0);
}
}
SwitchValue='0'; //reset switch
}
delay_ms(300);
//CHARGE OFF DISPLAY
if(chargeOn==0){
printf("CHARGING OFF\t%3.2fV\t%3.2fA\n\r",BatVolts,BatAmps);
}
//CHARGE ON DISPLAY and ROUTINE
else if(chargeOn==1){
if(chargeMode==1){
printf("CHARGING ON CC\t%3.2fV\t%3.2fA\n\r",BatVolts,BatAmps);
output_toggle(LED2);
//change from CV (mode 1) to CC (mode 2)
if(BatVolts>=8.4){
ChargeType(1); //change to CV
printf("CHANGING TO CV\n\r");
chargeMode=2;
}
}
else if(chargeMode==2){
printf("CHARGING ON CV\t%3.2fV\t%3.3fA\n\r",BatVolts,BatAmps);
output_toggle(LED3);
if(BatAmps<=0.1){
ChargeType(0); //change to OFF
printf("CHARGING STOPPED\n\r");
currentmode=0;
}
}
}
}
}
void WRITE_FLOAT_EEPROM(long int n, float data) {
int i;
for (i = 0; i < 4; i++)
write_eeprom(i + n, *((int8*)&data + i) ) ;
}
float READ_FLOAT_EEPROM(long int n) {
int i;
float data;
for (i = 0; i < 4; i++)
*((int8*)&data + i) = read_eeprom(i + n);
return(data);
}
void LedsOff(void){
output_low(LED2);
output_low(LED3);
output_low(LED4);
}
void ChargeType(intType){
if(intType==0){ //all inactive
OUTPUT_LOW(ctrlCC);
OUTPUT_LOW(ctrlCV);
}
else if(intType==1){ //CV active
OUTPUT_LOW(ctrlCC);
OUTPUT_HIGH(ctrlCV);
}
else if(intType==2){ //CC active
OUTPUT_LOW(ctrlCV);
OUTPUT_HIGH(ctrlCC);
}
}
void initTimers(void){
//timer 2
setup_ccp2(CCP_PWM); //Configure CCP2 as a PWM
setup_timer_2(T2_DIV_BY_1, 49, 1); // 40 KHz PWM freq with 8 MHz osc
//timer1 for ADC
setup_timer_1 (T1_INTERNAL|T1_DIV_BY_1);
//timer 3 - for run time cut off
}
void initADC(void){
//intialisation
setup_adc_ports(AN0_TO_AN1|VSS_VDD); //set internal adc analog ports
setup_adc(ADC_CLOCK_INTERNAL); //set internal adc
setup_adc(ADC_CLOCK_DIV_64);
}
void PwrLed(dir,stepDly){
//0 for bright to off
if(dir==0){
for (val=255;val>0;val--) {
set_pwm2_duty(val);
delay_ms(stepDly);
}
}
//1 for off to bright
else {
for (val=0;val<255;val++) {
set_pwm2_duty(val);
delay_ms(stepDly);
}
}
}
//interupts
#int_rb
void rb_isr(void) {
//RB button input with delay debounce
//button 1
byte key1;
byte change1;
key1=input(SW1);
change1=oldKey1 ^ key1; //XOR to identify changed keys
oldKey1=key1;
//button 2
byte key2;
byte change2;
key2=input(SW2);
change2=oldKey2 ^ key2; //XOR to identify changed keys
oldKey2=key2;
//RB4, SW1
if (bit_test(change1,0)) SwitchValue='1';
//RB5, SW2
if (bit_test(change2,0)) SwitchValue='2';
delay_ms(250);
clear_interrupt(INT_RB);
}
|
_________________ I type therefore I press buttons |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19482
|
|
Posted: Mon Jun 30, 2014 1:18 am |
|
|
Several comments, some 'general', and some that will cause problems.
1) Delay in the RB ISR. This is possibly a cause of major problems. Implies that interrupts _will_ be disabled in all the delays in the main code. Means key responses will be slow, and keys could easily be missed. Fundamental "don't do" thing....
Presumably to slow 'repeat' (doesn't give debounce as written).
Some solutions:
a) Scan the keys with a tick timer, rather than INT_RB. Say at 50Hz. Then accept key if it is 'true' for two successive calls. A cleaner solution. The same timer could be used to time everything.
b) Start a hardware timer when the change is seen, and exit the interrupt. Then when the hardware timer triggers perform your 'accept' function.
2) General comment. Get into the habit of doing variable declarations at the start of code blocks, not 'mid section'. C requires declarations at the start of block. Later languages like C++, allow mid block declarations. CCS 'supposedly' allows them (doesn't complain, and they generally work), _but_ when the numbers of variables get large, has a habit (on every version I have tried), or occasionally mis-handling variables declared mid section. It is therefore far safer to stick with the C standard.
3) Why use 'byte' variables to handle single key bits?.
4) On the same comment, handle all the keys with one read. Read the whole port (to avoid TRIS being changed on the other bits, read directly from PORTB), XOR the whole byte. Mask the bits, and all the keys are done in half the code.
5) Add 'ERRORS' to your RS232 declaration. Simple 'mantra'. This _must_ be used when using the hardware UART, unless _you_ add your own error handling code. Otherwise the UART can become locked.
6) There isn't a 'double' type with the PIC18. Doesn't 'matter', it gets changed to a 'FLOAT', but a sign that you are not thinking CCS....
Especially when you then use 'float' to handle the values to EEPROM.
7)
setup_adc(ADC_CLOCK_INTERNAL); //set internal adc
setup_adc(ADC_CLOCK_DIV_64);
Only the second one actually does anything....
8)
ext_int_edge( H_TO_L );
You are not using the external interrupt.
This doesn't affect INT_RB.
9) Clock. You need to specify 'INTERNAL=8MHz'. Currently you are selecting the internal clock, but it is running at 2MHz (hence the 500KHz output). All your delays will be 4* as long as they should be.
Probably several more.... |
|
|
alyeomans
Joined: 26 Feb 2014 Posts: 24
|
|
Posted: Mon Jun 30, 2014 4:42 pm |
|
|
Thanks Ttelmah for taking the time to comment. I shall learn and stop being lazy then see how the revised code works out. _________________ I type therefore I press buttons |
|
|
alyeomans
Joined: 26 Feb 2014 Posts: 24
|
|
Posted: Mon Jun 30, 2014 10:59 pm |
|
|
After some hours of testing and tinkering and no longer able to get the top sample code to work again I assembled another PCB which still failed.
Aghhh. So I opened up Microchip IDE, erased and programmed and SUCCESS!
Not sure why debug worked and programming failed by the CCS IDE but at least I have a work around and can carry on with the project.
Alex _________________ I type therefore I press buttons |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9218 Location: Greensville,Ontario
|
|
Posted: Tue Jul 01, 2014 5:18 am |
|
|
When burning code for PICs to run in the real world, be sure MPLAB has been configured to 'release' and not 'debug'.
It's a 'classic' error to have it in 'debug'( the original default) then wonder why the PIC doesn't run right. Since I don't use debug, I've set the default to 'release'.
Also be sure 'debug=true' is deleted from your PIC program as it might override the MPLAB settings.
hth
jay |
|
|
|
|
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
|