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 support@ccsinfo.com

Rusty programmer needs reality check...

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



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

Rusty programmer needs reality check...
PostPosted: Mon Aug 07, 2006 9:51 am     Reply with quote

Hi, I haven't done any programming for about a year and have just had to get back into the swing of it. It has taken 3 weeks just to start feeling like I know my way around again!

I now want to write a menu for a 40x2 LCD, which I have acheived before with some ugly code (state-machine based). I started looking for more elegant ways of doing it and came across Mark's example of using function pointers.
I couldn't understand what was being done with the pointers, so I got out K&R's book and looked up "pointers to functions" (5.11) but just can't get my head around the concept at all! I know this is the part of C that most people find difficult, so I have gone back to basics and started at the beginning of the 'pointers' section!

As a practise, I have re-written one of my serial RX buffers to use pointer arithmetic, instead of array subscripting. Can someone please check the following code snips for me? I believe the two are identical, at least according to K&R.

Regards,
Neil.

Code:
// Version using array subscripts
#byte RX_reg = 0x01A
byte RX_Buff[8];  // Using a binary number for efficiency
int Buff_index=0;

#int_RDA
Data_RX_ISR(){
     RX_Buff[Buff_index++] = RX_reg;
     Buff_index &=7;  // Roll around 0-7...0 (8 Bytes long)
     }

Code:
// Version using pointer arithmetic
#byte RX_reg = 0x01A
byte RX_Buff[8];  // Using a binary number for efficiency
int *Buff_ptr;  // Create a pointer to int (or should it be byte?)
Buff_ptr = RX_Buff;  // Left out the '&' because RX_Buff is an array! Buff_ptr points to the 1st element of RX_Buff.

#int_RDA
Data_RX_ISR(){
     *Buff_ptr = RX_reg;  // RX_reg is stuffed into location the pointer currently points to.
     (Buff_ptr++) &=7;  // Roll around 0-7...0 (8 Bytes long)
     }


Am I 'overloading' on that last line?
Ttelmah
Guest







PostPosted: Mon Aug 07, 2006 10:13 am     Reply with quote

You cannot have the line:

Buff_ptr = RX_Buff; // Left out the '&' because RX_Buff is an array! Buff_ptr points to the 1st element of RX_Buff.

Outside of the program flow.

Do it as an initialisation, with:

byte RX_Buff[8]; // Using a binary number for efficiency
int *Buff_ptr=RxBuff; // Create a pointer to int (or should it be byte?)

Int is fine. Bytes, and integers are identical size in CCS C.

Best Wishes
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

PostPosted: Tue Aug 08, 2006 2:32 am     Reply with quote

Thanks, for the help.

Where you said the initialisation can't be done outside program flow, does this differ from standard C? K&R's book seems to allow the declaration of a pointer, then the assignment to a variable.
All on one line does look neater though Smile

Cheers,
Neil.
Ttelmah
Guest







PostPosted: Tue Aug 08, 2006 4:51 am     Reply with quote

It's not allowed in K&R either.
It is fine to do this:
Code:

void main(void) {
    char buff[8];
    char * buff_addr;
    buff_addr=buff;
.......


}

Since here you are declaring a _local_ variable inside a function, and the instruction is inside the program, and will get executed.
The problem is that the line:
Buff_ptr = RX_Buff; // Left out the '&' because RX_Buff is an array!

Is actually a line of _program_ code, and if put outside the program itself, will never actually be executed.

Best Wishes
neil



Joined: 08 Sep 2003
Posts: 128

View user's profile Send private message

PostPosted: Thu Aug 10, 2006 5:19 am     Reply with quote

Thanks Ttelmah,
I see that now!

I have just written another test prog, before I think about putting it into my real code. I am using Typemod to create some easily accessible variables in the internal data EEprom. The typemod is per the CCS example and works, but I am using a 2D array to store some related variables. This also works, until I come to printf it to a terminal....

Here is my complete code....
Code:
#include <16F877.h>
#device *=16
#fuses NOWDT,HS, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define AMPS 0
#define VOLTS 1
#define WATTS 2
#define EMISS 0
#define OPER 1
#define TRIP 2

void dataEE_read(int32 addr,int8 * ram,int bytes); // Prototypes
void dataEE_write(int32 addr,int8 * ram,int bytes);

typemod <dataEE_read> EEPROM;

int loop1,loop2;
long test_2[3][3],temp;

long EEPROM op_vars[3][3], test[3]={1024,1000,500};

void main() {
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   op_vars[AMPS][EMISS] = 1400;  // fill up EEPROM locations in array with
   op_vars[AMPS][OPER] = 1650;   // some meaningful test values.
   op_vars[AMPS][TRIP] = 1800;
   op_vars[VOLTS][EMISS] = 300;
   op_vars[VOLTS][OPER] = 380;
   op_vars[VOLTS][TRIP] = 400;
   op_vars[WATTS][EMISS] = 4000;
   op_vars[WATTS][OPER] = 6000;
   op_vars[WATTS][TRIP] = 7000;
   
   for(loop1=0;loop1<3;loop1++){    // Dump EEPROM values back to terminal
      for(loop2=0;loop2<3;loop2++){
         temp=op_vars[loop1][loop2];
         printf("%lu\t",temp);    // This works
      }
   }
   while(TRUE);
}



void dataEE_read(int32 addr,int8 * ram,int bytes){
   int i;
   for(i=0;i<=bytes;i++,ram++,addr++) *ram = read_eeprom(addr);
}

void dataEE_write(int32 addr,int8 * ram,int bytes){
   int i;
   for(i=0;i<=bytes;i++,ram++,addr++) write_eeprom(addr, *ram);
}

I have found that prinf won't accept a 2D array from the typemod. It will accept a 2D array in normal RAM, or it will accept a 1D array from the typemod. Is this something I am doing wrong, or is it a limitation of the typemod?
Code:
   for(loop1=0;loop1<3;loop1++){    // Dump EEPROM values back to terminal
      for(loop2=0;loop2<3;loop2++){
         printf("%lu\t",op_vars[loop1][loop2]); // This tells me the printf format is invalid and will not compile
      }
   }


Code:
   for(loop1=0;loop1<3;loop1++){    // Dump EEPROM values back to terminal
      for(loop2=0;loop2<3;loop2++){
         printf("%lu\t",test_2[loop1][loop2]); // This works (test_2 is in RAM)
      }
   }

Code:
   for(loop1=0;loop1<3;loop1++){    // Dump EEPROM values back to terminal
      for(loop2=0;loop2<3;loop2++){
         printf("%lu\t",test[loop2]); // this 1D array from EE works!
      }
   }



I can't see why myself... can you explain?
Even stranger, when I 'preview this post, the typemod line in code comes out different from what I typed in! it should read "typemod <dataEE_read> EEPROM;" Is it being seen as HTML?
... nope, still won't read correctly, the write function and address parameters are still being missed out. I really did type them in!

Thanks,
Neil.[/code]
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