having Problem in array passing to the function (Calculating CRC)

Status
Not open for further replies.

Mani_91

Newbie level 3
Joined
Feb 1, 2013
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,310
Hello...!
I got stuck in a problem if anyone here can help me..!
I am unable to pass array to the function as if i don't use this way the program becomes too big so if any of you have command over it i will be so thankful to u...! My work is on PIC18F452 and here is its mikroC code

Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
void Lcd_Chr_Cp(char);
// End LCD module connections

unsigned int CRC_L_R, CRC_H_R;    //variables to mask Received CRC
unsigned char CRC_L_S, CRC_H_S;  // variables to mask CRC to be send
unsigned char SlaveId, FunctionCode, Data_H, Data_L,  loop_Out, loop_Inner, i, Check;    //Other variables
unsigned char Print1 [] = "INVALID REQUEST";    //Display in case of Wrong CRC or Slave id mismatch or Functioncode mismatch
unsigned char Cal[6];                           // Register to store received 6 data bytes
unsigned int CRC_Rec_R,CRC_Rec,CRC_Cal,CRC_Cal_R;  //Registers for saving and reversing CRC
unsigned char Temp=100,Humidity=100,Temp_Pre=155,Humid_Pre=120;       //Variables shows Present teperature Humidity and their setpoint
unsigned int reverseBits(unsigned int num);
unsigned int Received_CRC_FETCH(unsigned char* A[2]);
unsigned int Calculator(unsigned char *C[4]);
unsigned char Tester(unsigned char* Check1,unsigned char* Check2,unsigned char* B[4]);

unsigned int reverseBits(unsigned int num) //Function work for Bitreversal
{
    unsigned int  NO_OF_BITS = sizeof(num) * 8;
    unsigned int reverse_num = 0;
    for (i = 0; i < NO_OF_BITS; i++)
    {
        if((num & (1 << i)))
           reverse_num |= 1 << ((NO_OF_BITS - 1) - i);
   }
    return reverse_num;
}

unsigned int Received_CRC_FETCH(unsigned char * A) {  // Function to interpret the CRC from Bit reversed CRC

        CRC_L_R = A[0] & 0x00FF  ;
        CRC_L_R = CRC_L_R << 8  ;
        CRC_H_R=0x00FF & A[1];
        CRC_Rec_R=CRC_L_R|CRC_H_R;
        CRC_Rec = reverseBits(CRC_REC_R);
        }
*unsigned int Calculator(unsigned char * C)    //Work to calculate CRC Using SlaveId,FunctionCode and two Data bytes
{

unsigned int CRC = 0xFFFF;
for (loop_Out=0;loop_Out<4;loop_Out++)
                                             {
 CRC = CRC ^ C[Loop_Out];
  CRC = CRC >> 1;
for (loop_Inner = 0; loop_Inner < 7; loop_Inner++)
                                      {
 if ( ((CRC & 0x0001) ^ 0x0001) ==1 ) //This condition checks Th LSB either it is 0 or 1
                         {
 CRC = CRC ^ 0xA001;
 CRC = CRC >> 1;
                         }
else
  {
  CRC = CRC >> 1;
  }                              }
}

         return CRC;                                        }         */
         

 //Function to tackle with data corruption and SlaveId + FunctionCode
unsigned char Tester(unsigned char * B)
{
if ((B[0]==0x01)&(B[1]==0x01)) {
CRC_Cal = Calculator(&B[0],&B[1],&B[2],&B[3]);
CRC_Rec = Received_CRC_FETCH(&B[4],&B[5]);  //Returns 1 to Check if Function code is 1 and
if (CRC_Cal==CRC_Rec) return 1 ;         // This FuntionCode is for setting point for Temperature
else   return 0;         }              //  and Humidity

else if ((B[0]==0x01)&(B[1]==0x00)) {
CRC_Cal = Calculator(&B[0]); //Returns 2 to Check if Function code is 2 and
CRC_Rec = Received_CRC_FETCH(&B[4],&B[5]);        //This function code is for getting data from MCU
if (CRC_Cal==CRC_Rec) return 2;              }
else return 0;
              }




