51单片机与PC串口通信程序,求指导 ! 具体要求如下:

51单片机与PC串口通信程序,求指导 ! 具体要求如下:,第1张

要求用什么语言?

------------------------------

网友“星心晨梦”的回答,是可以满足题目要求的。

我实验了,是成功的,没有任何错误。

楼主应该检查自己的电路、串口设置等等。

------------------------------

网友“星心晨梦”的回答,篇幅稍稍长了一些。

缩减一半就可以正常工作了,可读性更好一些。

建议看看下面的。

------------------------------

#include <AT89X51h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

//---------------------------------------------------

uchar idata trdata1[] = {

'W','E','L','C','O','M','E',' ','T','O',' ','C','H','I','N','A','!',0x0d,0,0x00};

uchar idata trdata2[] = {

'M','Y',' ','N','A','M','E',' ','I','S',' ','L','I','M','I','N','G',0x0d,0,0x00};

uchar idata trdata3[] = {

'Y','I','N','G','Y','O','N','G','K','E','X','U','E','X','U','E','Y','U','A','N',0x0d,0,0x00};

uchar RxBuf[5], Rx_p, Rx_i, TX_p, Tx_i;

//---------------------------------------------------

void UART_Init(void) //串口初始化

{

PCON = 0x00;

SCON = 0x50; //串口工作方式为1,允许接收

TMOD = 0x20; // T1 定时方式2

TH1 = 0xfd; //波特率 9600bps @ fosc = 110592MHz

TL1 = 0xfd;

TR1 = 1; //启动T1

ES = 1; //开串口中断

EA = 1; //开总中断

}

//---------------------------------------------------

void main()

{

UART_Init();

Rx_p = 0;

Rx_p = 2;

while(1) {

if (Rx_p != 0) {

TX_p = Rx_p;//字符串1 2 3

Tx_i = 0; //字符指针

Rx_p = 0; //清零

Rx_i = 0;

TI = 1; //启动发送中断

} }

}

//---------------------------------------------------

void Uart_INT(void) interrupt 4 //串口中断函数

{

uchar Tcv = 0;

if(RI) { //接收?

RI = 0; //标志位清零

RxBuf[Rx_i] = SBUF;

if((RxBuf[Rx_i - 1] == 'g') && (RxBuf[Rx_i] == 'o')) Rx_p = 1;

if((RxBuf[Rx_i - 2] == 'w') && (RxBuf[Rx_i - 1] == 'h') && (RxBuf[Rx_i] == 'o')) Rx_p = 2;

if((RxBuf[Rx_i - 3] == 'h') && (RxBuf[Rx_i - 2] == 'o') && (RxBuf[Rx_i - 1] == 'm') && (RxBuf[Rx_i] == 'e')) Rx_p = 3;

P1 = Rx_p; //在P1显示收到的信息

Rx_i++;

Rx_i %= 5;

}

else {

TI = 0;

if (TX_p == 1) Tcv = trdata1[Tx_i]; //取来待发字符

if (TX_p == 2) Tcv = trdata2[Tx_i];

if (TX_p == 3) Tcv = trdata3[Tx_i];

if (Tcv != 0) {SBUF = Tcv; Tx_i++;} //不是0就发送

}

}

//---------------------------------------------------

编写串口通讯程序步骤为:

1、设置波特率

2、设置串口工作方式

3、收发数据。

比如:

main()

{

unsigned char dat;

TMOD=0x20;

TH1=0xfd;

TL1=0xfd;

TR1=1;

SCON=0x50;

while(1)

    {

    while(RI==0);

    RI=0;

    dat=SBUF;

    SBUF=~dat;

    while(TI==0)

    TI=0;

    }

}

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit LCD_RS = P2^0;

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

uchar data RXDdata[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 };

uchar temp,buf,m,count;

bit playflag=0;

uchar code cdis1[ ] = {" SERILA TRANFER "};

uchar code cdis2[ ] = {" "};

/

延时子程序

/

char code SST516[3] _at_ 0x003b;

void delay1(uint ms)

{

uchar k;

while(ms--)

{

for(k = 0; k < 120; k++);

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

delayNOP();

result = (bit)(P0&0x80);

LCD_EN = 0;

return(result);

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

delay1(15);

lcd_wcmd(0x01); //清除LCD的显示内容

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x0c); //开显示,显示光标,光标闪烁

delay1(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay1(5);

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos | 0x80); //数据指针=80+地址变量

}

/

发送数据函数

/

void senddata(uchar dat)

{

SBUF =dat;

while(!TI);

TI = 0;

}

