单片机RS-485通信源程序
- 格式:doc
- 大小:417.00 KB
- 文档页数:7
单片机485烧程序方法
1. 准备工作,首先,你需要准备一台支持单片机485烧录的编程器,以及单片机的开发板和对应的编程软件。
确保你有正确的单片机型号和对应的烧录工具。
2. 连接硬件,将编程器通过USB接口连接到计算机上,然后将编程器的接口与开发板上的对应接口相连。
确保连接的稳固性和正确性。
3. 打开编程软件,打开单片机的编程软件,一般来说,这些软件会提供一个界面,你可以在界面中选择单片机型号和相应的烧录方式。
4. 选择文件,在编程软件中选择你要烧录的程序文件,通常是一个.hex文件或者.bin文件。
5. 设置参数,根据你的需要,设置好烧录的参数,比如时钟频率、烧录方式等。
6. 烧录程序,点击软件界面上的烧录按钮,软件会开始向单片
机烧录程序。
在烧录过程中,要确保编程器和单片机的连接稳定,避免操作过程中的干扰。
7. 验证烧录,烧录完成后,一般软件会提示烧录成功。
此时可以进行一次验证,确认程序是否成功烧录到单片机中。
总的来说,单片机485烧程序方法需要准备好硬件设备、连接正确的硬件接口、选择正确的编程软件、设置好烧录参数,并且要确保烧录过程中的稳定性和正确性。
希望这些步骤能帮助到你。
单片机RS-485通信源程序附录一、主机源程序#include <reg52.H>unsigned char xdata table[5];unsigned char code tab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x05,0xc1,0x63,0x85,0x61,0x71,0xff}; sbit ctrl=P1^2;sbit DATA=P1^0;sbit CLK=P1^1;void show(unsigned char m)//LED显示子程序{unsigned char i,d;d=tab[m];for(i=0;i<8;i++){DATA=d&0x01;CLK=0;CLK=1;d=d>>1;}}void interrupt0(void) interrupt 0 using 0//串行中断程序{unsigned char cm0,cm1,sum0,sum1,i;lab:sum0=0;ctrl=1;//将MAX485设置为发送方式SBUF=0xFF;//发送数据申请while(TI!=1);ctrl=0; //将MAX485设置为接收方式TI=0;while(RI!=1);cm0=SBUF;//接收申请确认信号RI=0;if(cm0==0xff){i=0;ctrl=0;while(RI!=1);cm1=SBUF; //接收第一个数据RI=0;附录二、从机源程序#include <reg52.H>unsigned char xdata table[]={0,0,0,0};sbit replay=P1^0;sbit warn0=P1^1;sbit CTRL=P1^2;sbit DATA=P1^3;sbit CLK=P1^4;unsigned char code tab[]={0x03,0x9f,0x25,0x0d, //显示用的码表0x99,0x49,0x41,0x1f,0x01,0x09,0x05,0xc1,0x63,0x85,0x61,0x71,0xff};void delay(void) //键盘扫描延时10ms程序{unsigned char i,j;for(i=20;i>0;i--)for(j=248;j>0;j--);}void show(unsigned char m)//LED显示子程序{unsigned char i,d;d=tab[m];for(i=0;i<8;i++){DATA=d&0x01;CLK=0;CLK=1;d=d>>1;}}void ser(void) interrupt 4 using 0//串行中断程序{unsigned char cm,sum,i;sum=0;replay=1;warn0=1;cm=SBUF;RI=0;if(cm==0xf0)//判断是否为主机返回的确认信号{replay=0; //表示已正确发送完一组数据goto end;}elseif(cm!=0xff)//判断是否为主机的数据申请{warn0=0; //通信命令错误提示goto end;}else{CTRL=1; //置MAX485为发送方式SBUF=0xff;//发送申请确认信号while(TI!=1);TI=0;for(i=0;i<4;i++){SBUF=table[i]; //发送数据while(TI!=1);TI=0;sum=sum+table[i];//计算校验和}SBUF=sum; //发送校验和while(TI!=1);TI=0;SBUF=0xf0;//发送结束标志while(TI!=1);TI=0;}end: CTRL=0; //置MAX485为接收方式return;}void main(void){unsigned char key,X,Y,temp;SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1 定时方式2 PCON=0x80; //设SMOD=1;TH1 = 0xFA; //11.0592MHz 9600 波特率TL1 = 0xFA;TR1 = 1; //启动定时器ES=1; //开串行中断EA=1; //开总中断CTRL=0; //置MAX485为接收方式replay=1;warn0=1;while(1) //键盘扫描{P2=0xff; //键盘初始化P2=0xf0;if (P2!=0xf0){delay(); //延时去抖if (P2!=0xf0){X=P2; //读键盘P2=0x0f;Y=P2;P2=X|Y;temp=P2;switch(temp){case 0xee:key=0;break;case 0xde:key=1;break;case 0xbe:key=2;break;case 0x7e:key=3;break;case 0xed:key=4;break;case 0xdd:key=5;break;case 0xbd:key=6;break;case 0x7d:key=7;break;case 0xeb:key=8;break;case 0xdb:key=9;break;case 0xbb:key=10;break;case 0x7b:key=11;break;case 0xe7:key=12;break;case 0xd7:key=13;break;case 0xb7:key=14;break;case 0x77:key=15;break;}for(X=0;X<4;X++) //存储最近读的按键码table[X]=table[X+1];table[3]=key;P2=0xf0;temp=P2;for(X=0;X<4;X++)show(table[X]);while(temp!=0xf0){P2=0xf0;temp=P2;}}}else key=16;}}附录三、电路原理图显示部分电路主要部分电路。
485通信程序(51单片机)什么是485通信?RS-485是一种串行通信协议,它使用差分信号传输数据。
485通信支持了在两个或以上设备之间传输数据的需求,比如用于电子计算机、通信设备、工业自动化等等。
RS-485已广泛应用于数控机床、自动化设备控制等领域中。
单纯的485通信包含四种通信模式:点对点、总线形、多主机和简介式通信。
其中,点对点通信指的是一对一的通信方式;总线形通信指的是一对多的群通信方式,所有设备都在同一条总线上发送和接收数据;多主机通信指的是多台主机的通信方式,多个设备都可以同时发送数据;简介式通信是一种用于仅需要发送少量数据的情况的通信方式。
下面介绍一下485通信的部分基本知识1.485通信的传输距离远,一般可以达到1200米。
2.485通信具有较强的抗干扰能力。
3.485通信使用差分信号进行传输,信号稳定,传输速率也比较快。
4.485通信可以支持多个设备同时进行通信,但是在同一时间内只有一个设备可发送数据。
5.在采用485通信时,一定要注意通讯端口的设置,如波特率、数据位、停止位等。
程序实现原理该程序使用了51单片机作为主控制器实现了基本的485通信,具体实现如下:1.通信模式的设置在程序开始时,需要设置通信模式。
如果通信模式为点对点通信,则可以直接使用UART通信模块进行通信;如果是多点通信,则需要使用485通信芯片。
2.通讯端口的配置在进行485通讯时,需要进行通讯端口的配置,包括波特率、数据位、停止位等参数的设定。
在485通信模式下,只有一个设备可为主设备,其他设备均为被设备。
在发送数据时,主设备的TXD口要与外部总线的D+口相连,而D-口不连接,从设备的TXD口要与D-口相连,而D+口不连接。
在接收数据时,主设备的RXD口要与D+口相连,而D-口不连接,从设备的RXD口要与D-口相连,而D+口不连接。
3.数据的发送和接收在发送和接收数据时,需要采用特定的方式进行报文的封装和解析。
RS485通信示例程序看程序时请配合芯片资料一起看,公布源码不是为了抄袭,而是为了相互学习,如果有不对的地方还请指出来,谢谢!/*===================================================== ===程序说明:PC端通过RS232-RS485芯片转换后再经过一个RS485收发芯片MAX485连接单片机的RX和TX(RO-RX,DI-TX)的通信示例程序控制发送和接收的引脚为P2.7,使用时注意正确连接!作者:绘天地点:成都信息工程学院====================================================== ==*/#include <reg52.h>#include "com_communication.h"sbit SHRL=P2^7;/*高电平发送,低电平接收*/void main(){int c;UartInit();SHRL=0;/*保持为发送状态*/while(1){if ( RI ) //如果收到数据{RI = 0; //清除接收标志c = SBUF; //读取收到的数据SHRL=1;UartSendChar(c); //回送收到的数据SHRL=0;}}}所调用的头文件:#ifndef _com_H_#define _com_H_//定义波特率(取值1200、2400、4800、9600、19200等)#define BaudRate 19200L/*********************************************************************** ********函数:UartInit()功能:串行口初始化************************************************************************ *******/void UartInit(){SCON = 0x50; //串口方式1(8位UART),允许接收PCON |= 0x80; //波特率加倍TMOD &= 0x0F; //设置T1为8位自动重装定时器,用于产生波特率TMOD |= 0x20;TH1 = TL1 = 256 - (11059200L / 12) / (16 * BaudRate); //设置T1初值TR1 = 1; //启动T1}/*********************************************************************** ********函数:UartSendChar()功能:通过串行口发送单个字节参数:c是被发送的字节数据,取值0x00~0xFF************************************************************************ *******/void UartSendChar(char c){SBUF = c; //数据写入SBUF,同时启动硬件发送过程while ( !TI ); //等待发送完毕TI = 0; //清除发送标志}#endif。
/* 以下为单片机串口485通讯程序,从机程序(当然也适用于主机程序),主机发送可以先用串口帮手软件来调试,经过Keil uVision4实际测试,测试效果如结尾图片所示, 大部分来自网络,只是改了两个地方: len = sizeof(dbuf),if(i >=( __ERRLEN+1)) // 帧超长,错误,返回,就可以实现了,其中的原因自已体会吧*/#ifndef __485_C__#define __485_C__#include <reg51.h>#include <string.h>#include <stdio.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/* 通信命令*/#define __ACTIVE_ 0x01 // 主机询问从机是否存在#define __GETDATA_ 0x02 // 主机发送读设备请求#define __OK_ 0x03 // 从机应答#define __STATUS_ 0x04 // 从机发送设备状态信息#define __MAXSIZE 0x08 // 缓冲区长度#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错//uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息uchar dbuf[__MAXSIZE];//={0,1,2,3,4,5,6,7}; // 该缓冲区用于保存设备状态信息uchar dev; // 该字节用于保存本机设备号sbit M_DE = P1^0; // 驱动器使能,1有效sbit M_RE = P1^1; // 接收器使能,0有效void get_status(); // 调用该函数获得设备状态信息,函数代码未给出void send_data(uchar type, uchar len, uchar *buf); // 发送数据帧bit recv_cmd(uchar *type); // 接收主机命令,主机请求仅包含命令信息void send_byte(uchar da); // 该函数发送一帧数据中的一个字节,由send_data()函数调用void main(){uchar type;uchar len;/* 系统初始化*/P1 = 0xff; // 读取本机设备号//dev = (P1>>2);dev = 0x01;TMOD = 0x20; // 定时器T1使用工作方式2TH1 = 250; // 设置初值TL1 = 250;TR1 = 1; // 开始计时PCON = 0x80; // SMOD = 1SCON = 0x50; // 工作方式1,波特率9600bps,允许接收ES = 0; // 关闭串口中断//IT0 = 0; // 外部中断0使用电平触发模式//EX0 = 1; // 开启外部中断0EA = 1; // 开启中断/* 主程序流程*/while(1) // 主循环{if(recv_cmd(&type) == 0) // 发生帧错误或帧地址与本机地址不符,丢弃当前帧后返回continue;switch(type){case __ACTIVE_: // 主机询问从机是否存在send_data(__OK_, 0, dbuf); // 发送应答信息,这里buf的内容并未用到break;case __GETDA TA_:// len = strlen(dbuf);//在C51中不能这个函数计算unsigned char型,这个函数只能计算char型len = sizeof(dbuf);// len =0x08;send_data(__STA TUS_, len, dbuf); // 发送设备状态信息break;default:break; // 命令类型错误,丢弃当前帧后返回}}}void READSTATUS() interrupt 0 using 1 // 产生外部中断0时表示设备状态发生改变,该函数使用寄存器组1{get_status(); // 获得设备状态信息,并将其存入dbuf指向的存储区,数据最后一字节置0表示数据结束}/* 该函数接收一帧数据并进行检测,无论该帧是否错误,函数均会返回* 函数参数type保存接收到的命令字* 当接收到数据帧错误或其地址位不为0时(非主机发送帧),函数返回0,反之返回1*/bit recv_cmd(uchar *type){bit db = 0; // 当接收到的上一个字节为0xdb时,该位置位bit c0 = 0; // 当接收到的上一个字节为0xc0时,该位置位uchar data_buf[__ERRLEN]; // 保存接收到的帧__ERRLEN=12;uchar tmp;uchar ecc = 0;uchar i;M_DE = 0; // 置发送禁止,接收允许M_RE = 0;/* 接收一帧数据*/i = 0;while(!c0) // 循环直至帧接收完毕{RI = 0;while(!RI);tmp = SBUF;RI = 0;if(db == 1) // 接收到的上一个字节为0xdb{switch(tmp){case 0xdd:data_buf[i] = 0xdb; // 0xdbdd表示0xdbecc = ecc^0xdb;db = 0;break;case 0xdc:data_buf[i] = 0xc0; // 0xdbdc表示0xc0ecc = ecc^0xc0;db = 0;break;default:return 0; // 帧错误,返回}i++;}switch(tmp) // 正常情况{case 0xc0: // 帧结束c0 = 1;break;case 0xdb: // 检测到转义字符db = 1;break;default: // 普通数据data_buf[i] = tmp; // 保存数据ecc = ecc^tmp; // 计算校验字节i++;}//if(i == __ERRLEN) // 帧超长,错误,返回if(i >=( __ERRLEN+1)) // 帧超长,错误,返回return 0;}/* 判断帧是否错误*/if(i<4) // 帧过短,错误,返回return 0;if(ecc != 0) // 校验错误,返回return 0;if(data_buf[0] != dev) // 非访问本机命令,错误,返回return 0;*type = data_buf[1]; // 获得命令字return 1; // 函数成功返回}/* 该函数发送一帧数据帧,参数type为命令字、len为数据长度、buf为要发送的数据内容*/void send_data(uchar type, uchar len, uchar *buf){uchar i;uchar ecc = 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<len; i++) // 发送数据{send_byte(*buf);ecc = ecc^(*buf);buf++;}send_byte(ecc); // 发送校验字节TI = 0; // 发送帧结束标志SBUF = 0xc0;while(!TI);TI = 0;}/* 该函数发送一个数据字节,若该字节为0xdb,则发送0xdbdd,若该字节为0xc0则,发送0xdbdc */void send_byte(uchar da){switch(da){case 0xdb: // 字节为0xdb,发送0xdbdd TI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdd;while(!TI)TI = 0;break;case 0xc0: // 字节为0xc0,发送0xdbdcTI = 0;SBUF = 0xdb;while(!TI);TI = 0;SBUF = 0xdc;while(!TI)TI = 0;break;default: // 普通数据则直接发送TI = 0;SBUF = da;while(!TI);TI = 0;}}#endif/* 调试结果*/。
实验一实验板点对点通信【实验目的】1. 建立双机通信的概念2. 掌握单片机串行口通信的编程和调试方法。
3. 掌握异步串行通信的数据格式及数据协议设定。
【实验环境】PC机一台,keil开发环境一套,RS232通信线【实验重点及难点】串行口通信的程序的设计,以及硬件的连接数据通信的协议等。
【实验原理介绍】1.1 程序下载方式介绍1.1.1 RS232与上位机通信下载程序由于要从上位机中下载程序到单片机中,所以需要建立他们之间的通信线路。
本实验采用MAX232芯片,max232是一种把电脑的串行口rs232信号电平(-10 ,+10v)转换为单片机所用到的TTL信号点平(0 ,+5)的芯片,下面介绍一下max232引脚图,看下面的图。
图3.1 max232引脚图本实验中采用11、12、13、14号管脚作输入输出,其中13、14与DB9连接,11、12与单片机连接。
1.1.2 485通信485通信的过程如下:从DB9接收数据,经过max485芯片实现电平转换,然后max485芯片经过高速光耦与单片机通信,将数据送入单片机中进行处理;处理完成后将数据返回至max485,再经DB9输出。
如此就可实现两单片机之间的通信或单片机与上位机间的通信。
下面介绍一下max485芯片接线方法,如下图示:图2 max485接线图其中1、4为输入输出管脚,经光耦与单片机连接,2、3为使能端,6、7为与外部通信接口。
1.2 MCU功能介绍本实验中选择stc12c5a60s2系列单片机,其管脚图如下:图3 tc12c5a60s2单片机管脚图stc12c5a60s2系列单片机是单时钟的单片机,增强型8051内核,速度比普通8051快8~12倍,宽电压:5.5~3.5V,2.2~3.8V,低功耗设计:空闲模式,掉电模式,工作频率:0~35MHz.时钟:外部晶体或内部RC振荡器可选,在ISP下载编程用户程序时设置。
全双工异步串行口,兼容8051的串口。
专业课程设计任务书2013-2014 学年第 2 学期第 16 周- 19 周题目基于RS-485的单片机通信系统设计内容及要求1.利用RS485实现单片机的双向通讯;2.通过键盘实现从机的选择、发送数据的输入;3.主机显示发送的数据及从机编号。
4提高要求:通过键盘实现循环工作模式、指定从机这2种工作方式的切换。
进度安排16周:查找资料,进行系统硬件设计、软件方案设计;17周:硬件制作、软件的分模块调试;19周:系统联调;19周:设计结果验收,报告初稿的撰写。
学生姓名:11042104万娇 11042109赵佳慧指导时间:周一、周三、周五指导地点:E楼 610室任务下达2014年 6 月 3 日任务完成2014年 6月 27 日考核方式 1.评阅□ 2.答辩□ 3.实际操作□ 4.其它□指导教师张小林系(部)主任注:1、此表一组一表二份,课程设计小组组长一份;任课教师授课时自带一份备查。
2、课程设计结束后与“课程设计小结”、“学生成绩单”一并交院教务存档。
摘要串口通信是一种广泛应用于各个领域的通信方式,在远距离数据传输和控制系统中,可以根据RS-485协议实现远距离传输。
此次课设即利用MAX485芯片实现半双工串行通信的双向通信系统。
系统主要由主机控制模块、通信模块、数据输入模块、数据显示模块和模数转换模块五个部分组成,实现了利用RS-485实现单片机的双向通信,通过键盘实现从机的选择、发送数据,主机显示发送的数据及从机编号,通过键盘实现循环工作模式、指定从机这两种工作方式的切换。
此系统具有使用方便、操作简单、便于实现、成本低、可靠性高、可拓展性强、易于维护等特点,具有较广泛的应用前景。
关键字:单片机;RS-485总线;串行通信;数模转换目录前言 0第一章设计内容及要求 (1)1.1设计内容 (1)1.2设计要求 (1)第二章系统组成及工作原理 (2)2.1系统组成 (2)2.2 工作原理 (2)第三章硬件电路方案设计 (3)3.1 主机控制模块 (3)3.2 数据显示模块 (4)3.3 模数转换模块 (5)3.4 键盘输入模块 (6)3.5 通信模块 (7)3.5.1 RS485通信协议 (8)3.5.2 RS485通信格式 (8)3.6从机控制模块 (9)3.6.1 单片机最小系统 (9)3.6.2 显示模块 (10)第四章软件设计 (11)4.1 通信协议 (11)4.1.1 串行通信协议的比较——RS232 RS422 RS485 (11)4.1.2 通信过程 (13)4.2 主机程序 (13)4.2.1 主程序流程图 (13)4.2.2 矩阵键盘输入子程序 (14)4.2.3 数码管显示子程序 (15)4.2.4 传输模块子程序 (16)4.3 从机程序 (16)4.3.1从机总流程图 (16)4.3.2 接收并显示子程序 (17)第五章实验调试和测试结果与分析 (18)第六章结论 (19)第七章参考文献 (20)附录一电路图 (21)附录二程序代码 (22)前言单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统。
485通讯协议程序怎么写(51单片机的485通信程序案例)
RS-485总线接口是一种常用的串口,具有网络连接方便、抗干扰性能好、传输距离远等优点。
RS-485收发器采用平衡发送和差分接收,因此具有抑制共模干扰的能力,加上收发器具有高的灵敏度,能检测到低达200mv的电压,可靠通信的传输距离可达数千米。
使用RS-485总线组网,只需一对双绞线就可实现多系统联网构成分布式系统、设备简单、价格低廉、通信距离长。
51单片机的485通信程序
#ifndef __485_C__ #define __485_C__
#include 《reg51.h》
#include 《string.h》
#define unsigned char uchar
#define unsigned int uint
/* 通信命令*/
#define __ACTIVE_ 0x01 // 主机询问从机是否存在
#define __GETDATA_ 0x02 // 主机发送读设备请求
#define __OK_ 0x03 // 从机应答
#define __STATUS_ 0x04 // 从机发送设备状态信息
#define __MAXSIZE 0x08 // 缓冲区长度
#define __ERRLEN 12 // 任何通信帧长度超过12则表示出错
uchar dbuf[__MAXSIZE]; // 该缓冲区用于保存设备状态信息
uchar dev; // 该字节用于保存本机设备号
sbit M_DE = P1。
附录一、主机源程序
#include <reg52.H>
unsigned char xdata table[5];
unsigned char code tab[]={0x03,0x9f,0x25,0x0d,
0x99,0x49,0x41,0x1f,
0x01,0x09,0x05,0xc1,
0x63,0x85,0x61,0x71,0xff}; sbit ctrl=P1^2;
sbit DATA=P1^0;
sbit CLK=P1^1;
void show(unsigned char m)//LED显示子程序
{
unsigned char i,d;
d=tab[m];
for(i=0;i<8;i++)
{
DATA=d&0x01;
CLK=0;
CLK=1;
d=d>>1;
}
}
void interrupt0(void) interrupt 0 using 0//串行中断程序{
unsigned char cm0,cm1,sum0,sum1,i;
lab:
sum0=0;
ctrl=1;//将MAX485设置为发送方式
SBUF=0xFF;//发送数据申请
while(TI!=1);
ctrl=0; //将MAX485设置为接收方式
TI=0;
while(RI!=1);
cm0=SBUF;//接收申请确认信号
RI=0;
if(cm0==0xff)
{
i=0;
ctrl=0;
while(RI!=1);
cm1=SBUF; //接收第一个数据
RI=0;
while(cm1!=0xf0)
{
table[i]=cm1;
while(RI!=1);
cm1=SBUF;//接收后续的数据
RI=0;
i++;
}
for(i=0;i<4;i++)
sum0=sum0+table[i];//计算校验和
sum1=table[4];//获取收到的校验和
if(sum0==sum1)
{
ctrl=1;
SBUF=0xf0; //发送数据确认信号
while(TI!=1);
TI=0;
for(i=0;i<4;i++)
show(table[i]);
}
else goto lab;
}
else goto lab;
ctrl=1;//将MAX485设置为发送方式return ;
}
void main(void)
{
SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1 定时方式2 PCON=0x80; //设SMOD=1;
TH1 = 0xFA; //11.0592MHz 9600 波特率TL1 = 0xFA;
TR1 = 1; //启动定时器
EX0=1; //开外部中断0
IT0=0;
EA=1; //开总中断
ctrl=1;//将MAX485设置为发送方式while(1); //等待中断
}
附录二、从机源程序
#include <reg52.H>
unsigned char xdata table[]={0,0,0,0};
sbit replay=P1^0;
sbit warn0=P1^1;
sbit CTRL=P1^2;
sbit DATA=P1^3;
sbit CLK=P1^4;
unsigned char code tab[]={0x03,0x9f,0x25,0x0d, //显示用的码表
0x99,0x49,0x41,0x1f,
0x01,0x09,0x05,0xc1,
0x63,0x85,0x61,0x71,0xff};
void delay(void) //键盘扫描延时10ms程序
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void show(unsigned char m)//LED显示子程序
{
unsigned char i,d;
d=tab[m];
for(i=0;i<8;i++)
{
DATA=d&0x01;
CLK=0;
CLK=1;
d=d>>1;
}
}
void ser(void) interrupt 4 using 0//串行中断程序
{
unsigned char cm,sum,i;
sum=0;
replay=1;
warn0=1;
cm=SBUF;
RI=0;
if(cm==0xf0)//判断是否为主机返回的确认信号
{
replay=0; //表示已正确发送完一组数据
goto end;
}
else
if(cm!=0xff)//判断是否为主机的数据申请
{
warn0=0; //通信命令错误提示
goto end;
}
else
{
CTRL=1; //置MAX485为发送方式
SBUF=0xff;//发送申请确认信号
while(TI!=1);
TI=0;
for(i=0;i<4;i++)
{
SBUF=table[i]; //发送数据
while(TI!=1);
TI=0;
sum=sum+table[i];//计算校验和
}
SBUF=sum; //发送校验和
while(TI!=1);
TI=0;
SBUF=0xf0;//发送结束标志
while(TI!=1);
TI=0;
}
end: CTRL=0; //置MAX485为接收方式return;
}
void main(void)
{
unsigned char key,X,Y,temp;
SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1 定时方式2 PCON=0x80; //设SMOD=1;
TH1 = 0xFA; //11.0592MHz 9600 波特率TL1 = 0xFA;
TR1 = 1; //启动定时器
ES=1; //开串行中断
EA=1; //开总中断
CTRL=0; //置MAX485为接收方式replay=1;
warn0=1;
while(1) //键盘扫描
{
P2=0xff; //键盘初始化
P2=0xf0;
if (P2!=0xf0)
{
delay(); //延时去抖
if (P2!=0xf0)
{
X=P2; //读键盘
P2=0x0f;
Y=P2;
P2=X|Y;
temp=P2;
switch(temp)
{
case 0xee:key=0;break;
case 0xde:key=1;break;
case 0xbe:key=2;break;
case 0x7e:key=3;break;
case 0xed:key=4;break;
case 0xdd:key=5;break;
case 0xbd:key=6;break;
case 0x7d:key=7;break;
case 0xeb:key=8;break;
case 0xdb:key=9;break;
case 0xbb:key=10;break;
case 0x7b:key=11;break;
case 0xe7:key=12;break;
case 0xd7:key=13;break;
case 0xb7:key=14;break;
case 0x77:key=15;break;
}
for(X=0;X<4;X++) //存储最近读的按键码
table[X]=table[X+1];
table[3]=key;
P2=0xf0;
temp=P2;
for(X=0;X<4;X++)
show(table[X]);
while(temp!=0xf0)
{P2=0xf0;temp=P2;}
}
}
else key=16;
}
}
附录三、电路原理图
显示部分电路
主要部分电路。