void main() {


  UART1_Init(9600);              // Initialize UART module at 9600 bps
  Delay_ms(100);                 // Wait for UART module to stabilize
    Lcd_Init();
    Lcd_Cmd(_LCD_CLEAR);
while (1) {
for(i=0;i<6;i++) {      //Receives 6 Bytes SlaID,FuncCode,DataH,DataL,CRC (2BYTES) MSB<-------->LSB


if (UART1_Data_Ready())              {      // If data is received,
Cal[i] = UART1_Read();      //   read the received data,
  UART1_Write(Cal[i]);
 Lcd_Chr_Cp(Cal[i]);                 }
                  }

 Check = Tester(Cal); //TEST the error and Slaveid+function code
  if(Check==0) {        //If Error and Invalid slaveId or Funtion
 Lcd_Chr_Cp(Print1[]);
               }
  if(Check==2) {  //Sends data means current temperature and Humidity status to HMI
  CRC_Cal = Calculator(0x00,0x00,Temp_Pre,Humid_Pre);
  CRC_Cal_R = reverseBits(CRC_Cal);   //Making it ready as CRC is send in Reversed order    || MSB leaves first
  CRC_H_S = ((CRC_Cal_R & 0xFF00) >> 8 ;   //Break it into 8-bit or 8 byte  using masking
  CRC_L_S = ( CRC_Cal_R & 0x00FF );
  if (UART1_Tx_Idle())              {      // If Transmission line is clear
  UART1_Write(0x00);                      // Data packets holding Temp and Humidity and 0 in place of Slave id and FunctionCode
  UART1_Write(0x00);
  UART1_Write(Temp_Pre);
  UART1_Write(Humid_Pre);
  UART1_Write(CRC_H_S);   //Transmission of bitreversed CRC
  UART1_Write(CRC_L_S);                  }
               }
   else {                //If tester function returns 1 then take Set point
   Temp = Cal[2];
   Humidity = Cal[3];
        }
        delay_ms(500);
  }
}
 

Attachments

  • SERIAL.rar
    1.9 KB · Views: 83
Last edited by a moderator:

First point, don't use the bitwise AND (&) in place of logical AND (&&)

That refers to
Code:
if((B[0] == 0x01) & (B[1] == 0x00))
that should be
Code:
if((B[0] == 0x01) && (B[1] == 0x00))

Secondly, when you wan to pass an array to a function you just pass the address of the first character of the array

What you have in your code is this function
Code:
*unsigned int Calculator(unsigned char * C)
you don't call it like
Code:
Calculator(&B[0], &B[1], &B[2], &B[3]);
but like
Code:
Calculator(B);
//or
Calculator(&B[0]);
Both these send the address of the first character of the array to the function

It is the same with
Code:
Received_CRC_FETCH(&B[4], &B[5]);
You should send
Code:
Received_CRC_FETCH(&B[4]);
which is the address of the fifth character of the array

- - - Updated - - -

I know how to pass an array to a function. I can help you if you tell me what the function has to do.

A) who cares what the function does, he is asking how to pass an array parameter
B) you can see what it does in the provided code

- - - Updated - - -

I also noticed this
Code:
*unsigned int Calculator(unsigned char * C)

The function returns a pointer but you return an unsigned int
Code:
unsigned int CRC = 0xFFFF;
return CRC

ans you also store the result to an unsigned int
unsigned int CRC_Cal;
CRC_Cal = Calculator(&B[0], &B[1], &B[2], &B[3]);
 
Sir i want to pass first four elements of array how can i do that...?
Instead of using unsigned
int Calculator(unsigned char * C)
because i want to use B[0],B[1],B[2],B[3] somewhere and in another i want to use B[4] and B[5].

- - - Updated - - -

Dear i want to communicate an HMI and Micro-controller which is carried out through mode-bus protocol so i am working separately over MCU and work ok assumed data of current temperature and humidity. so In modebus i am calculating CRC if CRC match then there are two possibilities either set point in MCU or send data to HMI otherwise print INVALID REQ to LCD..!
 

int Calculator(unsigned char * C)
because i want to use B[0],B[1],B[2],B[3] somewhere and in another i want to use B[4] and B[5].

When you use Calculator(B); then inside the function you can access B[0],B[1],B[2],B[3]

To access B[4] and B[5] it would probably be better to pass the same address Calculator(B); and then use B[4] and B[5]
The alternative is to pass Calculator(&B[4]); and use B[0], B[1] to access B[4] and B[5].
 


Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
void Lcd_Chr_Cp(char);
// End LCD module connections


unsigned int CRC_L_R, CRC_H_R;    //variables to mask Received CRC
unsigned char CRC_L_S, CRC_H_S;  // variables to mask CRC to be send
unsigned char SlaveId, FunctionCode, Data_H, Data_L,  loop_Out, loop_Inner, i, Check;    //Other variables
unsigned char Print1 [] = "INVALID REQUEST";    //Display in case of Wrong CRC or Slave id mismatch or Functioncode mismatch
unsigned char Cal[6];                           // Register to store received 6 data bytes
unsigned int CRC_Rec_R,CRC_Rec,CRC_Cal,CRC_Cal_R;  //Registers for saving and reversing CRC
unsigned char Temp=100,Humidity=100,Temp_Pre=155,Humid_Pre=120;       //Variables shows Present teperature Humidity and their setpoint
unsigned char Tester(unsigned char,unsigned char ,unsigned char);
unsigned int reverseBits(unsigned int );
unsigned int Received_CRC_FETCH( unsigned char );
unsigned int Calculator(unsigned char );

unsigned int reverseBits(unsigned int num) //Function work for Bitreversal
{
    unsigned int  NO_OF_BITS = sizeof(num) * 8;
    unsigned int reverse_num = 0;
    for (i = 0; i < NO_OF_BITS; i++)
    {
        if((num & (1 << i)))
           reverse_num |= 1 << ((NO_OF_BITS - 1) - i);
   }
    return reverse_num;
}

