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

code migration from 16LF73 to 16LF76

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



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

code migration from 16LF73 to 16LF76
PostPosted: Wed Nov 24, 2004 1:07 am     Reply with quote

Hi, All,
I have a piece of code to migrate from 16LF73 to 16LF76. Compiler version 3.148. The program is a software rs232 on pin_b0. (Later i try to post a sample code on the forum) The code is working fine on 16LF73, but after i modified #include <16F73.h> to #include <16F76.h> (i think that is the only change in the firmware. because these 2 chips are pin to pin compatible, and only that 16LF76 has a bigger size of program memory) The code does not work as good as run in 16LF73. Sometimes communication would break down.
Anybody familiar with these 2 chips? And know what makes this difference?

regards
Sigma
Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Wed Nov 24, 2004 2:32 am     Reply with quote

Here is the simplified version of the code:
Code:

#include    <16F76.h>
#fuses       XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT

//----- Pin assignment ---------------------------------------------------------------------
#define PBUS         PIN_B0         //PBus
#define RLED         PIN_C0         //Red LED
#define GLED         PIN_C1         //Green LED

//----- Command Table ----------------------------------------------------------------------
#define nCMD         15
#define   SYNC         0xB5
#define C1            0xBA
#define C2            0xBB
#define C3            0xBC
#define YA               0xBD
#define ACK             0xBE


char len[nCMD]={0,0,1,2,3,         
               3,1,0,1,2,      
            2,4,1,0,0,      //C1, C2, C3, YA, ACK
            };


#define NORMAL         0

#byte   INTCON = 0x0B

#bit   INTF = INTCON.1


/*******************************************************************************************
* Variable Declaration
*******************************************************************************************/
short   rxOK;
char   buf[20];
char   cmd;
char    sleep_count;
char   temp;

/*******************************************************************************************
* PBus - Using RS232 (Half duplex) functions
*******************************************************************************************/
#use delay(clock=4000000)
#use rs232(baud=9600, bits=8, xmit=PBUS, rcv=PBUS,float_high)

//------------------------------------------------------------------------------------------
short kbhit_pbus(void)
{
   return kbhit();
}

char getPbusByte()          
{
   char   r=0;
   long   i=0;
   char   j=0;

   while(i<100){
      if(kbhit_pbus()){
         r=getc();
         break;
      }
      else{
         [b]//delay_us(1);[/b]
                                                [b]i++;[/b]
      }
   }
   return r;
}


//------------------------------------------------------------------------------------------
void pbus_send(char cmd)
{
   char   c;
   char   i;
   char   temp;

   temp=cmd-0xB0;
   putc(SYNC);
   delay_us(10);
   putc(cmd);
   if (len[temp]>0) {                          
      for(i=0;i<len[temp];i++) {
         delay_us(10);
         putc(buf[i]);
      }
   }
}
//------------------------------------------------------------------------------------------
void pbus_receive() {

   char    rx,i;
   char   temp;

   [color=red]rxOK=FALSE;[/color]

   if(getPbusByte()==SYNC){
      cmd = getPbusByte();
      temp = cmd-0xB0;
      if (len[temp]!=0) {
         for (i=0; i<len[temp]; i++) {
            buf[i]=getPbusByte();
         }
          rxOk=TRUE;
      }
      else rxOK=TRUE;
   }
}



/*******************************************************************************************
* General Functions
*******************************************************************************************/
void blinkRLED(char c)
{
   char i;

   for (i=0; i<c; i++) {
      output_high(RLED);
      delay_ms(10);
      output_low(RLED);
      if (i<(c-1))delay_ms(50);
   }
}

//------------------------------------------------------------------------------------------
void blinkGLED(char c)
{
   char   i;

   for (i=0; i<c; i++) {
      output_high(GLED);
      delay_ms(10);
      output_low(GLED);
      if (i<(c-1))delay_ms(50);
   }
}


