VB中关于PC机与51单片机通信的一些问题
背景:本人最近在用VB中MSComm控件,对PC机与单片机之间的通信,进行编程。希望对这方面熟悉的达人能够帮我解决一下以下问题。1、单片机串行口中断问题:单片机串行口中断...
背景:本人最近在用VB中MSComm控件,对PC机与单片机之间的通信,进行编程。希望对这方面熟悉的达人能够帮我解决一下以下问题。
1、单片机串行口中断问题:单片机串行口中断是不是这么一个过程:PC机给单片机每发送一帧数据,单片机就启动一次中断?
2、(对问题1的追问)如果我要发送两帧数据,第一帧用来选择操作对象(比如说有P1,P2,P3三个操作对象),第二帧数据,用来操作对象赋值。这个程序该怎么写。
3、在MSComm控件中,对数据发送有两个方式,一个是文本方式,一个是二进制方式。
3.1如果用文本方式发送。单片机能对这个文本进行处理吗?或者说这个文本方式发送用于什么情况。
3.2如果用二进制方式发送,但我在单片机程序里,用十六进制对发送过来的数据进行判断,这样会不会产生问题。详见以下程序。
*程序摘录
MOV A,SBUF
XRL A,#05H
JZ SET_T0 展开
1、单片机串行口中断问题:单片机串行口中断是不是这么一个过程:PC机给单片机每发送一帧数据,单片机就启动一次中断?
2、(对问题1的追问)如果我要发送两帧数据,第一帧用来选择操作对象(比如说有P1,P2,P3三个操作对象),第二帧数据,用来操作对象赋值。这个程序该怎么写。
3、在MSComm控件中,对数据发送有两个方式,一个是文本方式,一个是二进制方式。
3.1如果用文本方式发送。单片机能对这个文本进行处理吗?或者说这个文本方式发送用于什么情况。
3.2如果用二进制方式发送,但我在单片机程序里,用十六进制对发送过来的数据进行判断,这样会不会产生问题。详见以下程序。
*程序摘录
MOV A,SBUF
XRL A,#05H
JZ SET_T0 展开
展开全部
1.不一定是一每发送一帧数据就启动一次中断,你也可以启动一次中断,连续发送多个数据,并将这些数据存储在单片机的存储器中,但这些数据的长度和存储位置,是你在单片机里面约定好的
2.可以的,你所说的是PC连接多个从片的情况吧,这只要先发送一个地址给单片机,让单片机确认是自己的地址后,在回复PC自己的地址,PC自己确定没错后,在发送命令,传送数据,我这里有个我自己写的485通讯程序,调试过后,效果很好,你可以参考一下,当然,你只要求的是对指定地址发送一个数据,,可以对下面的程序做简化,没有必要要L
#include <reg51.h> //选用晶振11.0592MHz
#include <absacc.h>
#define DATA51 DBYTE[0x80] //80H存数据
#define AddressID 1 //本机地址
unsigned char Call,*p; //call命令00H(从机接收)01H(从机发送)
unsigned char L; //发送的字个数
void Rs485();
main()
{
EA=1;
TMOD=0x20; //定时器T1方式为2
TH1=0xfa; //波特率设定为9600
TL1=0xfa;
/************EA需要定时开,不能一直开着******/
ES=1;
/******************************************/
SCON=0xf0; //串口方式为3,SM2=1,REN=1允许接受
PCON=0x80; //SMOD=1
TR1=1;
p=&DATA51;
while(1);
}
void Rs485()
{ unsigned int i=0;
SM2=0; //不管RB8的值,都接受8位数据
SBUF=AddressID; //应答P本机地址C
while(TI==0);
TI=0;
while(RI==0);
RI=0;
if(RB8==0) //接受的是数据
goto SSC2;
SM2=1; //打开RB8控制,只有接受到RB8=1;才把8位数据给SBUF
SBUF=0x80; //不合法命令,报错
while(TI==0);
TI=0;
return;
SSC2:
if(Call==0x00||Call==0x01) //合法命令
goto SSC3;
SBUF=0x80; //不合法命令,报错
while(TI==0);
TI=0;
return;
SSC3:
if(Call==0x00) //从机接收数据命令00H
goto SSC4;
if(F0==1) //自定义位F0,表示该单片机已经准备好了
goto STD;
SBUF=0x00;
while(TI==0);
TI=0;
return;
STD:
SBUF=0x02;
while(TI==0);
TI=0;
STD1:
SBUF=*(p+i++);
while(TI==0);
TI=0;
if(--L>0)
goto STD1;
SM2=1;
return;
SSC4:
if(F0==1)
goto SRD;
SBUF=0x00;
while(TI==0);
TI=0;
return;
SRD:
SBUF=0x01;
while(TI==0);
TI=0;
SRD1:
while(RI==0);
RI=0;
*(p+i++)=SBUF;
if(--L>0)
goto SRD1;
return;
}
void counter4(void) interrupt 4 //串口中断
{
if(SBUF==AddressID)
Rs485();
}
3.1 采用文本方式发送,可能导致通讯不成功。这时应该采用二进知方式发送,即可以发送任意字符,如你的数据是纯可读字符(含空格,0x00等),即可用文本方式发送,接受,这样你不用作数据转换也能收到可读的数据,而二进制方式,则无论你发送的是什么数据,均要做数据转化,转化为BCD码
3.2 如果你要用汇编的话,要注意接收、发送的格式,接受发送万变,必须软件复位TI和RI
接收:
JNB TI,$
MOV A,SBUF
CLR TI
发送:
MOV SBUF,A
JNB RI,$
CLR RI
2.可以的,你所说的是PC连接多个从片的情况吧,这只要先发送一个地址给单片机,让单片机确认是自己的地址后,在回复PC自己的地址,PC自己确定没错后,在发送命令,传送数据,我这里有个我自己写的485通讯程序,调试过后,效果很好,你可以参考一下,当然,你只要求的是对指定地址发送一个数据,,可以对下面的程序做简化,没有必要要L
#include <reg51.h> //选用晶振11.0592MHz
#include <absacc.h>
#define DATA51 DBYTE[0x80] //80H存数据
#define AddressID 1 //本机地址
unsigned char Call,*p; //call命令00H(从机接收)01H(从机发送)
unsigned char L; //发送的字个数
void Rs485();
main()
{
EA=1;
TMOD=0x20; //定时器T1方式为2
TH1=0xfa; //波特率设定为9600
TL1=0xfa;
/************EA需要定时开,不能一直开着******/
ES=1;
/******************************************/
SCON=0xf0; //串口方式为3,SM2=1,REN=1允许接受
PCON=0x80; //SMOD=1
TR1=1;
p=&DATA51;
while(1);
}
void Rs485()
{ unsigned int i=0;
SM2=0; //不管RB8的值,都接受8位数据
SBUF=AddressID; //应答P本机地址C
while(TI==0);
TI=0;
while(RI==0);
RI=0;
if(RB8==0) //接受的是数据
goto SSC2;
SM2=1; //打开RB8控制,只有接受到RB8=1;才把8位数据给SBUF
SBUF=0x80; //不合法命令,报错
while(TI==0);
TI=0;
return;
SSC2:
if(Call==0x00||Call==0x01) //合法命令
goto SSC3;
SBUF=0x80; //不合法命令,报错
while(TI==0);
TI=0;
return;
SSC3:
if(Call==0x00) //从机接收数据命令00H
goto SSC4;
if(F0==1) //自定义位F0,表示该单片机已经准备好了
goto STD;
SBUF=0x00;
while(TI==0);
TI=0;
return;
STD:
SBUF=0x02;
while(TI==0);
TI=0;
STD1:
SBUF=*(p+i++);
while(TI==0);
TI=0;
if(--L>0)
goto STD1;
SM2=1;
return;
SSC4:
if(F0==1)
goto SRD;
SBUF=0x00;
while(TI==0);
TI=0;
return;
SRD:
SBUF=0x01;
while(TI==0);
TI=0;
SRD1:
while(RI==0);
RI=0;
*(p+i++)=SBUF;
if(--L>0)
goto SRD1;
return;
}
void counter4(void) interrupt 4 //串口中断
{
if(SBUF==AddressID)
Rs485();
}
3.1 采用文本方式发送,可能导致通讯不成功。这时应该采用二进知方式发送,即可以发送任意字符,如你的数据是纯可读字符(含空格,0x00等),即可用文本方式发送,接受,这样你不用作数据转换也能收到可读的数据,而二进制方式,则无论你发送的是什么数据,均要做数据转化,转化为BCD码
3.2 如果你要用汇编的话,要注意接收、发送的格式,接受发送万变,必须软件复位TI和RI
接收:
JNB TI,$
MOV A,SBUF
CLR TI
发送:
MOV SBUF,A
JNB RI,$
CLR RI
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询