51单片机串行口中断服务程序

合集下载

关于51系列单片机中断嵌套

关于51系列单片机中断嵌套

说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。

现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。

在说到中断之前,我先来定义一下优先级,明白了什么是优先级,后面的阐述就容易明白了。

实际上很多人都是混淆了优先级的含义,所以才觉得糊里糊涂。

中断的优先级有两个:查询优先级和执行优先级。

什么是查询优级呢?我们从datasheet或书上看到的默认(IP寄存器不做设置,上电复位后为00H)的优先级:外部中断0 > 定时/计数器0 > 外部中断1 > 定时/计数器1 > 串行中断或int0,timer0,int1,timer1,serial port 或INT0、T0、INT1、T1、UART或PX0>PT0>PX1>PT1>PS>......其实都是查询优级。

首先查询优先级是不可以更改和设置的。

这是一个中断优先权排队的问题。

是指多个中断源同时产生中断信号时,中断仲裁器选择对哪个中断源优先处理的顺序。

而这与是否发生中断服务程序的嵌套毫不相干。

当CPU查询各个中断标志位的时候,会依照上述5个查询优先级顺序依次查询,当数个中断同时请求的时候,会优先查询到高优查询先级的中断标志位,但并不代表高查询优先级的中断可以打断已经并且正在执行的低查询优先级的中断服务。

例如:当计数器0中断和外部中断1(按查询优先级,计数器0中断>外部中断1)同时到达时,会进入计时器0的中断服务函数;但是在外部中断1的中断服务函数正在服务的情况下,这时候任何中断都是打断不了它的,包括逻辑优先级比它高的外部中断0计数器0中断。

而中断的执行优先级就是你对IP寄存器的设置了。

在2个优先级的情况下,某位为1,则相应的中断源为高优先级;为0,则为低优先级。

关于中断的优先级有三条原则:1、CPU同时接收到几个中断时,首先响应优先级最高的中断请求;2、正在进行的中断过程不能被新的同级或低行优优先级的中断请求所中断;3、正在进行的低行优优先级中断服务,能被高行优优先级中断请求中断;若:同一执行优先级中的中断申请不止一个时,则有一个中断优先权排队问题。

MCS-51系列单片机的中断系统

MCS-51系列单片机的中断系统
单片机原理与接口技术
大连理工大学出版社
第5章 中断
当断不断必受其乱
第5章 中断系统
5.1 概述 MCS-51系列单片机的中断系统 5.2 MCS-51系列单片机的中断系统 5.3 中断程序设计方法
第5 章
中断系统
中断控制是单片机最重要的技术之一, 实时控制及人机交互等应用都是通过中 断实现的。 本章主要介绍中断的基本概念、MCS-51 系列单片机单片机的中断机制及其简单 应用。
5.2.2中断控制 5.2.2中断控制
1.中断允许 MCS-51系列单片机中断系统通过中断允许控制 寄存器IE实现开中断和关中断的功能。 (1)IE寄存器 IE寄存器由一个中断允许总控制位和各中断源 的中断允许控制位构成,从而进行两级中断允 许控制。IE寄存器的各位定义如下:
5.2.2中断控制 IE寄存器
5.2.2中断控制 IE寄存器
EX1(IE.2)——外中断1的中断允许控 制位。中断总允许时,EX1=0,禁止外中 断1中断;EX1=1,允许外中断1中断。 ET1(IE.3)——定时器T1的中断允许控 制位。中断总允许时,EX1=0,禁止T1中 断;ET1=1,允许T1中断。
5.2.2中断控制 5.2.2中断控制 IE寄存器
5.2.1中断源和中断标志
当MCS-51系列单片机的外中断源以脉冲方式触 发时,负脉冲有效。CPU在一个机器周期采样到 INT0(或者 INT1 )引脚上为高电平,在接下 来的一个机器周期采样到INT0(或者INT1)引 脚上是低电平,即出现了下降沿的跳变(负脉 冲)时,就认为是外中断0(或者外中断1)的 一个有效的中断请求信号。因为两次检测的间 隔时间为一个机器周期,负脉冲对应的高低电 平持续时间都应至少维持一个机器周期,从而 保证CPU能够检测到电平的跳变。

