Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to send an array of data from PC to 89C51 via RS232?

Status
Not open for further replies.

elchula

Member level 3
Joined
Mar 16, 2005
Messages
66
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
1,846
Help me. I want to send an array of data to 89C51 from PC via RS232, then export these data to P1...i'm a beginner, so I don't know how to do it!!!!!!.
 

Wheather you send an array of numeric data or strings .. is always the same .
At this level you are dealing with a serial comunication channel that only sends bytes ..So you need to implement a PROTOCOL ,, it can be very simple like a header that describes at first what you are going to send and how many bytes you will be awaiting . If there is a problem and the data doesn't conforms with the header ..then at your turn you can send another message saying send again .or transmision ok ..is UP TO YOU how to organize it ..
a HEADER can be one byte or more depending on how many bytes you spect to send .in that header you could specify also how the data can be recovered
as chars ,ints ,longs, etc .
the code in a header is up to you ,for ex 77 = char, 33 can be etc.
 

Protocol, oh, i don't know how to create it, can you help me?.
 

elchula said:
Protocol, oh, i don't know how to create it, can you help me?.
for topics on protocols refer "data communications and networking" - foruzan

u can do that without using a protocol, just type the data in the "hyperterminal"software that comes along with ur windows os. receive them as ascii in the serial port and then convert in to hex. this is given in "the 8051 and embedded system "mazidi.
good luck
 

You can explain clearly for me, I didn't yet do this.

You have link for "the 8051 and embedded system "? Send it to me. Thanx
 

Hi elchula,
please visite this lionk, I guess it good thing
**broken link removed**


Siswanto
 

Hic, i don't find the information I want to know!
 

Hi there are many way to orgenize it ..
for example you could use any charactor to define as a start charactor stream and then program to count amount of byte to receive and put each data to array or port.. You could also use serial interrupt for better receiving data stream
 

Help me. I want to send an array of data to 89C51 from PC via RS232, then export these data to P1

what for export data to P1, if you only it without processing data, you can simple receive serial data without protocol, so only receive serial data and export it direct to P1.

like this simple code:

MOV SCON, #52h ; #11011100b ;SCON: mode 1, 8-bit UART, enable rcvr */
MOV TMOD, #20h ; TMOD: timer 1, mode 2, 8-bit reload */
ORL PCON, #080h
MOV TH1, #0FFh ; Baud Rate 19200 (#0FDh) Baud Rate 57600 (#0FFh)
MOV TL1, #0FFh ;

SETB TR1 ;TR1: timer 1 run */
CLR RI ; ready to receive data

RX: JNB RI, $
MOV A, SBUF ; receive data
CLR RI ; ready to receive
MOV P1, A ; export to P1
JMP RX ; receive again
 

Hic, I write this program by C language, and my code is followed :

---------------------------------------
#include <AT89S53.h>
unsigned char chr,h;
unsigned char s[8];
void delay(unsigned char k);
void delay1();
char getchr(void);
void sendchr(char chr);
unsigned int array(unsigned char chr);

void main()
{
SCON = 0x50;
TMOD = 0x20;
TH1 = 0xFD; //9600 Baud
TR1 = 1;
TI = 1;
P1 = 0xff;
while(1)
{
for(h = 15; h >= 0; h--)
{
chr = getchr();
array(chr); // receive an array from COM port
P0 = P2 = chr; // send to LEDs.
P1 = h; // shift .
delay1();
}
}
}

char getchr(void)
{
char chr;
{
chr = SBUF;
RI = 0;
return(chr);
}while (RI != 1);
}

void sendchr(char chr)
{
if (chr == '\r') chr = '\n';
{
TI = 0;
SBUF = chr;
return;
}while (TI != 1);
}

void delay1()
{
unsigned int i;
for(i = 0; i < 40000; i ++);
}

void delay(unsigned int k)
{
unsigned int i;
for (i = 0; i <= k; i ++);
}

unsigned int array(unsigned char chr)
{
unsigned char s[8];
unsigned char i;
i = 0;
while(buffull != 0)
{
for (i = 0; chr != 0xa; i ++)
{
chr = getchr();
s = chr;
}
s[i - 1] = 0;
return;
}
}


But, when I send a character, it do well, and then, I want to send a 8 characters - array, it's wrong. Can you explain, and find my wrong. Thanx!
 

What a terible mess ! That it's his homework ?