/

串行中断服务函数

/

void serial() interrupt 4

{

ES = 0; //关闭串行中断

RI = 0; //清除串行接受标志位

buf = SBUF; //从串口缓冲区取得数据

playflag=1;

switch(buf)

{

case 0x31: senddata('X');break; //接受到1,发送字符'W'给计算机

case 0x32: senddata('L');break; //接受到2,发送字符'I'给计算机

case 0x33: senddata('1');break; //接受到3,发送字符'L'给计算机

case 0x34: senddata('0');break; //接受到4,发送字符'L'给计算机

case 0x35: senddata('0');break; //接受到5,发送字符'A'给计算机

case 0x36: senddata('0');break; //接受到5,发送字符'R'给计算机

default: senddata(buf);break; //接受到其它数据,将其发送给计算机

}

if(buf!=0x0D)

{

if(buf!=0x0A)

{

temp =buf;

if(count<16)

{

RXDdata[count]=temp;

count++;

}

}

}

ES = 1; //允许串口中断

}

/

数据显示函数

/

void play()

{

if(playflag)

{

lcd_pos(0x40); //设置位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //清LCD1602第二行

for(m=0;m<16;m++)

{

lcd_pos(0x40+m); //设置显示位置为第二行

lcd_wdat(RXDdata[m]); //显示字符

}

playflag=0;

count=0x00;

for(m=0;m<16;m++)

RXDdata[m]=0x20; //清显存单元

}

}

/

主函数

/

void main(void)

{

P0 = 0xff;

P2 = 0xff;

SCON=0x50; //设定串口工作方式

PCON=0x00; //波特率不倍增

TMOD=0x20; //定时器1工作于8位自动重载模式, 用于产生波特率

EA=1;

ES = 1; //允许串口中断

TL1=0xf3;

TH1=0xf3; //波特率2400

TR1=1;

lcd_init();

lcd_pos(0x00); //设置显示位置为第一行

for(m=0;m<16;m++)

lcd_wdat(cdis1[m]); //显示字符

lcd_pos(0x40); //设置显示位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //显示字符

while(1)

{

play();

}

}

这个串口通信程序在我的开发版上已经全部验证通过,你可以根据实际,攸 改里面某些参数,满足你自己的需要就行。

比如你你点亮小灯,这部分你只可在相应位置添加代码即可。单片机都是51的。

其中1602的显示程序是用来验证是否通信成功,这部分你可作为参考。这部分你大可用小灯显示程序来替代。

/   甲机串口程序:甲机向乙机发送控制命令字符,甲机同时接收乙机发送的数字,并显示在数码管上。/

#include<reg51h>

#define uchar unsigned char

#define uint unsigned int

sbit LED1=P1^0;

sbit LED2=P1^3;

sbit K1=P1^7;

uchar Operation_No=0;  // *** 作代码

//数码管代码

uchar codeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//延时

void DelayMS(uint ms)

{

uchari;

while(ms--)for(i=0;i<120;i++);

}

//向串口发送字符

void Putc_to_SerialPort(uchar c)

{

SBUF=c;

while(TI==0);

TI=0;

}

//主程序

void main()

{

LED1=LED2=1;

P0=0x00;

SCON=0x50;         //串口模式1,允许接收

TMOD=0x20;        //T1工作模式2

PCON=0x00;         //波特率不倍增

TH1=0xfd;

TL1=0xfd;

TI=RI=0;

TR1=1;

IE=0x90;        //允许串口中断

while(1)

{

DelayMS(100);

if(K1==0)      //按下K1时选择 *** 作代码0,1,2,3

{

while(K1==0);

Operation_No=(Operation_No+1)%4;

switch(Operation_No)    //根据 *** 作代码发送A/B/C或停止发送

{

case0:     Putc_to_SerialPort('X');

LED1=LED2=1;

break;

case1:     Putc_to_SerialPort('A');

LED1=~LED1;LED2=1;

break;

case2:     Putc_to_SerialPort('B');

LED2=~LED2;LED1=1;

break;

case3:     Putc_to_SerialPort('C');

LED1=~LED1;LED2=LED1;

break;

}

}

}

}

//甲机串口接收中断函数

void Serial_INT() interrupt   4

{

if(RI)

{

RI=0;

if(SBUF>=0&&SBUF<=9)P0=DSY_CODE[SBUF];

elseP0=0x00;

}

}

/ 乙机程序接收甲机发送字符并完成相应动作:乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作。/

#include<reg51h>

#define uchar unsigned char

#define uint unsigned int

