文档库 最新最全的文档下载
当前位置:文档库 › 发一个用串口命令单片机控制开关输出的小程序

发一个用串口命令单片机控制开关输出的小程序

发一个用串口命令单片机控制开关输出的小程序
发一个用串口命令单片机控制开关输出的小程序

发一个用串口命令单片机控制开关输出的小程序,如串口发送led0_open回车后,单片机点亮led0 程序波特率设为2400bps(12Mhz晶振),请根据需要自行修改

[attachment=2332028]

#include

#include "string.h"

sbit led0=P0^0; //定义led接口

sbit led1=P0^1; //同上

sbit led2=P0^2; //同上

sbit led3=P0^3; //同上

sbit led4=P0^4; //同上

sbit led5=P0^5; //同上

sbit led6=P0^6; //同上

sbit led7=P0^7; //同上

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXX

// 定义各种变量

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXX

unsigned char cmd_buf[40]; //串口命令的缓冲区

unsigned char data counter=0; //用于数据接收计数

unsigned char data flag=0; //命令接收结束标记,为1时说明接收到了个完整的命令,进入到主函数中进行解析和执行

/******************************************************************** ******

- 功能描述:51单片机的串口初始化

- 隶属模块:STC51串口操作

- 函数属性:外部,使用户使用

- 参数说明:无

- 返回说明:无

- 注:正确的初始化串口十分重要

******************************************************************** ******/

void Com_init()

{

/******************设定定时器*********************/

TMOD = 0x20; //设定定时器的工作方式(方式2)

TH1 = 0xf3; //设定波特率为9600 bps (在11.0592MHZ晶振时)

TL1 = 0xf3;

/*******************设定串口**********************/

SM0 = 0; //SM0 和SM1 设定串口的工作方式(方式1)

SM1 = 1;

REN = 1; //允许串口接收外部传来的数据

/******************设定中断**********************/

ES = 1; //允许串口收到数据后产生中断通知我们

EA = 1; //因为总中断开关是控制所有中断的,所以要把它打开

TR1 = 1; //启动定时器,串口就开始工作喽!

}

/******************************************************************** ******

- 功能描述:51单片机的串口发送字节的函数

- 隶属模块:STC51串口操作

- 函数属性:外部,使用户使用

- 参数说明:mydata:要发送的一个字节

- 返回说明:无

- 注:发送一个字节,是串口发送的基础操作

******************************************************************** ******/

void UART_Send_Byte(unsigned char mydata)

{

ES=0;

TI=0;

SBUF=mydata;

while(!TI);

TI=0;

ES=1;

}

/******************************************************************** ******

- 功能描述:51单片机的串口发送0d 0a ,即回车换行

- 隶属模块:STC51串口操作

- 函数属性:外部,使用户使用

- 参数说明:无

- 返回说明:无

- 注:此函数就是发送0d 0a这两个字节,在“超级终端”上会有回车换行的效果

******************************************************************** ******/

void UART_Send_Enter()

{

UART_Send_Byte(0x0d);

UART_Send_Byte(0x0a);

}

/******************************************************************** * 名称: UART_Send_Str(char *s)

* 功能: 串口发送一个字符串

* 输入: s:指向字符串数组的指针

* 输出: 无

********************************************************************

***/

void UART_Send_Str(char *s)

