| Author |
Message |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
03 Dec 2003 13:36 keil variable types |
|
|
|
|
| I have an int variable that in certain parts of the program contains a number less than 255. I need to send this as a single byte to the serial port (SBUF=xx). Just before transmitting I copy the contents to a char variable and send that instead, at the other end the numbers 1,2,3 are received ok, but 4,5,6 etc are not. I cannot directly use a char variable, as in other parts of the program it need to be 16bits. Have also tried sending int variable directly. Also with AND to mask out upper byte, and with >>4 and <<4 to shift bits. None of these attempts seem to work correctly. I would be most appreciative of any advice.
|
|
| Back to top |
|
 |
C-Man
Joined: 19 Jul 2001 Posts: 1235 Helped: 73
|
03 Dec 2003 13:56 Re: C Changing variable types K*E*I*L |
|
|
|
|
What about this:
union
{
unsigned char bytevar[2];
char charvar[2];
unsigned int wordvar;
int intvar;
}variable;
If you want to use it as 16 bit variable.wordvar or variable.intvar
Or as 8 Bit varible.bytevar[0] or variable.bytevar[1] or variable.charvar[0] or variable.charvar[1]
Keil puts the lowbyte of the 16 bit variable in bytevar[1] Hi-Tech on the Pic does it the other way round ...
hope this helps
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
03 Dec 2003 14:23 |
|
|
|
|
Thanks C-Man,
To the rescue once again!.
Just a small point, if K*eil puts just the the lower byte when copied, why cannot one just do the following?.
unsigned int a;
unsigned char b;
b = a;
|
|
| Back to top |
|
 |
Flying Dutchman
Joined: 23 May 2001 Posts: 13
|
03 Dec 2003 14:31 Re: C Changing variable types K*E*I*L |
|
|
|
|
Just a small remark: shifting a byte is >>8 or <<8, not >>4 or <<4.
Maybe this explains...
FD.
|
|
| Back to top |
|
 |
Maddin
Joined: 26 Sep 2001 Posts: 165 Location: Europe
|
03 Dec 2003 15:02 Re: C Changing variable types K*E*I*L |
|
|
|
|
Hi,
this comments are non compiler specific, but may be of additional interest for you if you try to send single chars over the serial port:
- you can cast your int to unsigned char when assigning the variable to SBUF
- maybe you have an timing problem; some MCUs have fifo styled xmt buffers for transmitting chars and thus allowing to write multiple chars in sequence before they got sent out by your serial port
hope it helped,
Maddin
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
03 Dec 2003 15:28 |
|
|
|
|
Thx FD, Just a Silly typo.
Maddin, Think it may be a timing prob as received data varies. Maybe because of using SBUF direct?.
|
|
| Back to top |
|
 |
artem
Joined: 22 May 2003 Posts: 1652 Helped: 91 Location: Turan
|
03 Dec 2003 15:44 |
|
|
|
|
The interpretation of int and char , meant whether they are signed or unsiogned is compiler specific feature .
Is it the signed int you trying to send ?
If number in signed int is possitive try to cast like
(unsigned char)((unsigned int)tnum) before sending .
Another approach , but I do not know whether machine is big endian or little endian
unsigned char *pchar = (unsigned char*)(&intnumber);
then
sendByte(*pchar) - if it is little endian
or
sendByte(*(++pchar)) if it is big endian
|
|
| Back to top |
|
 |
Google AdSense

|
03 Dec 2003 15:44 Ads |
|
|
|
|
|
|
| Back to top |
|
 |
Maddin
Joined: 26 Sep 2001 Posts: 165 Location: Europe
|
03 Dec 2003 15:48 |
|
|
|
|
| GrandAlf wrote: |
Thx FD, Just a Silly typo.
Maddin, Think it may be a timing prob as received data varies. Maybe because of using SBUF direct?. |
This could be the case if you write too frequently to the serial buffer. Try to introduce some simple queuemanagement that extends your MCU's fifo or, if you have plenty of time, just check your MCU datasheet for a flag that can be polled to check when your xmt buffer is free again for writing into it.
The better way will of course be using the queue in conjunction with an xmt-interrupt service routine....
Maddin
|
|
| Back to top |
|
 |
