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

Problem when change from PIC18F4680 to PIC18F46k22

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



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

Problem when change from PIC18F4680 to PIC18F46k22
PostPosted: Mon May 27, 2013 3:03 am     Reply with quote

Hi all.
In my project, PIC18F4680 is died so that i must change used to PIC18F46K22, can not buy a new PIC18F4680
My code run normal with PIC18F4680, but in PIC18F46K22 had a problems with external RB0 and PortB on change interrupts, my program always jump to int_rb interrupts function and with int_ext, it is not work.

1. I configured fuses for PIC18F46K22 as below:
Code:

#include <18F46K22.h>
#fuses HSH,PUT,NOPROTECT,NOLVP,NOWDT,NOBROWNOUT,NOPLLEN,NOPBADEN
//setup_oscillator(OSC_32MHZ);
#device *=16 WRITE_EEPROM = NOINT // TAM DUNG GHI EPPROM KHI CO NGAT, NGAT XONG GHI TIEP         //HIGH_INTS=TRUE
#use delay(clock=20000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, errors) // HARD UART
//!#use i2c(master, sda=DS1307_SDA, scl=DS1307_SCL)
//#priority ext,rb,rda
#use fast_io (A)
#use fast_io (D)
#use fast_io (E)


2. config interrupts:
Code:

   setup_oscillator(OSC_PLL_OFF);
   port_b_pullups (TRUE);
   delay_us (100);      // Allow time for weak pullups to rise up
   temp=input_b();      // Read PortB to clear change condition
   clear_interrupt (int_rb);
   
   //------------------------------------------------
   // INIT INTERRUPTS EDGE --- int EXT 0
   //------------------------------------------------
   ext_int_edge (0, H_TO_L) ;
   clear_interrupt (int_ext);
   enable_interrupts (int_ext);
   

   enable_interrupts (int_rb);
   enable_interrupts (int_rda);
   enable_interrupts (global);


3. Interrupts service function
Code:

#int_ext

void ngat_rb0()

   output_low(PIN_E1);
   //delay_ms(500);
   while(input(PIN_B0)==0)
   {
      //delay_ms(100);
   }
   check_rcv_send=0;
   check_ack_change_c=0;
   status_counter_change = 1;
   //delay_ms (100);
   output_toggle (PIN_e1);   
   count_send++;
   count_change = 1;
   check_ack_val=0;
   //enable_interrupts (int_ext);
}


#int_rb // detect ON/OFF BIEN TAN

void ngat_rb()
{
   output_low(PIN_E0);
   if(input(PIN_B5)==0)
   {
      output_low(PIN_E0);
   }
   else
   {
      output_high(PIN_E0);
   }
   check_rcv_send=0;
   check_ack_change_s=0;
   status_onoff_change = 1;
   check_ack_sa_so=0;

   clear_interrupt(int_rb); 
   enable_interrupts (int_rb);
}



Please show me way to fix it.
Thanks all.
_________________
Begin Begin Begin !!!
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon May 27, 2013 5:16 am     Reply with quote

first error...

HSH is NOT a valid fuse option for the 46k22.

second error..

You've enabled an ISR(serial #1) without a handler.

program will crash..

third..
Never enable an interrupt from inside itself.

program will crash.



suggestion...


create the '1Hz flashing LED program' and verify it does run correctly before going any further, there are other errors in your code, but as shown we cannot 'cut and paste' it to test.

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 27, 2013 11:34 am     Reply with quote

Quote:
my program always jump to int_rb interrupts function

If you get instant #int_rb interrupt when the program starts, there is
probably something wrong in this area:
Quote:

port_b_pullups (TRUE);
delay_us (100); // Allow time for weak pullups to rise up
temp=input_b(); // Read PortB to clear change condition

I notice you increased the delay from 10us to 100us. That didn't help,
and it should not be necessary.

Next thing, you are using a new PIC. What if the pull-ups operate
differently in the new PIC ? You should suspect this. Look at the
I/O Ports section of the 18F46K22 data sheet. It says:
Quote:
10.3.1 WEAK PULL-UPS
Each of the PORTB pins has an individually controlled
weak internal pull-up. When set, each bit of the WPUB
register enables the corresponding pin pull-up.

