CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F4620 Will not run program

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
alyeomans



Joined: 26 Feb 2014
Posts: 24

View user's profile Send private message

PIC18F4620 Will not run program
PostPosted: Sun Jun 29, 2014 5:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 5:53 pm     Reply with quote

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: 19481

View user's profile Send private message

PostPosted: Sun Jun 29, 2014 10:53 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 30, 2014 12:11 am     Reply with quote

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: 19481

View user's profile Send private message

PostPosted: Mon Jun 30, 2014 1:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 30, 2014 4:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 30, 2014 10:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jul 01, 2014 5:18 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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