while(TI != 1); and while(RI != 1); placed after return statement.
unknown identifier buffull. probably buffer full for receiving.
missing return expression in function array (it was not declared as returning void, but unsigned int)
an unsigned char s[8] declared inside function array according with scope function rules it's hidden from outside world.
He is expecting to use array s as global variable (declared at the top program) to send 8 characters received from PC to port P0 and P2.
He ends up by no using at all the s array and he ask where 8 characters sent has gone and why don't appear on P0 when P0 = P2 = chr;.
A sendchr function never used.
P1 = h; //shift what kind of shift is sending numbers from 15 downto 0 on low nibble of P1 ?
i = 0; just before while(buffull != 0) why since is initialized when starting loop for (it's not a big mistake, but how can you tell him about these small harmless things)

He tried to compile the program before posting here ?
Because he could easily figure out what's not working.

Sometimes I can't help myself and wonder how can really help a newbie.
Doing his job ?

Look at the code posted by suromenggolo.
He tried kindly to help elchula.
He didn't know that elchula hates the assembler but loves more C from which didn't understand too many things until now.
 

may be problem at delay procedure. If you send 8 character, it's receive first character quickly to array and P0, P2.
after enter delay, receiver second character still wait delay before save to array, so 3rd, 4th .... may be stiill execute delay procedure

I think you must use serial interrupt for this is, or on delay procedure place RI check code, if a data have receive.
 

suromenggolo said:
may be problem at delay procedure. If you send 8 character, it's receive first character quickly to array and P0, P2.
after enter delay, receiver second character still wait delay before save to array, so 3rd, 4th .... may be stiill execute delay procedure

I think you must use serial interrupt for this is, or on delay procedure place RI check code, if a data have receive.

Hi suromenggolo,

He laready placed RI check code. But in wrong placed, after the RET. The statement in C "while (RI != 1);" it's exactly like yours write in assembler "RX: JNB RI, $". But instead these sequence:

- RX: JNB RI, $
- RET

he get as compiler results (if the C compiler will compile so, because it don't)

- RET
- RX: JNB RI, $

just because he placed the statement
while (RI != 1);
after
return(chr);

With other words, he leave the call function before the flag RI is set.
You got the point ?

Second, paralel port P0 and P2 receive the value of variable chr not ones from "s" array (the 8 characters he wants to send to P0) even if his intention was calling function "array" with argument "chr".
That's a terible mess in his head.
He must learn how to use the pointers to array and how a function is called by reference or by value, how the function returns values.
I'll not teach him how to do it, because he claims that is skilled. Read his post on forum by just clicking on word post bellow his nick name.
Maybe I wouldn't be a good teacher, that's why I advice him to read books or listen more carefully his teacher's advices in the class.

It's not only a matter of delays.

I like more assembly, that's why I said that the best practice is viewing the LST file generated by compiler to see how every statement is converted in assembler.
So, you got a much closer feeling about what's happening behind the curtain.
 

elchula said:
Help me. I want to send an array of data to 89C51 from PC via RS232, then export these data to P1...i'm a beginner, so I don't know how to do it!!!!!!.

Okey,
I will explain about the serial data trimsmisson pinciples.

If you connect two serial devices, in this project between RS232-8051 and RS232-PC
I assume in PC by using Hyperterminal software as Transmit and Receive data.

Two point connection in RS232, only binary data can transmit and receive:

- 0DH as Carriage return
- 0AH as linefeed or new line

If you enter string in PC as HELLO+CR, in 8051 RX pin will receive binary only. HELLO string will receive as ascii stream. Total will receive 5 + 1 (0DH) + 1 (0AH) byte.

How to 8051 RX receive array and save in variable ?

Assume in 8051 declare variable as : int pass[3].

In keil int variable use two byte data, total 6 byte for pass[0], pass[1] and pass[2].

The process to passing array is:
1. In hyperterminal entry char by: PASS:2345,455,78
2. 8051 RX will receive 16 byte binary stream, will process if read 0AH binary (end of data).
3. 8051 must extract the first char by ending ':' char, this is for indentification what is the variable for passing to ?
4. 8051 extract string one by one separate by comma. And convert string to integer in c is atoi(). My be use 3 loop for this case.
5. save the result by converting using atoi to variable pass. pass[0]=atoi(string).

Point 1 is called string protocol, mybe you can build another string protocol as you need.

bsiswoyo
 

Can you repair my program? Thanx
 

Are you need only to send a value to Port of 8051 via hyper terminal ?.
Currently, i am writing C-8051 in keil only, no problem with you ?.

bsiswoyo
 

Hello,
I write a small program by using C51 keil uVision and BASCOM-51.
This program will set P0, P1, P2, P3 by typing string from serial or remote program like visual basic.

8051-MCU from RX pin will read line string with the following format:
PX=nnn[CR] -> X is port number 0..3 and nnn is 0..255 (decimal format)

examples:

P0=15
all P0 (low nyble) will set to high

P1=255
all P1 (byte) will set to high

To test this program, use hyper terminal with 9600,n,8,1 setting.

The command format not set Port as simultan but set one by one.
For simultan can use [ Pnnn,nnn,nnn,nnn ] command.

The following listing is written in C51 by using keil uVision:

/******************************************************************************/
/* HOWTO SET PORT 8051 FROM HYPER TERMINAL (REMOTE PROGRAM) */
/* Written by BAMBANG SISWOYO (**broken link removed**) */
/* */
/* Using C51 Keil software */
/* DEDICATED TO EDABOARD.COM FOR TUTORIAL */
/* */
/* PROTOCOL: */
/* 1. 8051 RX wait string PX=nnn[CR] -> X: 0..3, nnn: 0..255 */
/* 2. The second char is port number that assign a value nnn */
/* 3. String is checked and string value convert to byte and assign to port */
/* 4. Send 'OK' if okey, an ERROR if have any error */
/******************************************************************************/

/******************************************************************************/
/* The function: getchar(), putchar, print_string can be replaced by: */
/* getchar(..), putchar(..) and printf(..) in stdio.h library */
/* */
/* For tutorial, There use separately functions instead use stdio library. */
/******************************************************************************/
/* TOTAL CODE = 731 */

static char code ok_msg[] = "OK";
static char code error_msg[] = "ERROR COMMAND";
static char code error_port[] = "ERROR: PORT NUMBER";
static char code error_assign[] = "ERROR: ASSIGN";
static char code error_value_enter[] = "ERROR: VALUE NOT EXIST";
static char code error_value_number[] = "ERROR: VALUE NOT IN RANGE";
static char code cmd_msg[]= "Enter Command:";

char lineinput[20];
char port;

#include <reg51.h>
#include "stdlib.h"

initSerial()
{ /* init serial to 1200 baud by using 11.0592MHz crystal */
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0xFD; /* TH1: reload value for 9600 baud */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */
}

/******************************************************************************/
/* FUNCTION LIKE getchar(..) */
/******************************************************************************/
char getchar()
/* function wait char from rx pin */
{
while(!RI);
RI = 0;
return SBUF;
}

/******************************************************************************/
/* FUNCTION LIKE putchar(..) */
/******************************************************************************/
void putchar(char ch)
{
while(!TI);
TI = 0;
SBUF = ch;
}

/******************************************************************************/
/* SEND NEW LINE CHARACTER */
/******************************************************************************/
void put_newline()
{
putchar(0x0D);
putchar(0x0A);
}

/******************************************************************************/
/* FUNCTION LIKE printf(...) */
/******************************************************************************/
void print_string(char *ptr)
{ char ch;
while((ch = *ptr++) != 0)
{ putchar(ch); }
put_newline();
}

/******************************************************************************/
/* WAIT LINE STRING ENTER */
/******************************************************************************/
void getlineinput()
/* get one line string */
/* wait string from rx until ending by CR and LINE FEED char */
{
unsigned char cnt; /* counter character */
char ch; /* buffer char */
cnt = ch = 0;
while(cnt < 19 && ch != 0x0D) /* read line input */
{ ch = getchar();
if (ch != 0x0D) /* if CR return set to null */
{
lineinput[cnt++] = ch;
putchar(ch); /* send back (echo) to terminal */
}
}
lineinput[cnt] = 0;
put_newline();
}

/******************************************************************************/
/* EVALUATE LINE STRING */
/* AND ASSIGN VALUE TO THE PORT NUMBER OF 8051-MCU */
/******************************************************************************/
void action_port()
{ unsigned char value;
int value_int;
char *ptr = &lineinput;
/* evaluate string and send error if any exist */
/* check the 'P' character */
if (*ptr++ != 'P')
{ print_string(&error_msg); return; }
/* check port */
if ((port = *ptr++) < '0' || port > '3')
{ print_string(&error_port); return; }
/* check assign */
if (*ptr++ != '=')
{ print_string(&error_assign); return; }
/* check value exist */
if (*ptr == 0)
{ print_string(&error_value_enter); return; }

// convert to byte from string input
value_int = atoi(ptr);
if (value_int < 0 || value_int > 255)
{ print_string(&error_value_number); return; }
/* convert to byte */
value = value_int;
// assign value to port number
if (port == '0') P0 = value;
if (port == '1') P1 = value;
if (port == '2') P2 = value;
if (port == '3') P3 = value;
// print ok
print_string (&ok_msg);
}

void main()
{
initSerial();

while(1)
{ put_newline();
/* send command string */
/* if use with visual basic (remote program), please removed */
print_string(&cmd_msg);
/* read line string from serial */
getlineinput();
/* action for port */
action_port();
}
}

The following listing is written in BASCOM-51:

'/******************************************************************************/
'/* HOWTO SET PORT 8051 FROM HYPER TERMINAL (REMOTE PROGRAM) */
'/* Written by BAMBANG SISWOYO (**broken link removed**) */
'/* */
'/* Using BASCOM51 */
'/* DEDICATED TO EDABOARD.COM FOR TUTORIAL */
'/* */
'/* PROTOCOL: */
'/* 1. 8051 RX wait string PX=nnn[CR] -> X: 0..3, nnn: 0..255 */
'/* 2. The second char is port number that assign a value nnn */
'/* 3. String is checked and string value convert to byte and assign to port */
'/* 4. Send 'OK' if okey, an ERROR if have any error */
'/******************************************************************************/
'/* TOTAL CODE = 991 */

$crystal = 11059200
$baud = 9600
$regfile = "reg51.dat"

Dim Lineinput As String * 20
Dim Port As Byte
Dim Ch As String * 1
Dim Value As Byte

'********************* MAIN PROGRAM ********************************************
Run:
'/* if use with visual basic (remote program), please removed */
Print "Enter Command:"
'/* read line string from serial */
Input Lineinput
'/* action for port */
Gosub Action_port
Print
Goto Run

'/******************************************************************************/
'/* EVALUATE LINE STRING */
'/* AND ASSIGN VALUE TO THE PORT NUMBER OF 8051-MCU */
'/******************************************************************************/
Action_port:
'/ * Evaluate String And Send Error If Any Exist * /
'/* check the 'P' character */
Ch = Left(lineinput , 1)
If Ch <> "P" Then
Print "ERROR COMMAND"
Return
End If
'/* check port */
Ch = Mid(lineinput , 2 , 1)
Port = Val(ch)
If Ch < "0" Or Ch > "3" Then
Print "ERROR: PORT NUMBER"
Return
End If
'/* check assign */
Ch = Mid(lineinput , 3 , 1)
If Ch <> "=" Then
Print "ERROR: ASSIGN"
Return
End If

'/* check value exist */
If Len(lineinput) = 3 Then
Print "ERROR: VALUE NOT EXIST"
Return
End If

'// convert to byte from string input
Value = Val(mid(lineinput , 4))
'// assign value to port number
Select Case Port
Case 0 : P0 = Value
Case 1 : P1 = Value
Case 2 : P2 = Value
Case 3 : P3 = Value
End Select
Print "OK"
Return
 
elchula said:
Help me. I want to send an array of data to 89C51 from PC via RS232, then export these data to P1...i'm a beginner, so I don't know how to do it!!!!!!.

Please test this program by using keil C51.

The principle of protocol is using:
Pnnn,nnn,nnn,nnn[CR]

The header is P char following by decimal number in range 0..255. Sequence of decimal number is 4 sequence as P0, P1, P2 and P3 separately by comma.

Example:
P23,45,66,255
Set P0=23, P1=45, P2=66, P3=255.

P,255,,1
Set P1=255, P3=1, P0 and P2 not assign.

Attention: You must not set P3.0 & P3.1 to 0 because RX/TX pin.

All variable save in array port[0..3].
 
bsiswoyo said:
Hello,
/* PROTOCOL: */
/* 1. 8051 RX wait string PX=nnn[CR] -> X: 0..3, nnn: 0..255 */
/* 2. The second char is port number that assign a value nnn */
/* 3. String is checked and string value convert to byte and assign to port */
/* 4. Send 'OK' if okey, an ERROR if have any error */
/******************************************************************************/

hello I have test the application and i have any problem,

i start my 8051, after crete a connection whit hyperterminal 9600,8,n,1 but the application it seems not to work? i used a nullmodem wire...

1) by hyperterminal i must send a text file whit for example the line "P0=15"?
or when i start the hyper terminal i would have to see any text msg to my pc video?

help me ...THANKS!!!!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top