That means you don't use TRUE and FALSE for the port_b_pullups() function.
Read the CCS manual:
Quote:

port_x_pullups ( )

Parameters: value is TRUE or FALSE on most parts, some parts that allow pullups to be specified on individual pins permit an 8 bit int here, one bit for each port pin.


This means you can turn on all PortB pullups with:
Code:
port_b_pullups(0xFF);

or, using binary notation:
Code:
port_b_pullups(0b11111111);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 27, 2013 11:44 am     Reply with quote

temtronic wrote:
first error...

HSH is NOT a valid fuse option for the 46k22.

It is valid in vs. 4.141 and other recent versions. See the fuses in the
header file below:
Quote:
//////// Standard Header file for the PIC18F46K22 device ////////////////
#device PIC18F46K22
#nolist
//////// Program memory: 32768x16 Data RAM: 3896 Stack: 31
//////// I/O: 36 Analog Pins: 28
//////// Data EEPROM: 1024
//////// C Scratch area: 00 ID Location: 200000
//////// Fuses: LP,XT,HSH,HSM,ECH,ECH_IO,RC,RC_IO,INTRC_IO,INTRC,ECM,ECM_IO




temtronic wrote:

third..
Never enable an interrupt from inside itself.
program will crash.

You are referring to this line from his code:
Quote:
void ngat_rb()
{
.
.
.
clear_interrupt(int_rb);
enable_interrupts (int_rb);
}

That's OK. The int_rb interrupts are already enabled when the code
is inside the isr. They are not disabled inside the isr. It's the GLOBAL
interrupts that are disabled inside the isr, and should not be enabled.
The line in bold is OK, but it's not necessary. Also, the compiler adds
hidden code to clear the interrupt flag, so the other line is also not
necessary.
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Tue May 28, 2013 3:26 am     Reply with quote

Thanks u,PCM
I repaired my program follow your instructions, but the result no change
Quote:
port_b_pullups(0xFF);

I'm afraid problems with Portb on change interrupts
In my project, I used pin RB5 to check interrupts on change, but pin RB5 is CCP3 input, and i setting off CCP in main program, but it still no change
Code:

void main(void)
{
   //setup_oscillator(OSC_PLL_OFF);
   setup_ccp3 (CCP_OFF);
......
}

Please show me to fix it, thanks u .
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Tue May 28, 2013 4:04 am     Reply with quote

Some comments inline:
Code:

#include <18F46K22.h>
#fuses HSH,PUT,NOPROTECT,NOLVP,NOWDT,NOBROWNOUT,NOPLLEN,NOPBADEN
#device WRITE_EEPROM = NOINT
//*=16, does nothing on a PIC18.
#use delay(clock=20000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, errors) // HARD UART
#use fast_io (A)
#use fast_io (D)
#use fast_io (E)

Where do you set the tris on these ports?. You have told the compiler not to control TRIS, but you are not taking over doing this.....
Code:

   setup_oscillator(OSC_PLL_OFF);
   port_b_pullups (0xFF);
   delay_us (100);      // Allow time for weak pullups to rise up
   temp=input_b();      // Read PortB to clear change condition
   clear_interrupt (int_rb); 
   //------------------------------------------------
   // INIT INTERRUPTS EDGE --- int EXT 0
   //------------------------------------------------
   ext_int_edge (0, H_TO_L) ;
   clear_interrupt (int_ext);
   enable_interrupts (int_ext);
   
   enable_interrupts (int_rb);
   enable_interrupts (int_rda);
   enable_interrupts (global);

Where is INT_RDA?. You must never enable an interrupt without a handler. This will hang the chip. Your code enables three interrupts but you show only two handlers...
Code:

#int_ext
void ngat_rb0(void)
{
   output_low(PIN_E1);
   //delay_ms(500);
//Good thing this is disabled, this will result in interrupts being disabled
//in _every_ bit of code that uses delays. Do not use delays in the ISR
   while(input(PIN_B0)==0)
   {
      //delay_ms(100);
   }
//This will stop anything else working, while RB0==0.....
//Reprogram the edge, and get out of the interrupt
   check_rcv_send=0;
   check_ack_change_c=0;
   status_counter_change = 1;
   //delay_ms (100);
   output_toggle (PIN_e1);   
   count_send++;
   count_change = 1;
   check_ack_val=0;
}