{

int len=strlen(s); //求字符串长度的

int i;

for(i=0;i

if(s=='\r')

{

UART_Send_Enter();

}

else

{

UART_Send_Byte(s);

}

}

/******************************************************************** * 名称: Com_send(unsigned char *p)

* 功能: 串口发送字符串

* 输入: p:指向字符串数组的指针

* 输出: 无

******************************************************************** ***/

void Com_send(unsigned char *p)

{

while(1)

{

SBUF = *p;

while(!TI); //如果发送完毕,硬件会置位TI

p++;

if(*p == '\0') break; //在每个字符串的最后,会有一个'\0'

TI = 0; //TI清零

}

}

/****************************************************************** - 功能描述:将一个32位的变量dat转为字符串,比如把1234转为"1234"

- 隶属模块:公开函数模块

- 函数属性:外部,用户可调用

- 参数说明:dat:带转的long型的变量

str:指向字符数组的指针,转换后的字节串放在其中

- 返回说明:无

******************************************************************/ void u32tostr(unsigned long dat,char *str)

{

char temp[20];

unsigned char i=0,j=0;

i=0;

while(dat)

{

temp=dat%10+0x30;

i++;

dat/=10;

}

j=i;

for(i=0;i

{

str=temp[j-i-1];

}

if(!i) {str[i++]='0';}

str=0;

}

/****************************************************************** - 功能描述:将一个字符串转为32位的变量,比如"1234"转为1234

- 隶属模块:公开函数模块

- 函数属性:外部,用户可调用

- 参数说明:str:指向待转换的字符串

- 返回说明:转换后的数值

******************************************************************/ unsigned long strtou32(char *str)

{

unsigned long temp=0;

unsigned long fact=1;

unsigned char len=strlen(str);

unsigned char i;

for(i=len;i>0;i--)

{

temp+=((str[i-1]-0x30)*fact);

fact*=10;

}

return temp;

}

/******************************************************************** ******

- 功能描述:51单片机的串口发送数值

- 隶属模块:STC51串口操作

- 函数属性:外部,使用户使用

- 参数说明:dat:要发送的数值

- 返回说明:无

- 注:函数中会将数值转为相应的字符串,发送出去。比如4567 转为"4567"

******************************************************************** ******/

void UART_Put_Num(unsigned long dat)

{

char idata temp[20]; //temp数组确定显示数字的位数

u32tostr(dat,temp); //转换数字到字符串的

UART_Send_Str(temp);

}

/******************************************************************** * 名称: UART_Put_Inf(char *inf,unsigned long dat)

* 功能: 串口发送一个字符串后面接着一串数字

* 输入: inf:指向字符串数组的指针dat:数字不能超过20位

* 输出: 无

******************************************************************** ***/

void UART_Put_Inf(char *inf,unsigned long dat)

{

UART_Send_Str(inf);

UART_Put_Num(dat);

UART_Send_Str("\r");

}

/******************************************************************** * 名称: unsigned char cmd_panduan(unsigned char *cmd_buf,unsigned char *cmd,unsigned char len)

* 功能: 在指定长度内比较两个字符串是否一致

* 输入: 指向字符串的指针cmd_buf,cmd 要比较的长度

* 输出: 是:输出1,否:输出0

********************************************************************/ unsigned char cmd_panduan(unsigned char *cmd_buf,unsigned char *cmd,unsigned char len)

{

unsigned char i,j;

for(j=0;j

{

i=(cmd_buf[j+1]==cmd[j]);

if(i)

{

i=1;

}

if(i==0)

{

i=0;

break;

}

}

j=0;

return i;

}

/******************************************************************** ******

- 功能描述:51单片机的串口中断处理函数

- 隶属模块:STC51串口操作

- 函数属性:外部,使用户使用(在此中断函数中常用来处理从串口收到的数据)

- 参数说明:无

- 返回说明:无

- 注:振南的很多产品,都是配合“超级终端”来进行演示的,在“超级终端”中

敲入的命令就是从计算机的串口发出,由单片机从串口接收,接收到的串口数据就在此中断函数中进行处理,完成命令接收及处理、命令解析等工作。

******************************************************************** ******/

void com_ser() interrupt 4 //串口中断处理函数,收到数据后产生中断,在这里处理

{

unsigned char data len=0; //命令字符串长度

if(RI) //如果数据已经接收完,即RI=1

{

RI=0; //对RI进行清零

cmd_buf[counter] = SBUF; //把收到的数据赋值给变量(注意接收的写法)

}

if(cmd_buf[counter]==0x0d) //如果串口输入回车,那么命令结束

{

cmd_buf[counter]='\0';

len=counter-1;

counter = 0;

flag=1;

}

else

counter = counter+1;

if(flag) //处理接收到的命令

{

if(cmd_panduan(cmd_buf,"led0_open",len))

{

led0=0;

UART_Send_Str("led0_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led0_close",len))

{

led0=1;

UART_Send_Str("led0_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led1_open",len)) {

led1=0;

UART_Send_Str("led1_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led1_close",len)) {

led1=1;

UART_Send_Str("led1_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led2_open",len)) {

led2=0;

UART_Send_Str("led2_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led2_close",len)) {

led2=1;

UART_Send_Str("led2_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led3_open",len)) {

led3=0;

UART_Send_Str("led3_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led3_close",len)) {

led3=1;

UART_Send_Str("led3_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led4_open",len)) {

led4=0;

UART_Send_Str("led4_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led4_close",len)) {

led4=1;

UART_Send_Str("led4_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led5_open",len)) {

led5=0;

UART_Send_Str("led5_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led5_close",len))

{

led5=1;

UART_Send_Str("led1_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led6_open",len))

{

led6=0;

UART_Send_Str("led6_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led6_close",len))

{

led6=1;

UART_Send_Str("led6_close OK!\r");

}

if(cmd_panduan(cmd_buf,"led7_open",len))

{

led7=0;

UART_Send_Str("led7_open OK!\r");

}

if(cmd_panduan(cmd_buf,"led7_close",len))

{

led7=1;

UART_Send_Str("led7_close OK!\r");

}

flag=0; //这里一定要将命令结束标记恢复置0

}

}

void main() //主函数

{

P0=0xff; //P0 I/O口置1,不输出控制信号(低电平输出控制信号) Com_init(); //初始化串口

while (1); //什么都不做,等待串口中断

}

用Visual Basic 实现串口通信的三种方法

网络用V isual Basic实现 串口通信的三种方法 ●赵海燕 目前,V isual Basic(简称V B)已成为WINDOWS系统开发的主要语言,以其高效、简单易学及功能强大的特点越来越为广大程序设计人员及用户所青睐。V B支持面向对象的程序设计,具有结构化的事件驱动编程模式并可以使用无限扩增的控件。在V B应用程序中可以方便地调用WINDOWS API 函数,使得编程效率提高,应用功能增强。 利用V B提供的这些功能,我们可以有三种方法完成串口通信。一种是用V B提供的具有强大功能的通信控件;另一种方法是调用WINDOWS API函数,使用WINDOWS提供的通信函数编写移植性强的应用程序;第三是利用文件的输入/输出完成,该方法简便易行,但有一定的局限性。 一、利用通信控件(MSCOMM)完成串口通信 V B提供了通信控件M SCOM M,文件名为M SCOM M.V BX。该控件可设置串行通信的数据发送和接收,对串口状态及串行通信的信息格式和协议进行设置。在通信过程中可以触发OnC omm事件,在该事件过程进行数据检验处理及检错,还可以通过编程访问C ommE vent属性来了解通信的情况,进行收发数据的处理。每个通信控件对应一个串口,如果要访问多个通信口,则要设计多个通信控件。 1.通信控件的事件及基本属性 (1)事件 OnC omm:通信控件只提供了一个事件,该事件的触发可以对串口的通信事件及错误进行处理。通过对C ommE vent属性的判断可知当前的通信错误和事件,分别对每个C om2 mE vent值进行编程就完成了对各个错误和事件的处理。如: C ommE vent=M SCOM M—EV—SEND表示发送事件。这些信息可从V B提供的常量文件CONST ANT.T XT中查出。 (2)属性 C ommP ort:设置通信控件与哪个串口相连接,设置并返回通信口号。 S ettin g:设置通信的信息格式,为字符型。顺序为:波特率、校验、数据位、停止位。 P ortO p en:布尔型、开关通信口。 In p utLen:从接收缓冲区读取字符个数。 In p ut,Out p ut:读取接收缓冲区或写入发送缓冲区字符。 以上五种属性对串口完成基本的设置和操作,下面的三种属性是描述如何利用V B提供的事件驱动机制来实现通信。 C ommE vent:返回通信过程中产生的错误信息及事件,了解通信状况。 ST hresh old:设置并返回不触发OnC omm事件时发送缓冲区被允许的最少字符数。当缓冲区的字符少于设置的值时,则触发OnC omm事件,并把C ommE vent设为M SCOM M M—EV—SEND。当ST hresh old=0则禁止发送触发OnC omm事件,当ST hresh old=1则发送缓冲区为空时就触发OnC omm事件。利用这一属性,就可完成发送数据后的一系列操作。如:对刚发送的数据进行处理,当串口是和M ODEM通信时,发送完数据后可进行拆除线路联接、挂机等操作。 RT hresh old:设置并返回不触发OnC omm事件时接收缓冲区被允许的最多字符数。当缓冲区的字符多于设置的值时,则触发OnC omm事件,并把C ommE vent设为M SCOM M—EV—RECEIVE,当RT hresh old=0则禁止接收触发OnC omm事件,当RT hresh old=1则接收缓冲区有一个或更多字符时就触发OnC omm事件。利用这一属性,就可完成对串口接收数据的处理。 2.利用通信控件的实例 Sub F orm1—load() form1.sh ow ′设置COM1 https://www.wendangku.net/doc/f72008671.html,m p ort=1 comm1.S ettin g="9600,o,8,1"′波特率:9600奇校验,8位数据,1位停止位 comm1.In p utlen=0′读取接收缓冲区的所有字符comm1.OutBufferS ize=512′设置发送缓冲区为512字节comm1.InBufferS ize=512′设置接收缓冲区为512字节comm1.ST hresh old=0′禁止发送事件 comm1.RT hresh old=1′每一个字符到接收缓冲区都触发接收事件 ′设置COM2 https://www.wendangku.net/doc/f72008671.html,m p ort=2 comm2.S ettin g="2400,e,8 ,1"

上位机与51单片机串口通信

上位机与51单片机串口通信 目录: 1、单片机串口通信的应用 2、PC控制单片机IO口输出 3、单片机控制实训指导及综合应用实例 4、单片机给计算机发送数据: [实验任务] 单片机串口通信的应用,通过串口,我们的个人电脑和单片机系统进行通信。 个人电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机系统接收后,用LED显示接收到的数据和向上位机发回原样数据。 [硬件电路图] [实验原理] RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串 行接口标准,用来实现计算机与计算机之间、计算机与外设之间的数据通讯。 RS-232串行接口总线适用于:设备之间的通讯距离不大于15m,传输速率最大为20kBps。RS-232协议以-5V-15V表示逻辑1;以+5V-15V 表示逻辑0。我们是用MAX232芯片将RS232电平转换为TTL电平的。一个完整的RS-232接口有22 根线,采用标准的25芯插头座。我们在这里使用的是简化的9芯插头座。 注意我们在这里使用的晶振是11.0592M的,而不是12M。因为波特率的设置 需要11.0592M的。 “串口调试助手V2.1.exe”软件的使用很简单,只要将串口选择‘CMO1’波 特率设置为‘9600’数据位为8 位。打开串口(如果关闭)。然后在发送区里 输入要发送的数据,单击手动发送就将数据发送出去了。注意,如果选中‘十六 进制发送’那么发送的数据是十六进制的,必须输入两位数据。如果没有选中, 则发送的是ASCLL码,那么单片机控制的数码管将显示ASCLL码值。

//参考源程序 #include "reg52.h" //包函8051 内部资源的定义 unsigned char dat; //用于存储单片机接收发送缓冲寄存器SBUF里面的内容sbit gewei=P2^4; //个位选通定义

智能仪器与PC串口通信的实现

福建电脑2010年第2期 图1SCPI 工作流程图 智能仪器与PC 串口通信的实现 管 平1,杨 丹2,胡新荣1 (1.武汉科技学院湖北武汉430073 2.长沙信息职业技术学校湖南长沙410610) 【摘要】:本文简要介绍了IEEE488.2标准,讨论了如何使用该协议进行智能仪器设备控制系统的编写.详细地介绍了SCPI 命令及其使用方法。利用Agilent 公司的IO suite 套件中的VISA 库实现对Agilent34401A 数字万用表的远程控制。 【关键词】:IEEE488.2,Agilent34401A ,SCPI 1、引言 1.1串口通信原理 在Windows 环境下,串行接口是系统资源的一部分。它本质功能是作为CPU 和串行设备间的编码转换器。当数据从CPU 经 过串行接口发送出去时,字节数据转换为串行的位。在接受数据时,串行的位被转换为字节数据。RS-232C 标准的全称是EIA-RS-232C 标准,其中EIA 代表美国电子工业协会,RS 代表推荐标准,232是标识号,C 代表RS232的最新一次修改。1.2SCPI 命令 Agilent34401A 数字多用表采用串口与IEEE488进行通信的技术,它能够得到精准、快速和可重复的测量结果。为了保证前向和后向兼容性,34401A 包括三种命令语言(SCPI 、Agi -lent3478A 和Fluke8840A/42A ),因此无需重写已有的测试软件。 SCPI (Standard Commands for Programmable Instruments )是可编程仪器标准命令,是一种建立在现有标准IEEE488.1和IEEE 488.2基础上,遵循了IEEE754标准中浮点运算规则、ISO646信息交换7位编码符号(相当于ASCll 编程)等多种标准的标准化仪器编程语言。它采用一套树状分层结构的命令集,提出了一个具有普遍性的通用仪器模型,采用面向信号的测量;它的助记符产生规则简单、明确,且易于记忆。SCPI 是以ASCII 字符组成的标准仪器命令语言,可以用于任何一种标准接口,如GPIB ,VXI ,RS232,USB ,LAN 。 SCPI 命令采用层次结构,系"树结构"语言。相关的命令集合到一起构成一个子系统,各组成命令称为"关键字",各关键字间用冒号":"分隔,如: SEN Se :FREQuency : VOLTage :RAN Ge ?[M INimum|MAXimum ] 方括弧([])表示选择性的关键字或参数。大括弧({})中为命令字串的参数。三角括弧(<>)表示必须用一数值来取代括号中的参数。(|)隔开多重参数的选择。 MEASure :VOLTage:DC?{|MIN|MAX|DEF},{|MIN|MAX|DEF} :VOLTage:AC?{|MIN|MAX|DEF},{|MIN|MAX|DEF} :CURRent:DC?{|MIN|MAX|DEF},{|MIN|MAX|DEF} :CURRent:AC?{|MIN|MAX|DEF},{|MIN|MAX|DEF} 从以上可以看出,SPCI 命令可以望文生意,简单明了,实际 SCPI 语言等于把各仪器的各种功能命令罗列起来完成某项测 量任务。 MEASure ?命令是设定仪器进行测量的最简单方法,在执 行这个命令的时候仪器必须先设置好所要求的状态,并立即执行测量。CONFigure 命令在执行的时候,仪器必须先将所要的配置预设成最好的设定,并且立即执行测量。 READ ?命令会将触发系统的状态,从"闲置"状态改为"等待触发"状态。在收到R EAD ?命令之后,且指定的触发条件满足时,测量便会开始,读数立即送到输出缓冲器上(读数资料必须输入到总线控制器上,否则输出缓冲器满了之后,测量就会停止)。INITiate 和FETCh?命令提供测量触发和读数取回最低限的控制。在配置好多用电表之后,使用INITiate 命令,它将使触发系统的状态,从"闲置"状态改为"等待触发"状态。在收到INITiate 命令之后,而指定的触发条件满足时,测量便会开始。读数将会存入多用电表的内部记忆体中。 .RST 重设多用电表电源开启时的配置。 .TST ? 执行多用电表的完整自我测试,传回值为"0"表示自我测试成功。它使用INITiate 将多用电表设至成"等待触发"状态,且在ExtTrig 端有脉冲进来的时候,量取一个读数,并将读数送到电表的内部记忆体上。2、硬件平台安装与配置 测试系统的建立,一般采用独立的测试或测量仪器,使用SCPI 命令或用软件驱动程序经GPIB ,USB ,LAN 接口发送ASCII 命令。 Agilent 34401A 数字多用表提供了一个GPIB 接口,在PC 和DMM 之间实现了简便稳定的连接能力。GPIB 接口满足IEEE-488.2标准,可以通过SCPI 命令进行远程控制。 我们选择NI 的AT-GPIB/TNT 卡与Agilent 34401A 进行通信.NI MAX 能发现所有NI 接口上的装置,但不能直接控制Ag -ilent 接口.如:VXI 的FireWire 接口,USB/GPIB 转换器,或PCL-GPIB 卡. Agilent 的Intuilink,VEE 和IO Libraries 能过NI -VISA 和NI488.2来连接GPIB-32.dll,如果应用程序使用VISA 编程,在对板卡基址配置完成后,先安装NI-VISA 软件包,再安装Agilent IO Libraries . 硬件安装与配置: 1)先安装NI-VISA IEEE488.2的板卡驱动程序.配置好GPIB 卡 2)设置万用表的通信方式:把agilent34401A 的通信方式设置为GPIB 通信方式,编程语言选择SCPI 。 3)安装Agilent 公司的IO 套件(iolibs_suite_14_2_8931_1_multimedia ),随IO 套件一起安装的还有的.net framework ,.net framework sp1,VISA 库,IO 套件必须要有VISA 库才能正常运行.在桌面任务栏的右下角会有一个IO 标志,打开Agilent connec -tion expert(安捷伦连接专家),它会自动检测到安装的硬件,使用GPIB0连接到万用表,这里也可测试计算机与(下转第137页 ) 168