unsigned int Received_CRC_FETCH(unsigned char A[]) {  // Function to interpret the CRC from Bit reversed CRC
        CRC_L_R = A[0] & 0x00FF  ;
        CRC_L_R = CRC_L_R << 8  ;
        CRC_H_R=0x00FF & A[1];
        CRC_Rec_R=CRC_L_R|CRC_H_R;
        CRC_Rec = reverseBits(CRC_REC_R);
        }
unsigned int Calculator(unsigned char C[])    //Work to calculate CRC Using SlaveId,FunctionCode and two Data bytes
{

unsigned int CRC= 0xFFFF;
for (loop_Out=0;loop_Out<4;loop_Out++)
                                             {
 CRC = CRC ^ C[loop_Out];
  CRC = CRC >> 1;
for (loop_Inner = 0; loop_Inner < 7; loop_Inner++)
                                      {
 if ( ((CRC & 0x0001) ^ 0x0001) ==1 ) //This condition checks Th LSB either it is 0 or 1
                         {
 CRC = CRC ^ 0xA001;
 CRC = CRC >> 1;
                         }
else
  {
  CRC = CRC >> 1;
  }                              }
}

         return CRC;                                        }

 //Function to tackle with data corruption and SlaveId + FunctionCode
unsigned char Tester(unsigned char B[])
{
if ((B[0]==0x01)&&(B[1]==0x01)) {
CRC_Cal = Calculator(B[0],B[1],B[2],B[3]);
CRC_Rec = Received_CRC_FETCH(B[4],B[5]);  //Returns 1 to Check if Function code is 1 and
if (CRC_Cal==CRC_Rec) return 1 ;         // This FuntionCode is for setting point for Temperature
else   return 0;         }              //  and Humidity

else if ((B[0]==0x01)&&(B[1]==0x00)) {
CRC_Cal = Calculator(B[0],B[1],B[2],B[3]); //Returns 2 to Check if Function code is 2 and
CRC_Rec = Received_CRC_FETCH(B[4],B[5]);        //This function code is for getting data from MCU
if (CRC_Cal==CRC_Rec) return 2;              }
else return 0;
              }




void main() {


  UART1_Init(9600);              // Initialize UART module at 9600 bps
  Delay_ms(100);                 // Wait for UART module to stabilize
    Lcd_Init();
    Lcd_Cmd(_LCD_CLEAR);
while (1) {
for(i=0;i<6;i++) {      //Receives 6 Bytes SlaID,FuncCode,DataH,DataL,CRC (2BYTES) MSB<-------->LSB


if (UART1_Data_Ready())              {      // If data is received,
Cal[i] = UART1_Read();      //   read the received data,
  UART1_Write(Cal[i]);
 Lcd_Chr_Cp(Cal[i]);                 }
                  }

 Check = Tester(Cal[0],Cal[1],Cal[2],Cal[3],Cal[4],Cal[5]); //TEST the error and Slaveid+function code
  if(Check==0) {        //If Error and Invalid slaveId or Funtion
 Lcd_Chr_Cp(Print1);
               }
  if(Check==2) {  //Sends data means current temperature and Humidity status to HMI
  CRC_Cal = Calculator(0x00,0x00,Temp_Pre,Humid_Pre);
  CRC_Cal_R = reverseBits(CRC_Cal);   //Making it ready as CRC is send in Reversed order    || MSB leaves first
  CRC_H_S = ((CRC_Cal_R & 0xFF00) >> 8 ;   //Break it into 8-bit or 8 byte  using masking
  CRC_L_S = ( CRC_Cal_R & 0x00FF );
  if (UART1_Tx_Idle())              {      // If Transmission line is clear
  UART1_Write(0x00);                      // Data packets holding Temp and Humidity and 0 in place of Slave id and FunctionCode
  UART1_Write(0x00);
  UART1_Write(Temp_Pre);
  UART1_Write(Humid_Pre);
  UART1_Write(CRC_H_S);   //Transmission of bitreversed CRC
  UART1_Write(CRC_L_S);                  }
               }
   else {                //If tester function returns 1 then take Set point
   Temp = Cal[2];
   Humidity = Cal[3];
        }
        delay_ms(500);
  }
}

Still not working if you have the compiler , Please solve my problem i am so tired of making changes and changes but still no outcome
:sad:
 
Last edited by a moderator:

But you are still using this style (in several function calls)
Code:
Calculator(B[0], B[1], B[2], B[3]);

I think I was clear enough that you should use
Code:
Calculator(B);

I don't think shortcuts will help you so you are better off reading a proper tutorial to understand pointers and arrays once and for all **broken link removed**
 

Thanks a lot sir finally I have done it.
i didn't make changes because it was making problems in other function calling but by molding it in desired way i have got result thanx a lot.:grin:
 

Guys check **broken link removed** three part tutorial which is well explained....i hope this will help you!
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…