#int_rb // detect ON/OFF BIEN TAN
void ngat_rb(void)
{
   output_low(PIN_E0);
   if(input(PIN_B5)==0)
   {
      output_low(PIN_E0);
   }
   else
   {
      output_high(PIN_E0);
   }
   check_rcv_send=0;
   check_ack_change_s=0;
   status_onoff_change = 1;
   check_ack_sa_so=0;
}

I'd suspect your main problem is INT_RDA.

Best Wishes
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Tue May 28, 2013 5:56 am     Reply with quote

Thanks u, Ttelmah
Because my program is too long, i only post shorter code.
I configured tris in main program
Code:

void main(void)
{
   delay_ms (100);
   set_tris_a (0);      // control A0 - A3: cs1, rst, cs2, cs3
   set_tris_b (0xff);   //  keypad
   set_tris_c (0x80);   //
   set_tris_d (0);
   set_tris_e (0);      // control
....
}

and i have a RDA handler in my program, and it also too long, i shortened it.
Code:

#int_rda //HIGH

void ngat_rs232()
{
   c = getc ();

   switch (c)
   {
      case '&':
      {
         count_hi_rcv = getc ();
         count_lo_rcv = getc ();
         count_bbc_rcv = getc ();

         if (check_one_rcv == 0)
         {
            if ( (count_hi_rcv ^ count_lo_rcv) == count_bbc_rcv)
            {
               output_toggle(PIN_E2);
               count_rcv = make16 (count_hi_rcv, count_lo_rcv);
               count_send = count_send + count_rcv;
               check_bbc_rcv = 1;
               check_one_rcv = 1;
            }
         }
      }

      break;

      //---------------------------------------------------------------------------------
      case '$':
      {
         index = 0;
      }

      break;
     
      //---------------------------------------------------------------------------------
      case '#':
      {
         //******************************************************************************
         //       KIEM TRA KET NOI VOI PC ----- > $1LINK#
         //******************************************************************************     
         if ( (str_rs232[0] == '1')&& (str_rs232[1] == 'L')&& (str_rs232[2] == 'I')&& (str_rs232[3] == 'N')&& (str_rs232[4] == 'K') )
         {
            check_link_pc = 1;
         }
         //******************************************************************************
         //       KIEM TRA KET NOI VOI PC ----- > $1LINK#
         //******************************************************************************     
         else if ( (str_rs232[0] == '1')&& (str_rs232[1] == 'R')&& (str_rs232[2] == 'E')&& (str_rs232[3] == 'S'))
         {
            check_restore_pc = 1;
         }
         //******************************************************************************
         //       KIEM TRA CAP NHAT GIA TRI COUNTER ----- > $1SEND#
         //******************************************************************************
         
         else if ( (str_rs232[0] == '1')&& (str_rs232[1] == 'S')&& (str_rs232[2] == 'E')&& (str_rs232[3] == 'N')&& (str_rs232[4] == 'D') )
         {
            check_send_count_data = 1;
            check_rcv_send=1;
         }
         
         //******************************************************************************
         //       KIEM TRA RESET TU PC
         //******************************************************************************
         
         else if ((str_rs232[0] == '1')&& (str_rs232[1] == 'R')&& (str_rs232[2] == 'S') && (str_rs232[3] == 'T'))
         {
            check_reset_pc = 1;
         }

         //******************************************************************************
         //       KIEM TRA PHAN HOI ACK TU PC
         //******************************************************************************
         
         else if ( (str_rs232[0] == '1')&& (str_rs232[1] == 'A')&& (str_rs232[2] == 'C') && (str_rs232[3] == 'K'))
         {
            if ((str_rs232[4] == 'V')&& (str_rs232[5] == 'A')&& (str_rs232[6] == 'L') )
            {
               check_ack_val = 1; //NHAN CHUOI $1ACKVAL# < - > PC DA NHAN DUNG GIA TRI SA
               check_ack_counter=1;
               status_counter_change=0;
            }

            //--------------------------------------------------------------------------------
            else if ((str_rs232[4] == 'S')&& (str_rs232[5] == 'A'))
            {
               check_ack_sa_so = 1; //NHAN CHUOI $1ACKSA# < - > PC DA NHAN DUNG GIA TRI SA
               status_onoff_change=0;
            }

            //--------------------------------------------------------------------------------
            else if ((str_rs232[4] == 'S')&& (str_rs232[5] == 'O'))
            {
               check_ack_sa_so = 1; //NHAN CHUOI $1ACKSO# < - > PC DA NHAN DUNG GIA TRI SO
               status_onoff_change=0;
            }

            //--------------------------------------------------------------------------------
            else if ((str_rs232[4] == 'C')&& (str_rs232[5] == 'A'))
            {
               check_ack_change = 1; //NHAN CHUOI $1ACKCA# < - > PC DA NHAN DUNG GIA TRI SO
               
            }
           
            else if((str_rs232[4] == 'N')&& (str_rs232[5] == 'G'))
            {
               check_ack_ng=1;
            }
         }
      }     
      break;

      //-----------------------------------------------------------------------------
      default:
      {
         str_rs232[index] = c;
         index++;
      }

      break;

      //-----------------------------------------------------------------------------
   } // end of switch
}   