51单片机串口通信,232通信,485通信,程序

51单片机串口通信,232通信,485通信,程序代码1:232通信 #include #define uchar unsigned char #define uint unsigned int uchar flag,a,i; uchar code table[]="i get"; void init() { TMOD=0X20; TH1=0XFD; TH0=0XFD; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1; } void main() { init();

while(1) { if(flag==1) { ES=0; for(i=0;i<6;i++) { SBUF=table[i]; while(!TI); TI=0; } SBUF=a; while(!TI); TI=0; ES=1; flag=0; } } } void ser() interrupt 4 {

RI=0; a=SBUF; flag=1; } 代码2:485通信 #include #include"1602.h" #define uchar unsigned char #define uint unsigned int unsigned char flag,a,i; uchar code table[]="i get "; void init() { TMOD=0X20; TH1=0Xfd; TL1=0Xfd; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1;

} void main() { init_1602(); init(); while(1) { if(flag==1) { display(0,a); } } } void ser() interrupt 4 { RI=0; a=SBUF; flag=1; } Love is not a maybe thing. You know when you love someone.

51单片机与PC机通信资料

《专业综合实习报告》 专业:电子信息工程 年级:2013级 指导教师: 学生:

目录 一:实验项目名称 二:前言 三:项目内容及要求 四:串口通信原理 五:设计思路 5.1虚拟串口的设置 5.2下位机电路和程序设计 5.3串口通信仿真 六:电路原理框图 七:相关硬件及配套软件 7.1 AT89C51器件简介 7.2 COMPIN简介 7.3 MAX232器件简介 7.4友善串口调试助手 7.5 虚拟串口软件Virtual Serial Port Driver 6.9八:程序设计 九:proteus仿真调试 十:总结 十一:参考文献 一:实验项目名称:

