We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All, I'm more of a Assembly guy than C. I came across this forum when I am seeking for some quick guide of sharing data registers / variables of different files of C and .a51 in a simple program. Calling each other from C to get the function written in .a51 or vice-versa is completed. Went through c2asm2c.zip, tested and find that it worked perfectly. However, I encounter some trouble when I need to pass on some variables that need to be manipulated from .a51 to .c My case:- Main code is in .a51. Requires to call a function that adds 20 slightly different 8bit data bytes and then take its average (i.e. by division). Writing the function above in .a51 is a pain due to unavailable 16bit-addition in 8051 done under Keil uV2. My solution thought:- is to write the addition function in C so addition can be done much more easily. Problem:- how do I pass the variables/registers defined in .a51 to the C function to be called from .a51 environment? The C function failed to recognize the similar declared register under .a51 before. Do I need to declare them under a new name OR use the similar name of data registers OR can use some global declaration of data registers. But how? Appreciate some really cool advice if available. Cheers, James
continuing... C source file:
#include <test_h.H> // include SFR and other definitions/macros // tell the linker known symbol names: // data DECLARED here (no memory space assigned here) // external data variables extern unsigned char data Char_dataA; extern unsigned char data Char_dataB; extern unsigned char data DataGroup1; extern unsigned char data DataGroup2; extern unsigned int data Int_data; // not necessary: extern unsigned char data Int_dataH; // MSB component of Int_data if you need it extern unsigned char data Int_dataL; // LSB (Big Endian manner) extern unsigned long data Long_data; // not necessary: extern unsigned char data Long_data1; // MSB... extern unsigned char data Long_data2; // t components of Long_data extern unsigned char data Long_data3; // o if you need it extern unsigned char data Long_data4; // ...LSB extern unsigned char data Char_array[A_LENGTH]; // defined in asm file // external bit variables extern bit Flag0; extern bit Flag1; extern bit abc; extern bit Flag7; extern bit Bit_var1; extern bit Bit_var2; // external bdata variables extern unsigned char bdata Flags1; extern unsigned char bdata Flags2; //Note: // sbit xyz = Flags1^3; // names for particular bits of EXTERNAL // bdata variables CAN'T be defined this way, unsigned char bdata Flags3; // but if the variable is DEFINED here, sbit xyz = Flags3^5; // then names for particular bits of such sbit MNO = Flags3^7; // bdata variables CAN be defined this way // external idata variables extern unsigned char idata Char_idata; // external xdata variables extern unsigned char xdata Char_xdata; // external functions extern void my_function_A51(void); extern void my_regpar_function_A51(unsigned char x); // global data DEFINED here (memory space assigned here) unsigned char data Divider; // data type either explicitly (data) unsigned int abcd; // or given by memory model unsigned char xdata Result; // Result explicitly in xdata memory bit bit_var1_C; // bit variables defined in a C file bit bit_var2_C; unsigned char data data_var1_C; // data variables defined in a C file unsigned char data data_var2_C; unsigned char idata idata_var_C; // idata variables defined in a C file unsigned char xdata xdata_var_C; // xdata variables defined in a C file void func_C(void) { // empty here } #pragma REGPARMS // it is default void func_regpar_C(unsigned int y) // function with parameters { DPTR = y; // use parameter(s) } void main(void) // an example, mostly MEANINGLESS !! { unsigned char a, i; // local data (data type given by memory model used) if (Flag0) { a = Int_dataL + Long_data2; } else { a = Char_array[3]; } Int_data = 0; for (i = 0; i < A_LENGTH; i++) { Int_data += Char_array[i]; } Int_data /= A_LENGTH; // ...sum of 'chars' divided by their number gives 'char' again (=average) Result = Int_data; // casting, better explicitly: (unsigned char)Int_data my_function_A51(); // call external function without parameters my_regpar_function_A51(Char_idata); // call external function with parameter(s) while(1); // stop here forever }
// put SFR and other definitions here (examples here) sfr ACC = 0xE0; // accumulator SFR address sfr PSW = 0xD0; // Program Status Register SFR address sbit ACC3 = ACC^3; // bit ACC.0 in assembler sbit CY = PSW^7; // bit Carry Flag - 7th bit of bitaddressable register PSW // bitaddressable SFRs have address' lower nibble 0 or 8 sfr TL2 = 0xCC; // if LSByte address of a 16-bit SFR register (here Timer2) sfr TH2 = 0xCD; // is by 1 lower than its MSByte address, sfr16 TIMER2 = 0xCC; // =TL2 // then sfr16 can be defined for such an SFR register // and compiler will arrange everything else sfr DPL = 0x82; sfr DPH = 0x83; sfr16 DPTR = 0x82; // miscellaneous constants or preprocessor macro definitions: #define A_LENGTH 5 // size of the array "Char_array"
I'm sorry, the line
sbit ACC3 = ACC^3; // bit ACC.0 in assembler
sbit ACC3 = ACC^3; // bit ACC.3 in assembler
Hi Eric, Thanks for very detailed 'cookbook'. Appreciate it so much. Will check it out ASAP and let you know the good results I'd reckon. cheerio, James