MCS-51单片机的中断系统

MCS-51单片机的中断系统

MCS-51单⽚机的中断系统单⽚机中断技术概述在任何⼀款事件驱动型的CPU⾥⾯都应该会有中断系统,因为中断就是为响应某种事件⽽存在的。

中断的灵活应⽤不仅能够实现想要的功能,⽽且合理的中断安排可以提⾼事件执⾏的效率,因此中断在单⽚机应⽤中的地位是⾮常重要的。

单⽚机中断(Interrupt)是硬件驱动事件,它使得CPU暂停当前的主程序,转⽽去执⾏⼀个中断服务⼦程序。

为了更形象地理解中断,下⾯以学⽣上⾃习时接电话为例阐述⼀下中断的概念。

单⽚机的中断系统有5个中断源、2个中断优先级,可实现两级中断服务程序嵌套。

如果单⽚机没有中断系统,单⽚机的⼤量时间可能会浪费在查询是否有服务请求发⽣的定时査询操作上。

采⽤中断技术完全消除了单⽚机在査询⽅式中的等待现象,⼤⼤地提⾼了单⽚机的⼯作效率和实时性。

单⽚机中断系统结构及中断控制中断系统结构图如图5-2所⽰。

由图5-2可见,MCS-51中断系统共有5个中断请求源:INT0——外部中断请求0,中断请求信号由INT0引脚输⼊。

定时/计数器T0计数溢出发出的中断请求。

INT1——外部中断请求1,中断请求信号由INT1引脚输⼊。

定时/计数器T1计数溢出发出的中断请求。

串⾏⼝中断请求。

中断优先级从⾼到底排列。

单⽚机如何知道有中断请求信号?是否能够响应该中断?若5个中断源请求信号同时到来,单⽚机如何响应?这些问题都可以由中断寄存器来解决。

单⽚机中断寄存器有中断标志寄存器TCON和SCON、中断使能寄存器IE和中断优先级寄存器IP,这些寄存器均为8位。

中断标志寄存器5个中断请求源的中断请求标志分别由TCON和SCON的相应位锁存,单⽚机通过这些中断标志位的状态便能知道具体是哪个中断源正在申请中断。

TCON寄存器TCON寄存器为定时/计数器的控制寄存器,字节地址为88H,可位寻址。

特殊功能寄存器TCON的格式如图5-3所⽰。

TCON各标志位功能如下。

TF1——定时/计数器T1的溢出中断请求标志位。

AT89S51单片机串行口的内部结构及工作原理介绍

AT89S51单片机串行口的内部结构及工作原理介绍

AT89S51单片机串行口的内部结构及工作原理介绍AT89S51单片机串行口的内部结构如下图所示。

它有两个物理上独立的接收、发送缓冲器SBUF(属于特殊功能寄存器),可同时发送、接收数据。

发送缓冲器只能写入不能读出,接收缓冲器只能读出不能写入,两个缓冲器共用一个特殊功能寄存器字节地址(99H)。

串行口的控制寄存器共有两个:特殊功能寄存器SCON 和PCON。

下面介绍这两个特殊功能寄存器各位的功能。

1、串行口控制寄存器SCON串行口控制寄存器SCON,字节地址988H,可位寻址,位地址为98H~9FH。

SCON的格式如下图所示。

下面介绍SCON中各位的功能。

(1) SM0、SMl:串行口4种工作方式选择位。

SM0、SM1两位的编码所对应的4种工作方式见下表。

表串行口的4种工作方式(2) SM2:多机通信控制位。

因为多机通信是在方式2和方式3下进行的,因此SM2位主要用于方式2或方式3中。

当串行口以方式2或方式3接收时,如果SM2=1,则只有当接收到的第9位数据(RB8)为1时,才使RI置l,产生中断请求,并将接收到的前8位数据送人SBUF;当接收到的第9位数据(RB8)为0时,则将接收到的前8位数据丢弃。