基于51单片机的单片机与PC机通信 二:前言 在国内外,以PC机作为上位机,单片机作为下位机的控制系统中,PC机通常以软件界面进行人机交互,以串行通信方式与单片机进行积极交互,而单片机系统根据被控对象配置相应的前向,后向信息通道,工作时作为主控机测对象,作为被控机接受PC机监督,指挥,定期或受命向上位机提供对象及本身的工作状态信息。 目前,随着集成电路集成度的增加,电子计算机向微型化和超微型化方向发展,微型计算机已成为导弹,智能机器人,人类宇宙和太空和太空奥妙复杂系统不可缺少的智能部件。在一些工业控制中,经常需要以多台单片机作为下位机执行对被控对象的直接控制,以一台PC机为上位机完成复杂的数据处理,组成一种以集中管理、分散控制为特点的集散控制系统。 为了提高系统管理的先进性和安全性,计算机工业自动控制和监测系统越来越多地采用集总分算系统。较为常见的形式是由一台做管理用的上位主计算机(主机)和一台直接参与控制检测的下位机(单片机)构成的主从式系统,主机和从机之间以通讯的方式来协调工作。主机的作用一是要向从机发送各种命令及参数:二是要及时收集、整理和分析从机发回的数据,供进一步的决策和报表。从机被动地接受、执行主机发来的命令,并且根据主机的要求向主机回传相应烦人实时数据,报告其运行状态。 用串行总线技术可以使系统的硬件设计大大简化、系统的体积减小、可靠性提高。同时,系统的更改和扩充极为容易。MCS-51系列单片机,由于内部带有一个可用于异步通讯的全双工的穿行通讯接口,阴齿可以很方便的构成一个主从式系统。 串口是计算机上一种非常通用的设备通讯协议,大多数计算机包容两个基于RS232的串口。串口同时也是仪器仪表设备通过用的通讯协议,很多GPIB兼容的设备也带有RS-232口。同时串口通讯协议也可以用于获取远程采集设备数据。所以,深入的理解学习和研究串口通信相关知识是非常必要的。此次毕业设计选题为“PC机与MCS-51单片机的串口通讯”,使用51单片机来实现一个主从式

