hello all! *.h void Baudrate(unsigned int *ptr,unsigned char Uart_num) large; *.c void main(void) { ... *ptr = 1152; Baudrate(ptr,1); ... } In the routine ,the var Baud( Baud = *ptr; )is not 1152 but 0x00.When changing the defintion : void Baudrate(unsigned int pp,unsigned char Uart_num) large;,and be called : Baudrate(1152,1);,the routine run well. What is the wrong?
Where's your definition of ptr?
The pointer is defined in the main.c as "unsigned int *ptr;". *.c: void main(void) { ... unsigned int *ptr; ... *ptr = 1152; Baudrate(ptr,1); ... }
Please distill this down to a complete, self-contained, compilable example case. Nobody can diagnose what's going wrong from a loose collection of snippets ripped from their context like the one you've decided to show, so far. For starters, your 'ptr' currently points nowhere. That's bad. Furthermore the observed behaviour could easily happen if the source file containing your 'main' didn't actually #include the header containing the prototype for Baudrate(), or if the prototype were #ifdef'ed out of sight, or if the actual definition of Baudrate (in some other .c file?) didn't agree with the prototype declaration.
As Hans says, ptr in main() is uninitialized. It could point anywhere, including an address where there is no RAM to store a value. Odds are, a garbage pointer happens to point to zero. Perhaps the ellipsis hides the initialization. There's no real reason to pass by reference in this case. Stylistically, I'd write U16 GetBaudRate (U8 uartNumber); This will also lead to smaller and faster code, particularly compared to using the 3-byte generic pointer to pass a 2-byte int. The "large" qualifier on the function makes me wonder. If this keyword changes the default pointer type for the parameter, and the caller is using a different memory model, the parameter might be confused without an explicit cast. But I'm feeling too lazy to test this hypothesis right now.
hi, here is a small example which could help you to see what is wrong. Please note that this is for "classic" C; for Keil please read notes below.
void main(void) { // Next line allocates memory where pointer is placed in. // Depend on compiler it may take different number of bytes. // Please note that this does not hold any value, // This just reserves a couple of bytes for pointer unsigned int *ptr; // Next line initializes the pointer. ptr = 0x1111; // Now the pointer points to the memory location 0x1111. // Here we load value 0x2222 in memory at address 0x1111. *ptr = 0x2222; // Depend on compiler and memory model // this loads two or four (or?) bytes in // sequential memory locations 0x1111, 0x1112, ... }
unsigned int *ptr;
unsigned int xdata *ptr; unsigned int idata *ptr;
unsigned int xdata *ptr; xdata unsigned int *ptr;
idata unsigned int xdata *ptr;
"unsigned int xdata *ptr; xdata unsigned int *ptr;" I believe the second example is obsolete syntax supported for backward compatibility. The new way of doing things is: char xdata * data ptr; Which is a pointer located in data space pointing to a char in xdata space. I think this makes things a bit easier as you only have to remember that the qualifier to the left of the '*' specifies the location of the object being pointed to and the qualifier to the right of the '*' specifies the location of the pointer. "Finally, to confuse you completely, answer what does next line do yourself: idata unsigned int xdata *ptr;" Yes, well, quite.
hi, I just compiled next example:
#include <reg51.h> void main(void) { idata char xdata *ptr; ptr = 0x11; *ptr = 0x22; while (1); }
; ptr = 0x11; MOV R0,#0x08 MOV @R0,#0x00 INC R0 MOV @R0,#0x11 ; *ptr = 0x22; DEC R0 MOV A,@R0 MOV R6,A INC R0 MOV A,@R0 MOV DPL,A MOV DPH,R6 MOV A,#0x22 MOVX @DPTR,A
"This shows that pointer is placed inside idata memory and points to xdata memory." Sorry, I should have explained that. I didn't realise it was a question. The correct syntax would be: char xdata * idata ptr;