/*******************************************************************************************
* main
*******************************************************************************************/
main() {

   short   done;
   char   count_to_sleep;
   char   state;

   port_b_pullups(TRUE);                     //Port B weak pullup
   
   output_low(GLED);                        //Off the green LED
   output_low(RLED);                        //Off the red LED
   ext_int_edge(h_to_l);                     //External interrupt edge from high to low
   enable_interrupts(INT_EXT);                  //PBUS is interrupt to wakeup
   disable_interrupts(GLOBAL);                  //Don't use interrupt

   done=FALSE;
   count_to_sleep=4;
   INTF=0;
   blinkGLED(5);

   while (1) {

      port_b_pullups(TRUE);                  //Port B weak pullup
   
      if(INTF){                           //If external interrupt (PIN_B0) flagged
            

         while(sleep_count<count_to_sleep){
            [b]pbus_receive();[/b]
            if(rxOK){
               sleep_count=0;
               state=cmd;
            }

            switch (state){

            case NORMAL:
               break;

            case YA:                   
               pbus_send(C1);
               break;

            case C2:
               pbus_send(C3);
               break;

            case ACK:
               blinkGLED(5);
               state=NORMAL;
               break;
            
            }
            sleep_count++;
         }
      }      //end if(INTF)


      sleep_count=0;                  //Reset count before sleep
      count_to_sleep=4;               //Reset count_to_sleep to 4
      port_b_pullups(FALSE);            //Port B weak pullup
      output_low(RLED);               //Off red LED
      output_low(GLED);               //Off green LED
      INTF=0;                        //Clear EXT interrupt flag before sleep
      done=FALSE;
      state=NORMAL;
      input(PBUS);
      sleep();                              //MCU sleep to save power

      #asm
         NOP                                 //After wake-up, this is executed
      #endasm
   } //end while
}

/******************************************************************************************/




Thanks.
Sigma


Last edited by Sigma on Wed Nov 24, 2004 3:57 am; edited 2 times in total
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Nov 24, 2004 3:04 am     Reply with quote

Quote:
#use rs232(baud=9600, bits=8, xmit=PBUS, rcv=PBUS,errors,float_high)


rxOK is a global variable that is tested in the main() but is never initialised.

The "errors" and "float_high" are mutually exclusive. errors works only with the hardware uart and float high works only with the software uart.

Have you simplified the code too much? In getPBusByte variable i never changes so the delay_us() is never executed.

You have used delays in the switch statements. If the sw uart is used you may miss characters depending on how the application communicating to the PIC behaves. Similarly if the hw uart is used you may get an additional two characters before an overrun occurs.

I can see two ways of significantly impriving the code. One method is to select the HW UART and use interrupt driven receive logic. This will prevent characters being lost during delay_xx()

Alternatively move the LED flashing to a timer interrupt handler. Setup a periodic interrupt (say every 5ms) and use counters to control the LEDs. For example...

Code:

// ..inside the timer interrupt handler
    if (Redcount)
    {
         Redcount--;
         output_high(RLED);
     }
     else
         output_low(RLED);

    if (Greencount)
    {
         Greencount--;
         output_high(GLED);
     }
     else
          output_low(GLED);
     //.........


To have the RED LED turn on for 50ms then in the mainline set Redcount = 10
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Wed Nov 24, 2004 3:54 am     Reply with quote

Thanks, Andrew. And i am really sorry i simplified the code too much. I already modified the code. Thanks.
Because i call pbus_receive(); in the main function, rxOK will be re-init again. 'i' is also increased when kbhit() not true until certain count exceeds.
I understand external interrupt can do the job, but using this polling i also achieved 0 error rate using 16LF73. But when the code exported to 76, it malfunctions. Their hardware properties should be quite the same, why there is such a difference? What do you think?
Sigma
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Nov 24, 2004 4:30 am     Reply with quote

Is the hardware identical - that is the only thing that has changed is the PIC? What is the float_high used for?
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
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