实验单片机与PC机串口通信

实验单片机与PC机串口通信(C51编程)实验 要求: 1、掌握串行口的控制与状态寄存器SCON 2、掌握特殊功能寄存器PCON 3、掌握串行口的工作方式及其设置 4、掌握串行口的波特率(bondrate)选择 任务: 1、实现PC机发送一个字符给单片机,单片机接收到后即在个位、十位数码管上进行显示,同时将其回发给PC机。要求:单片机收到PC机发来的信号后用串口中断方式处理,而单片机回发给PC机时用查询方式。 采用软件仿真的方式完成,用串口调试助手和KEIL C,或串口调试助手和PROTEUS分别仿真。 需要用到以下软件:KEIL,VSPDXP5(虚拟串口软件),串口调试助手,Proteus。 (1)虚拟串口软件、串口调试助手和KEIL C的联调 首先在KEIL里编译写好的程序。

打开VSPD,界面如下图所示:(注明:这个软件用来进行串口的虚拟实现。在其网站上可以下载,但使用期为2周)。 左边栏最上面的是电脑自带的物理串口。点右边的addpair,可以添加成对的串口。一对串口已经虚拟互联了,如果添加的是COM3、COM4,用COM3发送数据,COM4就可以接收数据,反过来也可以。 接下来的一步很关键。把KEIL和虚拟出来的串口绑定。现在把COM3和KEIL绑定。在KEIL中进入DEBUG模式。在最下面的COMMAND命令行,输入 modecom39600,0,8,1 %分别设置com3的波特率、奇偶校验 位、数据位、停止位 assigncom3sout %把单片机的串口和COM3绑定到一 起。因为所用的单片机是

(以上参数设置注意要和所编程序中设置一致!) 打开串口调试助手 可以看到虚拟出来的串口COM3、COM4,选择COM4,设置为波特率9600,无校验位、8位数据位,1位停止位(和COM3、程序里的设置一样)。打开COM4。 现在就可以开始调试串口发送接收程序了。可以通过KEIL发送数据,在串口调试助手中就可以显示出来。也可以通过串口调试助手发送数据,在KEIL中接收。 实验实现PC机发送一个字符给单片机,单片机接收到后将其回发给PC机。在调试助手上(模拟PC)发送数据,单片机收到后将收到的结果回送到调试助手上。 2、以下在Proteus和串口调试助手实现的结果: 将编译好的HEX程序加载到Proteus中,注意这里需要加上串口模块,用来进行串行通信参数的设置。 点击串口,可以对串口进行设置: 用串口调试助手发送数据,即可看到仿真结果。 实验参考程序源文件在exp2-comm文件夹中。

第06章单片机串行通信系统习题解答

第6章单片机串行通信系统习题解答 一、填空题 1.在串行通信中,把每秒中传送的二进制数的位数叫波特率。 2.当SCON中的M0M1=10时,表示串口工作于方式 2 ,波特率为 fosc/32或fosc/64 。 3.SCON中的REN=1表示允许接收。 4.PCON 中的SMOD=1表示波特率翻倍。 5.SCON中的TI=1表示串行口发送中断请求。 6.MCS-51单片机串行通信时,先发送低位,后发送高位。 7.MCS-51单片机方式2串行通信时,一帧信息位数为 11 位。 8.设T1工作于定时方式2,作波特率发生器,时钟频率为,SMOD=0,波特率为时,T1的初值为 FAH 。 9.MCS-51单片机串行通信时,通常用指令 MOV SBUF,A 启动串行发送。 10.MCS-51单片机串行方式0通信时,数据从引脚发送/接收。 二、简答题 1.串行口设有几个控制寄存器它们的作用是什么 答:串行口设有2个控制寄存器,串行控制寄存器SCON和电源控制寄存器PCON。其中PCON中只有的SMOD与串行口的波特率有关。在SCON中各位的作用见下表: 2.MCS-51单片机串行口有几种工作方式各自的特点是什么 答:有4种工作方式。各自的特点为:

3.MCS-51单片机串行口各种工作方式的波特率如何设置,怎样计算定时器的初值 答:串行口各种工作方式的波特率设置: 工作方式O :波特率固定不变,它与系统的振荡频率fosc 的大小有关,其值为fosc/12。 工作方式1和方式3:波特率是可变的,波特率=(2SMOD/32)×定时器T1的溢出率 工作方式2:波特率有两种固定值。 当SM0D=1时,波特率=(2SM0D/64)×fosc=fosc/32 当SM0D=0时,波特率=(2SM0D/64)×fosc=fosc/64 计算定时器的初值计算: 4.若fosc = 6MHz ,波特率为2400波特,设SMOD =1,则定时/计数器T1的计数初值为多少并进行初始化编程。 答:根据公式 N=256-2SMOD ×fosc /(2400×32×12)= ≈243 =F3H TXDA: MOV TMOD,#20H ;置T1定时器工作方式2 MOV TL1,#0F3H ;置T1计数初值. MOV TH1,#0F3H B f B f N OSC SMOD OSC SMOD ??-=???-=384225612322256

单片机串口通信C程序及应用实例

一、程序代码 #include//该头文件可到https://www.wendangku.net/doc/f72008671.html,网站下载#define uint unsigned int #define uchar unsigned char uchar indata[4]; uchar outdata[4]; uchar flag; static uchar temp1,temp2,temp3,temp; static uchar R_counter,T_counter; void system_initial(void); void initial_comm(void); void delay(uchar x); void uart_send(void); void read_Instatus(void); serial_contral(void); void main() { system_initial(); initial_comm(); while(1) { if(flag==1) { ES = 0; serial_contral(); ES = 1; flag = 0; } else read_Instatus(); } } void uart_send(void) { for(T_counter=0;T_counter<4;T_counter++) { SBUF = outdata[T_counter]; while(TI == 0);

TI = 0; } T_counter = 0; } uart_receive(void) interrupt 4 { if(RI) { RI = 0; indata[R_counter] = SBUF; R_counter++; if(R_counter>=4) { R_counter = 0; flag = 1; } } } void system_initial(void) { P1M1 = 0x00; P1M0 = 0xff; P1 = 0xff; //初始化为全部关闭 temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致 temp = 0xf0; R_counter = 0; T_counter = 0; } void initial_comm(void) { SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload PCON = 0x80; //波特率不加倍SMOD = 1 TH1 = 0xfa; //baud: 9600;fosc = 11.0596 IE = 0x90; // enable serial interrupt TR1 = 1; // timer 1 RI = 0; TI = 0; ES = 1; EA = 1; }

51单片机串口通信异常的调试一例

51单片机串口通信异常的调试一例 单片机与DSP在硬件结构和程序编写方面存在很多共同之处,所以最近几周试着用了一下51单片机开发板,希望进一步熟悉中断的概念、串口通信、I2C协议、存储扩展等常用的知识。 在进行串口通信的实验时,预期功能不能实现。实验的设计方案是:通过上位机给单片机发送一个16bit的字符串,单片机对字符串进行接收并立刻回显给上位机,接收并回显完毕后依次将这些字符(只能是0-9,a-f这几个字符,可以重复)在数码管上进行显示。 程序编写完成后,通过上位机发送字符串9876543210abcdef,单片机串口接收并回显9876543210abcde,然后数码管依次显示f9876543210abcde,数码管显示完成后,单片机串口回显的字符串中的e后面又多了一个f。 对实验现象进行分析不难发现,串口的接收和回显功能正常,但是存在2个问题:1.串口接收并回显和数码管显示的时序有点混乱;2.数码管的显示出现异常,本应该依次显示9876543210abcdef,实际上显示的却是f9876543210abcde。 对源代码进行分析发现,时序混乱的原因是中断响应及中断返回的执行时序出现问题,修改代码后问题1被解决。 问题2的解决思路:源代码中,通过串口接收到的字符串被存储在一个一维数组array[16]中,该数组有16个元素,每个元素都是unsigned char型。在源代码中,先注释掉数码管显示的那一段代码,然后添加串口打印代码,串口打印实现的功能是依次显示array[0]到array[15]这16个元素的值。编译通过后,将程序烧写到单片机。使用串口调试助手,以十六进制的形式观察array[0]到array[15]的取值,结果如下:

51单片机实现的485通讯程序

51单片机实现的485通讯程序 #ifndef __485_C__ #define __485_C__ #include #include #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^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); 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

单片机串口通信的发送与接收(可编辑修改word版)

51 单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。 当串行发送完毕后,将在标志位TI 置1,同样,当收到了数据后,也会在RI 置1。无 论RI 或TI 出现了1,只要串口中断处于开放状态,单片机都会进入串口中断处理程序。在中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。 看到过一些书籍和文章,在串口收、发数据的处理方法上,很多人都有不妥之处。 接收数据时,基本上都是使用“中断方式”,这是正确合理的。 即:每当收到一个新数据,就在中断函数中,把RI 清零,并用一个变量,通知主函数, 收到了新数据。 发送数据时,很多的程序都是使用的“查询方式”,就是执行while(TI ==0); 这样的语句来 等待发送完毕。 这时,处理不好的话,就可能带来问题。 看了一些网友编写的程序,发现有如下几条容易出错: 1.有人在发送数据之前,先关闭了串口中断!等待发送完毕后,再打开串口中断。 这样,在发送数据的等待期间内,如果收到了数据,将不能进入中断函数,也就不会保存的这个新收到的数据。 这种处理方法,就会遗漏收到的数据。 2.有人在发送数据之前,并没有关闭串口中断,当TI = 1 时,是可以进入中断程序的。 但是,却在中断函数中,将TI 清零! 这样,在主函数中的while(TI ==0);,将永远等不到发送结束的标志。 3.还有人在中断程序中,并没有区分中断的来源,反而让发送引起的中断,执行了接收 中断的程序。 对此,做而论道发表自己常用的方法: 接收数据时,使用“中断方式”,清除RI 后,用一个变量通知主函数,收到新数据。 发送数据时,也用“中断方式”,清除TI 后,用另一个变量通知主函数,数据发送完毕。 这样一来,收、发两者基本一致,编写程序也很规范、易懂。 更重要的是,主函数中,不用在那儿死等发送完毕,可以有更多的时间查看其它的标志。 实例: 求一个PC 与单片机串口通信的程序,要求如下: 1、如果在电脑上发送以$开始的字符串,则将整个字符串原样返回(字符串长度不是固定的)。

51单片机串口通信的原理与应用流程解析

51单片机串口通信的原理与应用流程解析 一、原理简介 51 单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。 与之前一样,首先我们来了解单片机串口相关的寄存器。 SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1),同时发送、接收数据,实现全双工。 串行口控制寄存器SCON(见表1)。 表1 SCON寄存器 表中各位(从左至右为从高位到低位)含义如下。 SM0 和SM1 :串行口工作方式控制位,其定义如表2 所示。 表2 串行口工作方式控制位 其中,fOSC 为单片机的时钟频率;波特率指串行口每秒钟发送(或接收)的位数。 SM2 :多机通信控制位。该仅用于方式2 和方式3 的多机通信。其中发送机SM2 = 1(需要程序控制设置)。接收机的串行口工作于方式2 或3,SM2=1 时,只有当接收到第9 位数据(RB8)为1 时,才把接收到的前8 位数据送入SBUF,且置位RI 发出中断申请引发串行接收中断,否则会将接受到的数据放弃。当SM2=0 时,就不管第位数据是0 还是1,都将数据送入SBUF,并置位RI 发出中断申请。工作于方式0 时,SM2 必须为0。