And i don't think have problems with RDA interrupts handler, but problems is continued Smile
Thanks u.
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Tue May 28, 2013 7:29 am     Reply with quote

I think you have problems with int_rda.

The RDA interrupt, means that _one_ character (just one), is ready to be read. Your handler will hang the chip. You need something like a state machine to handle the data. This _is_ a major problem.

There is also another problem. You have the comment '//HIGH' against this handler, suggesting you are perhaps using hardware interrupt priorities. Read the data sheet. Realise that if you use INT_EXT, it _always_ uses high priority, if interrupt priorities are used.

Also, nowhere do I see you turning off the analog functions. These override the I/O functions on many of the pins you are using.

Seriously, the first place to begin with debugging, is to cut the code down to the minimum showing the problem, and post _compilable_ code. Otherwise we haven't got a hope of knowing what is really going on.
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Jun 02, 2013 11:12 pm     Reply with quote

Ttelmah wrote:
I think you have problems with int_rda.

The RDA interrupt, means that _one_ character (just one), is ready to be read. Your handler will hang the chip. You need something like a state machine to handle the data. This _is_ a major problem.

There is also another problem. You have the comment '//HIGH' against this handler, suggesting you are perhaps using hardware interrupt priorities. Read the data sheet. Realise that if you use INT_EXT, it _always_ uses high priority, if interrupt priorities are used.

Also, nowhere do I see you turning off the analog functions. These override the I/O functions on many of the pins you are using.

Seriously, the first place to begin with debugging, is to cut the code down to the minimum showing the problem, and post _compilable_ code. Otherwise we haven't got a hope of knowing what is really going on.

Thanks u,Ttelmah.
I think RDA interrupt handler is normal, because all source code run true in Pic18F4680, but when i change to Pic18F46K22, the problem is appear in PortB interrupts Onchange.
In Pic18F4680, i fix the port b interrupt on change ( autorun when program start) with help of PCM Programmer:

Code:

port_b_pullups (0xff);
   delay_us (10);         // Allow time for weak pullups to rise up
   temp=input_b();      // Read PortB to clear change condition   
   clear_interrupt (int_rb);                           


The code run exactly in PIC18F4680
But when i change to use PIC18F46K22, i fixed PortB pull up also with help of PCM Programmer:
Code:
port_b_pullups (0xff);

But the errors is continued.
Pls show me way to fix it.
Thanks and Regards
_________________
Begin Begin Begin !!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Mon Jun 03, 2013 12:22 am     Reply with quote

Unfortunately, this is a little like the person who found they could slow their car, by pulling the choke. Just because it apparently works, doesn't make it even remotely good programming. You are _mishandling_ the interrupt, and basically making it pointless using it....
Key mantra on all interrupts, is that the code should _just_ handle the hardware event signalled by the interrupt. As little as possible more.

Step back and do this:

"the first place to begin with debugging, is to cut the code down to the minimum showing the problem, and post _compilable_ code. Otherwise we haven't got a hope of knowing what is really going on".

This is the core of all debugging.
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