而当SM2=0时,则不论第9位数据是l还是0,都将前8位数据送入SBUF中,并使RI置1,产生中断请求。

在方式1时,如果SM2=1,则只有收到有效的停止位时才会激活RI。

在方式0时,SM2必须为0。

(3)REN:允许串行接收位。

由软件置1或清0。

REN=1,允许串行口接收数据。

REN=O,禁止串行口接收数据。

(4)TB8:发送的第9位数据。

在方式2和方式3时,TB8是要发送的第9位数据,其值由软件置l或清O。

在双机串行通信时,TB8一般作为奇偶校验位使用;在多机串行通信中用来表示主机发送的是地址帧还是数据帧,TB8=1为地址帧,TB8=0为数据帧。

(5) RB8:接收的第9位数据。

工作在方式2和方式3时,RB8存放接收到的第9位数据。

51单片机串口通信程序。。含详细例子

51单片机串口通信程序。。含详细例子
while(RI == 0); RI = 0; c = SBUF; // 从缓冲区中把接收的字符放入 c 中 SBUF = c; // 要发送的字符放入缓冲区 while(TI == 0); TI = 0; } }
4.//////////////// /////////////////////////////////////////////////////////
pw.fpReadSign(); SendData();//通知上位机,送出读出器件特征字 }
void Erase()//擦除器件 {
pw.fpErase(); SendData();//通知上位机,擦除了器件 }
void Write()//写器件 {
BYTE n; pw.fpInitPro();//编程前的准备工作 SendData();//回应上位机表示进入写器件状态,
{
unsigned char c;
TMOD = 0x20; // 定时器 1 工作于 8 位自动重载模式, 用于产生波特率
TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); SCON = 0x50; PCON = 0x00; TR1 = 1; IE = 0x00; // 禁止任何中断 while(1) {
///////////////////////////////////////////////////////////////////////////////// //所支持的 FID,请在这里继续添加
///////////////////////////////////////////////////////////////////////////// extern void PreparePro00();//FID=00:AT89C51 编程器 extern void PreparePro01();//FID=01:AT89C2051 编程器 extern void PreparePro02();//FID=02:AT89S51 编程器

51单片机中断程序大全

51单片机中断程序大全