sbit LED1=P1^0;

sbit LED2=P1^3;

sbit K2=P1^7;

uchar NumX=-1;

//延时

void DelayMS(uint ms)

{

uchari;

while(ms--)for(i=0;i<120;i++);

}

//主程序

void main()

{

LED1=LED2=1;

SCON=0x50;         //串口模式1,允许接收

TMOD=0x20;        //T1工作模式2

TH1=0xfd;            //波特率9600

TL1=0xfd;

PCON=0x00;         //波特率不倍增

RI=TI=0;

TR1=1;

IE=0x90;

while(1)

{

DelayMS(100);

if(K2==0)

{

while(K2==0);

NumX=++NumX%11;   //产生0~10范围内的数字,其中10表示关闭

SBUF=NumX;

while(TI==0);

TI=0;

}

}

}

void Serial_INT() interrupt 4

{

if(RI)      //如收到则LED则动作

{

RI=0;

switch(SBUF)//根据所收到的不同命令字符完成不同动作

{

case'X':   LED1=LED2=1;break;          //全灭

case'A':   LED1=0;LED2=1;break;       //LED1亮

case'B':   LED2=0;LED1=1;break;       //LED2亮

case'C':   LED1=LED2=0;                  //全亮

}

}

}

IIC通讯只能是TTL连接通信,要求两个单片机是近距离的,应在1米以内。既然是TTL连接,为何不用串口呢,也是TTL连接,串口通信简单多了。

而IIC通信,两个单片机都是用引脚来模拟的,通信协议比较麻烦,写程序很麻烦的,又何苦呢?

初始化程序:

BTLEQU2FH;波特率放在内部RAM的2FH单元

MOVTMOD,#21H;T0方式1,16位计数器,T1方式2,串口用

SETBTR0;启动T0

MOVBTL,#0F3H;波特率设定为1200

MOVSCON,#0C0H;串口方式3,9位数据,禁止接收

接收及验证程序:

NUMEQU2BH;同步符个数值存放在内部RAM的2BH单元

TEMPEQU2CH

ROM-CH:DB55H,55H,55H,55H,55H,55H,55H,55H,55H,55H

DB55H,55H,55H,55H,55H,55H,55H,55H,55H,55H;20字节同步符

MIMDB'WSC':3字节密码“WSC”

SETBP35;置电台收状态

SETBREN;允许串口接收

A1:MOVNUM,#0;记录连续到同步符55H的个数

A2:JBRI,A2;串口有数据转A3

A3:CLRRI;清接收中断标志

MOVA,SBUF;读串口数据

CJNEA,#55H,A1;不是同步符转A1

INCNUM;收到的同步符个数加1

MOVA,NUM;取收到的同步符个数

CJNEA,#5,A2;未收够连续5个55H转A2

A4:MOVNUM,#0;密码验证,记录收到密码字节数

A5:MOVDPTR,#MIM;密码字符首址

MOVA,NUM

MOVCA,@A+DPTR;查表取密码

MOVTEMP,A;保存密码

JBRI,A6;串口收完一个字节转A6

A6:CLRRI;清接收中断标志

MOVA,SBUF;读串口数据

CJNEA,TEMP,A4;与密码不符转A4

INCNUM;收到的密码个数加1

MOVA,NUM;取已收到的密码字节数

CJNEA,#3,A5;密码未收完转A5

发送程序:

CLRP35;置电台发状态

MOVB,#23

MOVDPTR,#ROM-CH

B1:CLRA

MOVCA,@A+DPTR;查表发送同步符和密码共24字节

INCDPTR

LCALLSEND-CH;调发送单字节子程序

DJNZB,B1

CLRA

MOVDPTR,#7000H;外部RAM数据首址,发送外部RAM中的数据到电台

B2:CJNER4,#0,B3

CJNER3,#0,B3;R4R3=发送字节数

B3:MOVXA,@DPTR;取数据

INCDPTR

LCALLSEND-CH

CJNER3,#0,B4

CJNER4,#0,B5

B4:DECR3

LJMPB2

DECR3

DECR4

LJMPB2

SEND-CH:SETBTB8

MOVSBUF,A

DB0,0,0,0,0,0,0,0

JNBTI,$;延时4μs

CLRTI

RET

结语

以上就是关于51单片机与PC串口通信程序,求指导 ! 具体要求如下:全部的内容,包括:51单片机与PC串口通信程序,求指导 ! 具体要求如下:、怎样编写单片机的串口通信的程序,一般的步骤是怎么样、高分求51单片机串口通信的程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9446218.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存