C-Man
Joined: 19 Jul 2001 Posts: 1235 Helped: 73
|
03 Dec 2003 15:55 Re: C Changing variable types K*E*I*L |
|
|
|
|
GrandAlf if you use the hardware UART of the 8051 you might have to wait until a previous character has been sent out and the transmit buffer is empty.
Here is a snippet of the code I am using:
void serial_out(unsigned char character)
{
while(!TI)
continue;
TI=FALSE;
SBUF=character;
}
The routine waits until the TI (transmit interrupt) flag gets set which signs that the previous character has been sent completely.
hope you can use it, best regards
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
03 Dec 2003 15:55 |
|
|
|
|
Thx artem,
Both char and int are unsigned. Have tried putchar(b); , but it locks up the cpu. Still learning C, maybe I can use printf to send raw data, rather than using SBUF directly.
|
|
| Back to top |
|
 |
artem
Joined: 22 May 2003 Posts: 1652 Helped: 91 Location: Turan
|
03 Dec 2003 16:00 |
|
|
|
|
| As lasst resort try to catch the value you send to the port and sese what is the assembler output . This for sure is the last resort if nothing wrong with hardware .
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
03 Dec 2003 16:37 |
|
|
|
|
Thanks everyone,
C-Man, I used your routine, but changed FALSE to 0, as I do not have it defined. Program stays in this routine forever. This leads me to suspect that the flag is never set/unset. Must have some register settings wrong. Will have to a bit more reading I think.
|
|
| Back to top |
|
 |
C-Man
Joined: 19 Jul 2001 Posts: 1235 Helped: 73
|
03 Dec 2003 17:16 Re: C Changing variable types K*E*I*L |
|
|
|
|
GrandAlf send me your code either by PM or post it here, I will have a look at it for you ...
best regards
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
04 Dec 2003 8:46 |
|
|
|
|
Thats very kind of you C-Man,
This is the code that I use to setup the serial port, I am only transmitting (blind) BTW, and not receiving.
//FUNCTIONS
void serial_init (void) {
SCON = 0x50; // mode 1: 8-bit UART, enable receiver
TMOD = 0x20; // timer 1 mode 2: 8-Bit reload
TH1 = 0x98; // reload value 300 baud
TR1 = 1; // timer 1 run
ES = 0; // Disable serial port interrupt
EA = 0; // Disable
RI = 1;
TI = 1;
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
04 Dec 2003 8:51 |
|
|
|
|
| Sorry, I forgot to say the cpu is Atmel 89S8252.
|
|
| Back to top |
|
 |
C-Man
Joined: 19 Jul 2001 Posts: 1235 Helped: 73
|
04 Dec 2003 9:18 Re: C Changing variable types K*E*I*L |
|
|
|
|
Try this new initialization code instead of the posted code
TMOD = 0x20; // timer 1 mode 2: 8-Bit reload
TH1 = 0x98; // reload value 300 baud
SCON = 0x52; // mode 1: 8-bit UART, enable receiver TI remains set
TR1 = 1; // timer 1 run
ES = 0; // Disable serial port interrupt
EA = 0; // Disable
I know I gave you the old code but after checking my code I saw that I use an extra flag which gets the status of the TI flag in the serial interrupt routine (and of course I set this flag at power on).
At power on the TI bit is set which means you can put a new byte into SBUF but as the old initialisation code erases TI (it is located in SCON) it will never get set again (it would get set if you put a byte into SBUF without waiting for TI to get H).
I think you can only clear (and not set) TI and RI by software as it is set by hardware.
Hope things will be working with this code ...
best regards
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
04 Dec 2003 10:10 |
|
|
|
|
C-Man.
Still pretty much the same with this configuration. I can send 1,2,3 and receive them correctly, but 4 upwards is not received or wrong. I am pretty sure that the receiving end is ok, difficult to check what is being sent out as they are non printable characters. Also difficult to do a simulation without a major change to s/w, as I have probs with peripherals and eeprom.
Stange thing though, if I try to use printf or putchar insted of SBUF, the prog does not return from the function, thus effectivly locking the mpu. I would sumise that these funcions are waiting for a flag to be changed, and this it is not happening.
I think I will have to re-write a small section of code that I can simulate, and then go on from there.
I really appreciate all your advice, thank you so much.
|
|
| Back to top |
|
 |
GrandAlf
Joined: 09 Mar 2002 Posts: 409 Helped: 23
|
04 Dec 2003 11:02 |
|
|
|
|
| I think I have found the problem, seems to be with rtos. Single task is ok. At least I have something to work on now. Thanks for all your advice chaps.
|
|
| Back to top |
|
 |