//实例42:用定时器T0查询方式P2口8位控制LED闪烁#include<reg51.h> // 包含51单片机寄存器定义的头文件void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-46083)/256; //定时器T0的高8位赋初值TL0=(65536-46083)%256; //定时器T0的高8位赋初值{//实例43{// EA=1;//{while(TF1==0);TF1=0;sound=~sound; //将P3.7引脚输出电平取反TH1=(65536-921)/256; //定时器T0的高8位赋初值TL1=(65536-921)%256; //定时器T0的高8位赋初值}}//实例44:将计数器T0计数的结果送P1口8位LED显示#include<reg51.h> // 包含51单片机寄存器定义的头文件sbit S=P3^4; //将S位定义为P3.4引脚void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x02; //使用定时器T0的模式2TH0=256-156; //定时器T0的高8位赋初值TL0=256-156; //定时器T0的高8位赋初值TR0=1; //启动定时器T0while(1)//无限循环等待查询{while(TF0==0) //如果未计满就等待{if(S==0) //按键S按下接地,电平为0P1=TL0; //计数器TL0加1后送P1口显示}//实例45{EA=1;{}//实例46#include<reg51.h> // 包含51单片机寄存器定义的头文件sbit D1=P2^0; //将D1位定义为P2.0引脚unsigned char Countor; //设置全局变量,储存定时器T0中断次数void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式2TH0=(65536-46083)/256; //定时器T0的高8位赋初值TL0=(65536-46083)%256; //定时器T0的高8位赋初值TR0=1; //启动定时器T0Countor=0; //从0开始累计中断次数while(1);}/************************************************************** 函数功能:定时器T0的中断服务程序**************************************************************/ void Time0(void) interrupt 1 using 0{Countor++; //中断次数自加1if(Countor==20) //若累计满20次,即计时满1s{D1=~D1; //按位取反操作,将P2.0引脚输出电平取反Countor=0; //将Countor清0,重新从0开始计数}//实例47{EA=1;}{Countor2++; //Countor2自加1if(Countor1==2) //若累计满2次,即计时满100ms{D1=~D1; //按位取反操作,将P2.0引脚输出电平取反Countor1=0; //将Countor1清0,重新从0开始计数}if(Countor2==8) //若累计满8次,即计时满400ms{D2=~D2; //按位取反操作,将P2.1引脚输出电平取反Countor2=0; //将Countor1清0,重新从0开始计数}TH1=(65536-46083)/256; //定时器T1的高8位重新赋初值TL1=(65536-46083)%256; //定时器T1的高8位重新赋初值}//实例50-1:输出50个矩形脉冲#include<reg51.h> //包含51单片机寄存器定义的头文件sbit u=P1^4; //将u位定义为P1.4/*************************************************函数功能:延时约30ms (3*100*100=30 000μs =30m*************************************************/void delay30ms(void){ unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<100;n++);}{u=1;//实例{//实例51-2#include<reg51.h> //包含51单片机寄存器定义的头文件sbit ui=P3^2; //将ui位定义为P3.0(INT0)引脚,表示输入电压void main(void){TMOD=0x0a; // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1 EA=1; //开总中断ET0=0; //不使用定时器T0的中断TR0=1; //启动T0TH0=0; //计数器T0高8位赋初值TL0=0; //计数器T0低8位赋初值while(1) //无限循环,不停地将TL0计数结果送P1口{while(ui==0) : //INT0为低电平,T0不能启动TL0=0; //INT0为高电平,启动T0计时,所以将TL0清0 while(ui==1): //在INT0高电平期间,等待,计时P1=TL0; //将计时结果送P1口显示} }//实例53:用外中断0的中断方式进行数据采集#include<reg51.h> //包含51单片机寄存器定义的头文件sbit S=P3^2; //将S位定义为P3.2,void main(void){EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断P1=0xff;{P1=~P1;//实例54-1sbit u=P1^4;{EA=1;{u=~u; //}//实例54-2sbit u=P3^2;{TMOD=0x02; //TMOD=0000 0010B,使用定时器T0的模式2EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断ET0=1; //允许定时器T0中断TH0=0; //定时器T0赋初值0TL0=0; //定时器T0赋初值0TR0=0; //先关闭T0while(1) ; //无限循环,不停检测输入负脉冲宽度}void int0(void) interrupt 0 using 0 //外中断0的中断编号为0{ TR0=1; //外中断一到来,即启动T0计时TL0=0; //从0开始计时while(u==0) //低电平时,等待T0计时;P1=TL0; //将结果送P1口显示TR0=0; //关闭T0}//实例55:方式0控制流水灯循环点亮#include<reg51.h> //包含51单片机寄存器定义的头文件#include<intrins.h> //包含函数_nop_()定义的头文件unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码,该数组被定义为全局变量sbit P17=P1^7;/**************************************************************{{P17=0;_nop_();_nop_();P17=1;;TI=0; //}******************************************/void main(void){unsigned char i;SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0while(1){for(i=0;i<8;i++){Send(Tab[i]); //发送数据delay(); //延时}}}。

51单片机串口通信程序。。含详细例子

51单片机串口通信程序。。含详细例子