工业控制--串口通讯方法(精)

工业控制--串口通讯方法(WINAPI实现)介绍介绍工业控制领域利用串口和外围设备进行通讯。正文前言:总所周之,利用串口进行数据通讯在在通讯通讯领域重占有着重要的地位。利用RS232-RS485进行数据信号的采集和传递是VC 编程的又一大热点。串口通讯在通讯软件重有着十分广泛的应用。如电话、传真、视频和各种控制等。在各种开发工具中间,VC由于功能强大和灵活,同时也得到了Microsoft的最大支持,所以在一般进行涉及硬件操作的通讯编程重,大都推荐使用VC作为开发工具。然而工业控制串口通讯这个又不同于一般的串口通讯程序,因为控制外围设备传送的大都是十六进制数据(BYTE类型),所以,为了提高程序的运行稳定性,我们在编写程序进行通讯时可以不考虑传送BYTE类型数 据的工作。串口通讯目前流行的方法大概有两种:一是利用Microsoft提供的CMSCOMM控件进行通讯,不过现在很多程序员都觉应该放弃这种方式。二是利用WINAPI函数进行编程,这种编程的难度最高,要求你要掌握很多的API函 数。三是利用现在网络上面提供的一些串口通讯控件进行编写,比如CSerial类等。程序实现:我在经过许多的项目的开发和实践中发现,采用WIN API函数进行串口的开发能够给程序员很大的控件,并且程序运也很稳定。所以我将与串口接触的函数进行封装,然后在各个工程中进行调用,效果还是比较好的,现将各个函数和调用方法列举出来,希望对各位有所帮助。一、设置串口相关工作 #define MAXBLOCK 2048 #define XON 0x11 #define XOFF 0x13 BOOL SetCom(HANDLE &m_hCom, const char *m_sPort, int BaudRate, int Databit, CString parity, CString stopbit { COMMTIMEOUTS TimeOuts; ///串口输出时间超时设置 DCB dcb; ///与端 口匹配的设备 m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL; // 以重叠方式打开串口 if(m_hCom==INVALID_HANDLE_VALUE { AfxMessageBox("设置串口部分,串口打开失败"; /////重叠方式异步通信(INVALID_HANDLE_VALUE)函数失败。return FALSE; } SetupComm(m_hCom,MAXBLOCK,MAXBLOCK; //设置缓冲区memset(&TimeOuts,0,sizeof(TimeOuts; TimeOuts.ReadIntervalTimeout=MAXDWORD; // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作

两个单片机之间的串行通信

两个单片机之间的串行通信 一、设计要求 在某个控制系统中有U1、U2这两个单片机,U1单片机首先将P1端口指拨开关数据载入SBUF,然后经由TXD将数据传送给U2单片机,U2单片机将接收数据存入SBUF,再由SBUF载入累加器,并输出至P1端口,点亮相应端口的LED。 二、实验所需元器件 三、电路原理图: 两个单片机之间的串行通信电路图

四、程序设计 这两个单片机均工作在半工状态,U1将P1端口的状态通过TXD发半空给U2,而U2接收U1的数据,然后控制P1端口的LED显示。因此,需编写两个不同的程序,其程序流程图如下所示:

五、C语言程序: U1的C语言程序: #include "reg51.h" #define uint unsigned int #define uchar unsigned char void send(uchar state) { SBUF=state; while(TI==0); TI=0; } void SCON_init(void) { SCON=0x50; TMOD=0x20; PCON=0x00; TH1=0xfd; TL1=0xfd; TI=0; TR1=1; ES=1; } void main() { P1=0xff; SCON_init(); while(1) { send(P1); } } U2的C语言程序: #include "reg51.h" #define uint unsigned int #define uchar unsigned char uchar state; void receive() { while(RI==0) state=SBUF; RI=0; } void SCON_init(void) { SCON=0x50; TMOD=0x20; PCON=0x00; TH1=0xfd; TL1=0xfd; RI=0; TR1=1; } void main() { SCON_init(); while(1) { receive(); P1=state; } } 六、调试与仿真:

