51单片机实现的485通讯程序.docx
- 文档编号:26997528
- 上传时间:2023-06-25
- 格式:DOCX
- 页数:12
- 大小:63.25KB
51单片机实现的485通讯程序.docx
《51单片机实现的485通讯程序.docx》由会员分享,可在线阅读,更多相关《51单片机实现的485通讯程序.docx(12页珍藏版)》请在冰豆网上搜索。
51单片机实现的485通讯程序
51单片机实现的485通讯程序
#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 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"辅助完成,此程序可在下载 //此程序首先发送测试数据55H,再通过中断实现数据的接收和发送 #include "p18f458.h" void InterruptHandlerHigh(void>。 //初始化程序 void initial(> { 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 void InterruptVectorHigh(void> { _asm gotoInterruptHandlerHigh //跳到中断程 _endasm } //高优先级中断服务程序 #pragmacode #pragmainterruptInterruptHandlerHigh void InterruptHandlerHigh(> { while(PIR1bits.RCIF==1> //若接收中断标志不为1,则为误操作,返回 { TXREG=RCREG。 //将接收到的数据放入发送寄存器,并启动发送 } } //主程序 main(> { initial(>。 //系统初始化 TXREG=0X55。 //发送数据55H进行测试 for(。 。 >。 } ------------------------------------------汇编语言版本的RS-232接口实现计算机和单片机通信程序------------ 。 此程序通过RS-232接口来完成计算机和单片机通讯<程序以在p18f458实验板上调通) 。 本单片机程序由提供 。 此程序首先发送测试数据55H,再通过中断实现数据的接收和发送 。 程序的调试可以用"串口调试助手V2.1"辅助完成 LIST P=18f458 INCLUDE "P18f458.INC" ORG 0x00 GOTO MAIN ORG 0x08 GOTO INTSERVE ORG 0X30 。 **************中断服务子程序*************** INTSERVE BTFSS PIR1,RCIF 。 接收中断标志为1? GOTO ERR_RE 。 误操作,返回 MOVF RCREG,0 。 否则,将接收到的数据通过W寄存器 MOVWF TXREG 。 放入发送寄存器,并启动发送 ERR_RE NOP RETFIE 。 ****************初始化程序*************** INITIAL NOP MOVLW 0X19 。 选择传输波特率为9600bps MOVWF SPBRG MOVLW 0X04 。 选择异步高速方式传输8位数据 MOVWF TXSTA MOVLW 0X80 。 允许同步串行口工作 MOVWF RCSTA MOVLW 0X80 。 将RC7,RC6设置为输入,断绝与外接电路的连接 MOVWF TRISC BSF TXSTA,TXEN 。 发送允许 BSF RCSTA,CREN 。 接受数据允许 BSF PIE1,RCIE 。 接收中断使能 MOVLW 0XC0 。 总中断和外围中断允许 MOVWF INTCON RETURN 。 **********************主程序********************* MAIN NOP CLRWDT CALL INITIAL MOVLW 0X55 。 发送数据55H进行测试 MOVWF TXREG LOOP GOTO LOOP END 两片51单片机互相通信的串行通信程序(一个发送程序,一个接收程序> 2007-05-2708: 27 。 系统晶振是11.0592MHz 。 51单片机发送单片机程序 。 此程序用Proteus仿真通过 。 此程序在硬件上测试通过 。 2007-05-27 。 附有简化电路图 。 为了使初学者能看懂,程序与图尽可能的简单扼要 。 实验现象为,发送端的P1口的哪个键被接下,接收端的哪个灯对应着亮 。 如果把两个单片机的T和R通过无线模块<如基于MCP2120芯片的模块)来扩充,便可做成无线通信 ORG 0000H AJMP START ORG 0040H START: MOV SP,#60H MOV SCON,#50H 。 串口方式1 MOV TMOD,#20H 。 T1方式2 MOV TL1,#0FDH 。 波特率9600的常数 MOV TH1,#0FDH SETB TR1 mov r5,#00h WAIT: mov p1,#0ffh mov a,p1 mov r5,a lcalldelay 。 读键盘,这里去抖动,还要加几句话 mov a,p1 nop CJNE A,5,WAIT 。 是否有键输入 MOV SBUF,a 。 串口输出键盘输入的值 NOP SS: JBC TI,WAIT 。 是否发送完毕 SJMP SS DELAY: 。 延时子程序 PUSH 0 。 保存现场 PUSH 1 MOV 0,#06H DELAY1: MOV 1,#0H DJNZ 1,$ DJNZ 0,DELAY1 POP 1 。 恢复现场 POP 0 RET END 。 系统晶振是11.0592MHz 。 51单片机接收单片机程序 。 此程序用Proteus仿真通过 。 此程序在硬件上测试通过 。 2007-05-27 。 附有简化电路图 。 为了使初学者能看懂,程序与图尽可能的简单扼要 。 实验现象为,发送端的P1口的哪个键被接下,接收端的哪个灯对应着亮 。 如果把两个单片机的T和R通过无线模块<如基于MCP2120芯片的模块)来扩充,便可做成无线通信 ORG 0000H AJMP START ORG 0040H START: MOV SCON,#50H 。 串口方式1 MOV TMOD,#20H 。 T1方式2 MOV TL1,#0FDH 。 波特率9600的常数 MOV TH1,#0FDH SETB TR1 WAIT: JBC RI,DIS_REC 。 是否接收到数据 sjmp wait DIS_REC: MOV A,SBUF 。 读串口接收到的数据 mov p1,a SJMP wait 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就能了。 -----------------单片机串行口通信程序设计列子-------------------------- ORG
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 实现 485 通讯 程序