{ P3_4=0; P3_3=1;
} void RstPro()//编程器复位 {
pw.fpProOver();//直接编程结束 SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同 }
void ReadSign()//读特征字 {
} void serial () interrupt 4 using 3 //串口接收中断函数 {
if (RI) { RI = 0 ; ch=SBUF; read_flag= 1 ; //就置位取数标志 }
} main()
{ init_serialcom(); //初始化串口 while ( 1 ) { if (read_flag) //如果取数标志已置位,就将读到的数从串口发出 { read_flag= 0 ; //取数标志清 0 send_char_com(ch); } }
while(RI == 0); RI = 0; c = SBUF; // 从缓冲区中把接收的字符放入 c 中 SBUF = c; // 要发送的字符放入缓冲区 while(TI == 0); TI = 0; } }
4.//////////////// /////////////////////////////////////////////////////////
SendData(); } else break;//等待回应失败 } pw.fpProOver();//操作结束设置为运行状态 ComBuf[0]=0;//通知上位机编程器进入就绪状态 SendData(); }
void Lock()//写锁定位
{
pw.fpLock();
SendData();

第3章MCS-51单片机的中断系统

第3章MCS-51单片机的中断系统
某人看书执行主程序日常事务电话铃响中断信号int0中断请求暂停看书暂停执行主程序中断响应书中作记号当前pc入栈保护断点电话谈话执行io程序中断服务继续看书返回主程序中断返回执行主程序主程序继续执行主程序断点中断请求中断响应执行中断处理程序中断返回中断与转子的区别中断是随机的转子事先编程决定断点
3.3 MCS-51的中断系统 的中断系统
4、中断响应过程 、 关中断:屏蔽其它中断请求信号。 关中断:屏蔽其它中断请求信号。 保护断点:将断点地址压入堆栈保存,即当前 值入栈 值入栈。 保护断点:将断点地址压入堆栈保存,即当前PC值入栈。 寻找中断源:中断服务程序入口地址送 ,转入中断服务。 寻找中断源:中断服务程序入口地址送PC,转入中断服务。 保护现场:将中断服务程序使用的所有寄存器内容入栈。 保护现场:将中断服务程序使用的所有寄存器内容入栈。 中断处理:执行中断源所要求的程序段。 中断处理:执行中断源所要求的程序段。 恢复现场:恢复被使用寄存器的原有内容。 恢复现场:恢复被使用寄存器的原有内容。 开中断:允许接受其它中断请求信号。 开中断:允许接受其它中断请求信号。 中断返回:执行 指令, 中断返回:执行RETI指令,栈顶内容 指令 栈顶内容→PC,程序跳转回断点。 ,程序跳转回断点。
当前PC入栈 书中作记号 当前 入栈
主程序 执行主程序 中断请求 断点 继续执行主程序 中断返回 执行中断 处理程序 中断响应
中断与转子的区别 中断是随机的, 中断是随机的,转子事先编程决定
3.3.1 中断的定义 2、几个术语 、 主程序:原来正常运行的程序称为主程序。 主程序:原来正常运行的程序称为主程序。 断点: 主程序被断开的位置(或地址)称为“断点” 断点 主程序被断开的位置(或地址)称为“断点”。 中断源:引起中断的原因,或发出中断申请的来源。 中断源 引起中断的原因,或发出中断申请的来源。 引起中断的原因 中断请求:中断源要求服务的请求称为“中断请求” 中断请求 中断源要求服务的请求称为“中断请求” 。 中断源要求服务的请求称为 中断响应: 终止当前执行的程序, 中断响应:CPU终止当前执行的程序,去执行相应中断源 终止当前执行的程序 的中断请求。 的中断请求。 中断服务或中断处理程序: 中断服务或中断处理程序: “中断”之后所执行的相应的处理程序。 中断”之后所执行的相应的处理程序。 中断系统:能够实现中断处理功能的部件。 中断系统:能够实现中断处理功能的部件。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机串行口中断服务程序----------------------------------------------------------------------------//串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理//编程:聂小猛。

该资料来自“51单片机世界”/~dz2000,欢迎访问。

//出入均设有缓冲区,大小可任意设置。

//可供使用的函数名://char getbyte(void);从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。

//getline(char idata *line, unsigned char n); 获取一行数据回车结束,已处理backspce和delete,必须定义最大输入字符数//putinbuf(uchar c);模拟接收到一个数据//putbyte(char c);放入一个字节到发送缓冲区//putbytes(unsigned char *outplace,j);放一串数据到发送缓冲区,自定义长度//putstring(unsigned char code *puts);发送一个字符串到串口//puthex(unsigned char c);发送一个字节的hex码,分成两个字节发。

//putchar(uchar c,uchar j);发送一个字节数据的asc码表达方式,需要定义小数点的位置//putint(uint ui,uchar j);发送一个整型数据的asc码表达方式,需要定义小数点的位置//CR;发送一个回车换行//*************************************************************************#include <w77e58.h> //该头文件包括了51,52,80320的特殊寄存器,用在51,52上也可#define uchar unsignedchar #define uint unsigned int #define OLEN 64/* size of serial transmission buffer */idata unsigned char outbuf[OLEN];/* storage for transmission buffer */unsigned char idata *outlast=outbuf; //最后由中断传输出去的字节位置unsigned char idata *putlast=outbuf;//最后放入发送缓冲区的字节位置#define ILEN 2 /* size of serial receiving buffer */idata unsigned char inbuf[ILEN];unsigned char idata *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置 unsignedchar idata *getlast=inbuf; //最后取走的字节位置 bit outbufsign; //输出缓冲区非空标志有=1 bit inbufsign;//接收缓冲区非空标志有=1bit inbufful;//输入缓冲区满标志满=1#define CR putstring("\r\n") //CR=回车换行//*****************************//放入一个字节到发送缓冲区putbyte(char c) {uchar i,j; ES=0;/*暂停串行中断,以免数据比较时出错? */if (outlast==putlast ){ i=(0-TH1);do{i--;j=36;do {j--;}while(j!=0);}while(i!=0);//延时一个字节发送时间}*putlast=c; //放字节进入缓冲区putlast++; //发送缓冲区指针加一 if(putlast==outbuf+OLEN) putlast=outbuf; //指针到了顶部换到底部if (!outbufsign){outbufsign=1;TI=1;} //缓冲区开始为空置为有,启动发送ES=1; }//****************************** //放一串数据到发送缓冲区putbytes(unsigned char *outplace,unsigned char j){ int i; for(i=0;i<j;i++){putbyte(*outplace);outplace++;}}//******************************//putchar(uchar c,uchar j);发送一个字节数据的asc码表达方式,需要定义小数点的位置putchar(uchar c,uchar j){uchar idata free[4];uchar data i;i=0;free[i++]=(c/100+0x30);if (j==3) free[i++]='.';free[i++]=(c%100)/10+0x30;if (j==2) free[i++]='.';if (j==2 && free[i-3]==0x30) free[i-3]=0x20;free[i++]=(c%10)+0x30;if (j==1 && free[i-3]==0x30) free[i-3]=0x20;if (j==1 && free[i-3]==0x20 && free[i-2]==0x30) free[i-2]=0x20;putbytes(free,i);}//******************************//putint(uint ui,uchar j);发送一个整型数据的asc码表达方式,需要定义小数点的位置putint(uint ui,uchar j){uchar idata free[6];uchar data i;//i=0;free[i++]=(ui/10000+0x30);if (j==5) free[i++]='.';free[i++]=((ui%10000)/1000+0x30);if (j==4) free[i++]='.';if (j==4 && free[i-3]==0x30) free[i-3]=0x20;free[i++]=((ui%1000)/100+0x30);if (j==3) free[i++]='.';if (j==3 && free[i-4]==0x30) free[i-4]=0x20;if (j==3 && free[i-4]==0x20 && free[i-3]==0x30) free[i-3]=0x20;free[i++]=((ui%100)/10+0x30);if (j==2) free[i++]='.';if (j==2 && free[i-5]==0x30) free[i-5]=0x20;if (j==2 && free[i-5]==0x20 && free[i-4]==0x30) free[i-4]=0x20;if (j==2 && free[i-5]==0x20 && free[i-4]==0x20 && free[i-3]==0x30) free[i-3]=0x20;free[i++]=(ui%10+0x30);if (j==1 && free[i-5]==0x30) free[i-5]=0x20;if (j==1 && free[i-5]==0x20 && free[i-4]==0x30) free[i-4]=0x20;if (j==1 && free[i-5]==0x20 && free[i-4]==0x20 && free[i-3]==0x30) free[i-3]=0x20;if (j==1 && free[i-5]==0x20 && free[i-4]==0x20 && free[i-3]==0x20 && free[i-2]==0x30) free[i-2]=0x20; putbytes(free,i);}//***************************************//发送一个字符串到串口putstring(unsigned char *puts){for (;*puts!=0;puts++) //遇到停止符0结束putbyte(*puts);}//*************************************//发送一个字节的hex码,分成两个字节发。

unsigned char code hex_[]={"0123456789ABCDEF"};puthex(unsigned char c){int ch;ch=(c>>4)&0x0f; putbyte(hex_[ch]); ch=c&0x0f; putbyte(hex_[ch]); } //************************************* //从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。

uchar getbyte (void){ char idata c; while (!inbufsign); //缓冲区空等待ES=0; c= *getlast; //取数据getlast++; //最后取走的数据位置加一inbufful=0; //输入缓冲区的满标志清零if (getlast==inbuf+ILEN) getlast=inbuf; //地址到顶部回到底部if (getlast==inlast) inbufsign=0; //地址相等置接收缓冲区空空标志,再取数前要检该标志ES=1; return (c);//取回数据 }//***************************************** //接收一行数据,必须定义放数据串的指针位置和大小del=0x7f,backspace=0x08,cr=0x0d,lf=0x0avoid getline (uchar idata *line, unsigned char n){ unsigned char cnt = 0; //定义已接收的长度char c;do{ if ((c = getbyte ()) == 0x0d)c = 0x00; //读一个字节,如果是回车换成结束符if (c == 0x08 || c == 0x7f) //BACKSPACE 和 DEL 的处理{if (cnt != 0) //已经输入退掉一个字符{cnt--; //总数目减一line--; //指针减一putbyte (0x08); //屏幕回显的处理putbyte (' ');putbyte (0x08);}}else{ putbyte (*line = c);//其他字符取入,回显line++; //指针加一cnt++; //总数目加一}} while (cnt < n - 1 && c != 0x00 && c!=0x1b); //数目到了,回车或ESC停止*line = 0; //再加上停止符0 }//****************************//模拟接收到一个数据putinbuf(uchar c){ES=0; if(!inbufful){*inlast= c; //放入数据 inlast++;//最后放入的位置加一if (inlast==inbuf+ILEN)inlast=inbuf;//地址到顶部回到底部if (inlast==getlast)inbufful=1; //接收缓冲区满置满标志inbufsign=1;}ES=1;}//*****************************************//串口中断处理serial () interrupt 4 { if (TI ){TI = 0;if (outbufsign) //if (putlast==outlast)outbufsign=0; //else {SBUF=*outlast; //未发送完继续发送outlast++; //最后传出去的字节位置加一if (outlast==outbuf+OLEN)outlast=outbuf;//地址到顶部回到底部if (putlast==outlast)outbufsign=0; //数据发送完置发送缓冲区空标志}}if (RI){RI = 0; if(!inbufful){ *inlast= SBUF; //放入数据inlast++; //最后放入的位置加一inbufsign=1;if (inlast==inbuf+ILEN)inlast=inbuf;//地址到顶部回到底部if (inlast==getlast)inbufful=1; //接收缓冲区满置满标志}}}//*****************************//串口初始化 0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200 serial_init (){SCON = 0x50; /* mode 1: 8-bit UART, enable receiver */TMOD |= 0x20; /* timer 1 mode 2: 8-Bit reload */PCON |= 0x80;TH1 = 0xfd;//fa, //baud*2/* reload value 19200 baud */TR1 = 1; /* timer 1 run */ES = 1;REN=1;EA=1;SM2=1; //SM2=1时收到的第9位为1才置位RI标志//TMOD |=0x01; //th1 auto load 2X8,th0 1X16 //TH0=31;TL0=0; //X 32 =1S //TR0=1; ET0=1; }。

相关文档
最新文档