您的位置 首页 模拟

51单片机完成的485通讯程序

#ifndef__485_C__#define__485_C__#includereg51.h>#includestring.h>#defineunsignedcharuchar#defi

#ifndef__485_C__
#define__485_C__
#include
#include

#defineunsignedcharuchar
#defineunsignedintuint
/*通讯指令*/
#define__ACTIVE_0x01//主机问询从机是否存在
#define__GETDATA_0x02//主机发送读设备恳求
#define__OK_0x03//从机应对
#define__STATUS_0x04//从机发送设备状况信息
#define__MAXSIZE0x08//缓冲区长度
#define__ERRLEN12//任何通讯帧长度超越12则表明犯错
uchardbuf[__MAXSIZE];//该缓冲区用于保存设备状况信息
uchardev;//该字节用于保存本机设备号
sbitM_DE=P1^0;//驱动器使能,1有用
sbitM_RE=P1^1;//接纳器使能,0有用
voidget_status();//调用该函数取得设备状况信息,函数代码未给出
voidsend_data(uchartype,ucharlen,uchar*buf);//发送数据帧
bitrecv_cmd(uchar*type);//接纳主机指令,主机恳求仅包括指令信息
voidsend_byte(ucharda);//该函数发送一帧数据中的一个字节,由send_data()函数调用
voidmain()
{
uchartype;
ucharlen;

/*体系初始化*/
P1=0xff;//读取本机设备号
dev=(P1>>2);
TMOD=0x20;//定时器T1运用作业方法2
TH1=250;//设置初值
TL1=250;
TR1=1;//开端计时
PCON=0x80;//SMOD=1
SCON=0x50;//作业方法1,波特率9600bps,答应接纳
ES=0;//封闭串口中止
IT0=0;//外部中止0运用电平触发形式
EX0=1;//敞开外部中止0
EA=1;//敞开中止
/*主程序流程*/
while(1)//主循环
{
if(recv_cmd(&type)==0)//产生帧过错或帧地址与本机地址不符,丢掉当时帧后回来
continue;
switch(type)
{
case__ACTIVE_://主机问询从机是否存在
send_data(__OK_,0,dbuf);//发送应对信息,这儿buf的内容并未用到
break;
case__GETDATA_:
len=strlen(dbuf);
send_data(__STATUS_,len,dbuf);//发送设备状况信息
break;
default:
break;//指令类型过错,丢掉当时帧后回来
}
}
}
voidREADSTATUS()interrupt0using1//产生外部中止0时表明设备状况产生改动,该函数运用寄存器组1
{
get_status();//取得设备状况信息,并将其存入dbuf指向的存储区,数据最终一字节置0表明数据完毕
}
/*该函数接纳一帧数据并进行检测,不管该帧是否过错,函数均会回来
*函数参数type保存接纳到的指令字
*当接纳到数据帧过错或其地址位不为0时(非主机发送帧),函数回来0,反之回来1
*/
bitrecv_cmd(uchar*type)
{
bitdb=0;//当接纳到的上一个字节为0xdb时,该方位位
bitc0=0;//当接纳到的上一个字节为0xc0时,该方位位
uchardata_buf[__ERRLEN];//保存接纳到的帧
uchartmp;
ucharecc=0;
uchari;

M_DE=0;//置发送制止,接纳答应
M_RE=0;

/*接纳一帧数据*/
i=0;
while(!c0)//循环直至帧接纳完毕
{
RI=0;
while(!RI);
tmp=SBUF;
RI=0;
if(db==1)//接纳到的上一个字节为0xdb
{
switch(tmp)
{
case0xdd:
data_buf[i]=0xdb;//0xdbdd表明0xdb
ecc=ecc^0xdb;
db=0;
break;
case0xdc
data_buf[i]=0xc0;//0xdbdc表明0xc0
ecc=ecc^0xc0;
db=0;
break;
default
return0;//帧过错,回来
}
i++;
}
switch(tmp)//正常状况
{
case0xc0://帧完毕
c0=1;
break;
case0xdb://检测到转义字符
db=1;
break;
default://一般数据
data_buf[i]=tmp;//保存数据
ecc=ecc^tmp;//核算校验字节
i++;
}
if(i==__ERRLEN)//帧超长,过错,回来
return0;
}
/*判别帧是否过错*/
if(i<4)//帧过短,过错,回来
return0;
if(ecc!=0)//校验过错,回来
return0;
if(data_buf[0]!=dev)//非拜访本机指令,过错,回来
return0;
*type=data_buf[1];//取得指令字
return1;//函数成功回来
}
/*该函数发送一帧数据帧,参数type为指令字、len为数据长度、buf为要发送的数据内容*/
voidsend_data(uchartype,ucharlen,uchar*buf)
{
uchari;
ucharecc=0;//该字节用于保存校验字节
M_DE=1;//置发送答应,接纳制止
M_RE=1;

send_byte(dev);//发送本机地址
ecc=dev;
send_byte(type);//发送指令字
ecc=ecc^type;
send_byte(len);//发送长度
ecc=ecc^len;
for(i=0;i{
send_byte(*buf);
ecc=ecc^(*buf);
buf++;
}
send_byte(ecc);//发送校验字节

TI=0;//发送帧完毕标志
SBUF=0xc0;
while(!TI);
TI=0;
}
/*该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0则,发送0xdbdc*/
voidsend_byte(ucharda)
{
switch(da)
{
case0xdb://字节为0xdb,发送0xdbdd
TI=0;
SBUF=0xdb;
while(!TI);
TI=0;
SBUF=0xdd;
while(!TI)
TI=0;
break;
case0xc0://字节为0xc0,发送0xdbdc
TI=0;
SBUF=0xdb;
while(!TI);
TI=0;
SBUF=0xdc;
while(!TI)
TI=0;
break;
default://一般数据则直接发送
TI=0;
SBUF=da;
while(!TI);
TI=0;
}
}
#endif

RS-232接口完结核算机和单片机通讯程序
作者:
佚名来历:
本站原创点击数:…更新时刻:2008年07月10日【字体:大中小】 

//此程序经过RS-232接口来完结核算机和单片机通讯(程序已用p18f458试验板上调试经过)
//程序的调试可以用”串口调试帮手V2.1″辅佐完结,此程序可在http://www.51hei.com下载
//此程序首要发送测验数据55H,再经过中止完结数据的接纳和发送
#include”p18f458.h”
voidInterruptHandlerHigh(void);
//初始化程序
voidinitial()
{
SPBRG=0X19;//挑选传输波特率为9600bps
TXSTA=0X04;//挑选异步高速方法传输8位数据
RCSTA=0X80;//答应同步串行口作业
TRISC=0X80;//将RC7,RC6设置为输入,隔绝与外接电路的衔接
TXSTAbits.TXEN=1;//发送答应
RCSTAbits.CREN=1;//承受数据答应
PIE1bits.RCIE=1;//接纳中止使能
INTCON=0XC0;//总中止和外围中止答应
}
//高优先级中止向量
#pragmacodeInterruptVectorHigh=0x08
voidInterruptVectorHigh(void)
{
_asm
gotoInterruptHandlerHigh//跳到中止程
_endasm
}
//高优先级中止服务程序
#pragmacode
#pragmainterruptInterruptHandlerHigh
voidInterruptHandlerHigh()
{
while(PIR1bits.RCIF==1)//若接纳中止标志不为1,则为误操作,回来
{
TXREG=RCREG;//将接纳到的数据放入发送寄存器,并发动发送
}
}
//主程序
main()
{
initial();//体系初始化
TXREG=0X55;//发送数据55H进行测验
for(;;);
}

——————————————汇编语言版别的RS-232接口完结核算机和单片机通讯程序————
;
此程序经过RS-232接口来完结核算机和单片机通讯(程序以在p18f458试验板上调通)
;
本单片机程序由http://www.51hei.com供给
;
此程序首要发送测验数据55H,再经过中止完结数据的接纳和发送
;
程序的调试可以用”串口调试帮手V2.1″辅佐完结
LISTP=18f458
INCLUDE”P18f458.INC”
ORG0x00
GOTOMAIN
ORG0x08
GOTOINTSERVE
ORG0X30
;
**************中止服务子程序***************
INTSERVE
BTFSSPIR1,RCIF;
接纳中止标志为1?
GOTOERR_RE;
误操作,回来
MOVFRCREG,0;
不然,将接纳到的数据经过W寄存器
MOVWFTXREG;
放入发送寄存器,并发动发送
ERR_RENOP
RETFIE
;
****************初始化程序***************
INITIALNOP
MOVLW0X19;
挑选传输波特率为9600bps
MOVWFSPBRG
MOVLW0X04;
挑选异步高速方法传输8位数据
MOVWFTXSTA
MOVLW0X80;
答应同步串行口作业
MOVWFRCSTA
MOVLW0X80;
将RC7,RC6设置为输入,隔绝与外接电路的衔接
MOVWFTRISC
BSFTXSTA,TXEN;
发送答应
BSFRCSTA,CREN;
承受数据答应
BSFPIE1,RCIE;
接纳中止使能
MOVLW0XC0;
总中止和外围中止答应
MOVWFINTCON
RETURN
;
**********************主程序*********************
MAINNOP
CLRWDT
CALLINITIAL
MOVLW0X55;
发送数据55H进行测验
MOVWFTXREG
LOOP
GOTOLOOP
END

两片51单片机相互通讯的串行通讯程序(一个发送程序,一个接纳程序)
2007-05-2708:27
;
体系晶振是11.0592MHz
;
51单片机发送单片机程序
;
此程序用Proteus仿真经过
;
此程序在硬件上测验经过
;
2007-05-27
;
附有简化电路图
;
为了使初学者能看懂,程序与图尽可能的简略简明
;
试验现象为,发送端的P1口的哪个键被接下,接纳端的哪个灯对应着亮
;
如果把两个单片机的T和R经过无线模块(如根据MCP2120芯片的模块)来扩大,便可做成无线通讯
ORG0000H
AJMPSTART
ORG0040H
START:
MOVSP,#60H
MOVSCON,#50H;串口方法1
MOVTMOD,#20H;T1方法2
MOVTL1,#0FDH;波特率9600的常数
MOVTH1,#0FDH
SETBTR1
movr5,#00h
WAIT:
movp1,#0ffh
mova,p1
movr5,a
lcalldelay;
读键盘,这儿去颤动,还要加几句话
mova,p1
nop
CJNEA,5,WAIT;
是否有键输入
MOVSBUF,a;
串口输出键盘输入的值
NOP
SS:
JBCTI,WAIT;
是否发送完毕
SJMPSS
DELAY:
;
延时子程序
PUSH0;
保存现场
PUSH1
MOV0,#06H
DELAY1:
MOV1,#0H
DJNZ1,$
DJNZ0,DELAY1
POP1;
康复现场
POP0
RET
END

;
体系晶振是11.0592MHz
;
51单片机接纳单片机程序
;
此程序用Proteus仿真经过
;
此程序在硬件上测验经过
;
2007-05-27
;
附有简化电路图
;
为了使初学者能看懂,程序与图尽可能的简略简明
;
试验现象为,发送端的P1口的哪个键被接下,接纳端的哪个灯对应着亮
;
如果把两个单片机的T和R经过无线模块(如根据MCP2120芯片的模块)来扩大,便可做成无线通讯
ORG0000H
AJMPSTART
ORG0040H
START:
MOVSCON,#50H;串口方法1
MOVTMOD,#20H;T1方法2
MOVTL1,#0FDH;波特率9600的常数
MOVTH1,#0FDH
SETBTR1
WAIT:
JBCRI,DIS_REC;
是否接纳到数据
sjmpwait
DIS_REC:
MOVA,SBUF;
读串口接纳到的数据
movp1,a
SJMPwait
end

51单片机串行口通讯程序设计比如
时刻:2009-03-0617:13来历:
不知道作者:
牛牛点击:768次
串行口方法0使用编程8051单片机串行口方法0为移位寄存器方法,外接一个串入并出的移位寄存器,就能扩展一个并行口。单片机串行口通讯
程序设计硬件衔接图例:用8051单片机串行口外接CD4094扩展8位并行输出口,如图所示,8位并行口的各位都接一个发光二极管
  串行口方法0使用编程8051单片机串行口方法0为移位寄存器方法,外接一个串入并出的移位寄存器,就能扩展一个并行口。

<单片机串行口通讯程序设计硬件衔接图>
例:用8051单片机串行口外接CD4094扩展8位并行输出口,如图所示,8位并行口的各位都接一个发光二极管,要求发光管呈流水灯状况。串行口方法0的数据
传送可选用中止方法,也可选用查询方法,不管哪种方法,都要借助于TI或RI标志。串行发送时,能靠TI置位(发完一帧数据后)引起中止请求,在中止服务程序中发送
下一帧数据,或许经过查询TI的状况,只需TI为0就持续查询,TI为1就完毕查询,发送下一帧数据。在串行接纳时,则由RI引起中止或对RI查询来确认何时接纳下一帧数据。
不管选用什么方法,在开端通讯之前,都要先对操控寄存器SCON进行初始化。在方法0中将,将00H送SCON就能了。

—————–单片机串行口通讯程序设计列子————————–
ORG2000H
START:
MOVSCON,#00H;置串行口作业方法0
MOVA,#80H;最高位灯先亮
CLRP1.0;
封闭并行输出(避象传输过程中,各LED的”暗红”现象)
OUT0:
MOVSBUF,A;
开端串行输出
OUT1:
JNBTI,OUT1;
输出完否
CLRTI;
完了,清TI标志,以备下次发送
SETBP1.0;
翻开并行口输出
ACALLDELAY;
延时一段时刻
RRA;
循环右移
CLRP1.0;
封闭并行输出
JMPOUT0;
循环
阐明:DELAY延时子程序能用前面咱们讲P1口流水灯时用的延时子程序,这儿就不给出了

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/moni/275032.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部