51单片机串口通信

一、串口通信原理 串口通讯对单片机而言意义重大,不但可以实现将单片机的数据传输到计算机端,而且也能实现计算机对单片机的控制。由于其所需电缆线少,接线简单,所以在较远距离传输中,得到了广泛的运用。串口通信的工作原理请同学们参看教科书。 以下对串口通信中一些需要同学们注意的地方作一点说明: 1、波特率选择 波特率(Boud Rate)就是在串口通信中每秒能够发送的位数(bits/second)。MSC-51串行端口在四种工作模式下有不同的波特率计算方法。其中,模式0和模式2波特率计算很简单,请同学们参看教科书;模式1和模式3的波特率选择相同,故在此仅以工作模式1为例来说明串口通信波特率的选择。 在串行端口工作于模式1,其波特率将由计时/计数器1来产生,通常设置定时器工作于模式2(自动再加模式)。在此模式下波特率计算公式为:波特率=(1+SMOD)*晶振频率/(384*(256-TH1)) 其中,SMOD——寄存器PCON的第7位,称为波特率倍增位; TH1——定时器的重载值。 在选择波特率的时候需要考虑两点:首先,系统需要的通信速率。这要根据系统的运作特点,确定通信的频率范围。然后考虑通信时钟误差。使用同一晶振频率在选择不同的通信速率时通信时钟误差会有很大差别。为了通信的稳定,我们应该尽量选择时钟误差最小的频率进行通信。 下面举例说明波特率选择过程:假设系统要求的通信频率在20000bit/s以下,晶振频率为12MHz,设置SMOD=1(即波特率倍增)。则TH1=256-62500/波特率 根据波特率取值表,我们知道可以选取的波特率有:1200,2400,4800,9600,19200。列计数器重载值,通信误差如下表: 因此,在通信中,最好选用波特率为1200,2400,4800中的一个。 2、通信协议的使用 通信协议是通信设备在通信前的约定。单片机、计算机有了协议这种约定,通信双方才能明白对方的意图,以进行下一步动作。假定我们需要在PC机与单片机之间进行通信,在双方程式设计过程中,有如下约定:0xA1:单片机读取P0端口数据,并将读取数据返回PC机;0xA2:单片机从PC机接收一段控制数据;0xA3:单片机操作成功信息。 在系统工作过程中,单片机接收到PC机数据信息后,便查找协议,完成相应的操作。当单片机接收到0xA1时,读取P0端口数据,并将读取数据返回PC机;当单片机接收到0xA2时,单片机等待从PC机接收一段控制数据;当PC机接收到0xA3时,就表明单片机操作已经成功。 3、硬件连接 51单片机有一个全双工的串行通讯口,所以单片机和计算机之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如计算机的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。我们采用了三线制连接串口,也就是说和计算机的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。

单片机串口通信

单片机串口通信 关键词:单片机,串口通信 单片机应用中,串口通信是不可缺少的部分。如何编写有效的串口通信程序对程序的结构、可靠性都有很大的影响。串口控制程序一般分为查询和中断两者方式。查询方式适用于简单的应用,简单可靠,但是缺点是需要占用处理器资源,在发送或者接收数据的时候不能做其它的事情,处理器利用率低。中断方式下,在发送或者接受数据的时候处理器还可以做其它的工作,效率较高。 对于稍微复杂的系统来说,中断方式管理串口程序将会更加有效。中断处理方式也可分为几种,其中采用循环缓冲区的方式比较高效。循环缓冲区为定义的一定长度的RAM区间,对于接受数据来说,中断中收到的数据将存入RAM中,然后等待主程序来读取。其中会涉及到数据见的协调问题,写数据的时候不能把还没有读取的数据覆盖掉,读数据的时候应该读取的是缓冲区中最老的数据。当缓冲区已满的时候,写入的新数据应该覆盖掉最老的数据。这些问题的处理可以使用两个指针来实现。

初始化时两个指针均指向RAM区间的底部,如图1所示。当中断中接收到一个数据的时候,将这个数据写入写指针WPTR指向的存储单元,然后调整写指针指向下一个空余的RAM区间,程序上处理就是把写指针加一,如图2所示。同理,写入N个数据后写指针同步更新,如图3所示。 当读数据的时候,首先判断缓冲区中是否有数据,方法是判断读指针和写指针是否相等,如果相等表明没有数据,如图5所示。如果读指针和写指针不等,那么读取缓冲区中的数据,然后调整读指针,当写指针和读指针相等的时候,表明缓冲区中的有效数据已经读取完,此时读指针和写指针相等。

当有数据再次写入的时候,继续紧接着上次写入的地址后写入新的数据,如果数据长度超过缓冲区的长度,写指针重新返回缓冲区的底部重新开始(这是循环缓冲的由来),如图6所示。此时如果有数据读出,读指针做同样的更新。如果没有数据读出,一直有数据写入,可能会出现缓冲区写满的情况,如图7所示。此时如果仍然没有数据读取,继续有数据写入的时候,为了保留新的数据,必须丢弃老的数据,即写指针可能超过读指针,此时,读指针必须和谐指针同步更新,这样才能保证读取的是没有被覆盖的最老的数据,如图8所示。 需要注意的是,读指针在中断过程中也可能被更改,因此,读数据的子程序需要对读指针的更改进行保护,方法是在读数据的时候关闭串行口中断。下面是循环缓冲区接收数据的程序实例。 FT, 尽然连文本都不能上传,代码只好贴出来吧。 /* * FileName: uart.h * Description: header file for SerialPort * Author: SangWei, HUST-CEEE-2004 * Contact: swkyer@https://www.wendangku.net/doc/f72008671.html,, swkyer@https://www.wendangku.net/doc/f72008671.html,

相关文档
相关文档 最新文档