51单片机串口通信(相关例程)

合集下载

51单片机串行通信接口

51单片机串行通信接口

工 作 方 式 选 择 位
多允 机许 通接 信收 控控 制制 位位
发 接发接 送 收送收 数 数中中 据 据断断 第 第标标 九 九志志 位位
北京交通大学
18
各位功能说明如下: SM0 SM1:串口工作方式选择位
00 方式0: 同步移位寄存器 波特率=主振频率/12
01 方式1: 8位异步,波特率可变
⑵在双机通信中,该位作为奇偶校验位; ⑶在多机通信中用来表示D7-D0是地址帧或数据帧
即:
D8=0:表示数据帧; D8=1:表示地址帧
北京交通大学
20位是接收到的第9位数据。 方式1,SM2=0,停止位。方式0,不用。
⑵在多机通信中是地址帧(RB8=1)和数据帧 (RB8=0)的标识位。
北京交通大学
34
方式2、3的区别是:波特率设置不同 方式2的波特率是固定的。即:
波特率=fosc/32或fosc/64 方式3的波特率是可变的。即:
波特率 2smod
fosc
32 12 (256 X )
X
256
fosc (2s mod ) 384 波特率
北京交通大学
35
表1 波特率与时间常数
第6章 串行通信接口
本章主要内容 • 串行数据通信基本原理 • MCS-51单片机串行口 • 串行口应用举例
北京交通大学
1
一、串行数据通信基本原理
计算机的两种方式数据传送:并行和串行
并行传送的特点:
各数据位同时传送,传送速度快、效率高。
但需要的数据线多,因此传送成本高。并行数据
传送的距离通常小于30米。
3.直到停止位到来之后把它送入到RB8中,并 置位RI,通知CPU从SBUF取走接收到的一个字符。

51单片机的串口通信程序之欧阳家百创编

51单片机的串口通信程序之欧阳家百创编

单片机串口通信程序欧阳家百(2021.03.07)#include <reg52.h> #include<intrins.h>#include <stdio.h>#include<math.h>#define uchar unsigned char #define uint unsigned intsbit Key1 = P2^3;sbit Key2 = P2^2;sbit Key3 = P2^1;sbit Key4 = P2^0;sbit BELL = P3^6;sbit CONNECT = P3^7;unsigned int Key1_flag = 0;unsigned int Key2_flag = 0;unsignedint Key3_flag = 0;unsigned int Key4_flag = 0;unsigned charb;unsigned char codeNum[21]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80, 0x90,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00, 0x10,0x89}; unsigned char code Disdigit[4] ={0x7F,0xBF,0xDF,0xEF};unsigned char Disbuf[4];void delayms(uint t){ uint i; while(t--) { /* 对于11.0592M时钟,约延时1ms */ for (i=0;i<125;i++) {} }}//-----------------------------------------------------void SendData(uchar Dat){uchar i=0;SBUF = Dat;while(1) { if(TI) { TI=0; break; } } }void ScanKey(){ if(Key1 == 0) { delayms(100); if(Key1 == 0) { Key1_flag = 1; Key2_flag = 0; Key3_flag =0; Key4_flag = 0; Key1 = 1; } else; } if(Key2 ==0) { delayms(100); if(Key2 == 0) { Key2_flag =1; Key1_flag = 0; Key3_flag = 0; Key4_flag = 0; Key2 = 1; } else; } if(Key3 == 0) { delayms(50); if(Key3 ==0) { Key3_flag = 1; Key1_flag = 0; Key2_flag =0; Key4_flag = 0; Key3 = 1; } else; } if(Key4 ==0) { delayms(50); if(Key4 == 0) { Key4_flag =1; Key1_flag = 0; Key2_flag = 0; Key3_flag = 0; Key4 = 1; } else; } else; }void KeyProc(){ if(Key1_flag) { TR1 = 1; SendData(0x55); Key1_flag = 0; } elseif(Key2_flag) { TR1 = 1; SendData(0x11); Key2_flag = 0; } else if(Key3_flag) { P1=0xff; BELL = 0; CONNECT = 1; Key3_flag = 0; } else if(Key4_flag) { CONNECT = 0; BELL = 1; Key4_flag = 0; } else; }void Initdisplay(void){Disbuf[0] = 1;Disbuf[1] = 2;Disbuf[2] =3;Disbuf[3] = 4;}void Display() //显示{unsigned int i = 0;unsigned inttemp,count; temp = Disdigit[count]; P2 =temp; temp = Disbuf[count]; temp = Num[temp]; P0=temp; count++; if (count==4) count=0; } void time0() interrupt 1 using 2{ Display(); TH0 = (65535 -2000)/256; TL0 = (65535 - 2000)%256;} voidmain(){Initdisplay();TMOD = 0x21;TH0 = (65535 - 2000)/256;TL0 = (65535 - 2000)%256;TR0 = 1;ET0 = 1; TH1 = 0xFD; //11.0592MTL1 = 0xFD;PCON&=0x80;TR1 = 1;ET1 = 1;SCON = 0x40; //串口方式REN = 1; PT1 = 0;PT0 = 1;EA = 1;while(1) { ScanKey(); KeyProc(); if(RI) { Disbuf[0] = 0; Disbuf[1] = 20; Disbuf[2] = SBUF>>4; Disbuf[3] =SBUF&0x0f; RI = 0; } else; }}。

51单片机串口通信实例

51单片机串口通信实例

51单片机串口通信实例一、原理简介51 单片机内部有一个全双工串行接口。

什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。

串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。

其缺点是传输速度较低。

与之前一样,首先我们来了解单片机串口相关的寄存器。

SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。

从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1),同时发送、接收数据,实现全双工。

串行口控制寄存器SCON(见表1) 。

表1 SCON寄存器表中各位(从左至右为从高位到低位)含义如下。

SM0 和SM1 :串行口工作方式控制位,其定义如表2 所示。

经验分享:学习单片机重要的是实践,所以开发板是很重要,给大家推荐些淘宝上信誉良好并且软硬件及小零件等、售前售后服务良好的皇冠级金钻店铺给大家,在硬件购买上少走弯路。

按住Ctrl键单击即可:慧净电子单片机(一皇冠)【天津商盟】天津锐志(电子)单片机经营部(两皇冠)金沙滩工作室(5钻)深圳育松电子元件,模块,传感器,批发部:淘宝最全最平价(5皇冠)志宏电子(4钻)表2 串行口工作方式控制位其中,fOSC 为单片机的时钟频率;波特率指串行口每秒钟发送(或接收)的位数。

SM2 :多机通信控制位。

该仅用于方式2 和方式3 的多机通信。

其中发送机SM2 = 1(需要程序控制设置)。

接收机的串行口工作于方式2 或3,SM2=1 时,只有当接收到第9 位数据(RB8)为1 时,才把接收到的前8 位数据送入SBUF,且置位RI 发出中断申请引发串行接收中断,否则会将接受到的数据放弃。

当SM2=0 时,就不管第位数据是0 还是1,都将数据送入SBUF,并置位RI 发出中断申请。

51单片机双机串行通信设计

51单片机双机串行通信设计

51单片机双机串行通信设计51单片机是一款广泛应用于嵌入式系统中的微控制器,具有高性能和低功耗的特点。

在一些场景中,需要使用51单片机之间进行双机串行通信,以实现数据传输和协同工作。

本文将介绍51单片机双机串行通信的设计,包括硬件连接和软件编程。

一、硬件连接1.串行通信口选择:51单片机具有多个串行通信口,如UART、SPI 和I2C等。

在双机串行通信中,可以选择其中一个串行通信口作为数据传输的接口。

一般来说,UART是最常用的串行通信口之一,因为它的硬件接口简单且易于使用。

2.引脚连接:选定UART口作为串行通信口后,需要将两个单片机之间的TX(发送)和RX(接收)引脚相连。

具体的引脚连接方式取决于所使用的单片机和外设,但一般原则上是将两个单片机的TX和RX引脚交叉连接。

二、软件编程1.串行通信初始化:首先需要通过软件编程来初始化串行通信口。

在51单片机中,可以通过设置相应的寄存器来配置波特率和其他参数。

具体的初始化代码可以使用C语言编写,并根据所使用的开发工具进行相应的配置。

2.发送数据:发送数据时,可以通过写入相应的寄存器来传输数据。

在51单片机中,通过将数据写入UART的发送寄存器,即可将数据发送出去。

发送数据的代码通常包括以下几个步骤:(1)设置发送寄存器;(2)等待数据发送完成;(3)清除数据发送完成标志位。

3.接收数据:接收数据时,需要通过读取相应的寄存器来获取接收到的数据。

在51单片机中,可以通过读取UART的接收寄存器,即可获取到接收到的数据。

接收数据的代码通常包括以下几个步骤:(1)等待数据接收完成;(2)读取接收寄存器中的数据;(3)清除数据接收完成标志位。

4.数据处理:接收到数据后,可以进行相应的数据处理。

根据具体的应用场景,可以对接收到的数据进行解析、计算或其他操作。

数据处理的代码可以根据具体的需求进行编写。

5.中断服务程序:在双机串行通信中,使用中断可以提高通信的效率。

51单片机串口通信(相关例程)

51单片机串口通信(相关例程)

51单片机串口通信(相关例程) 51单片机串口通信(相关例程)一、简介51单片机是一种常用的微控制器,它具有体积小、功耗低、易于编程等特点,被广泛应用于各种电子设备和嵌入式系统中。

串口通信是51单片机的常见应用之一,通过串口通信,可以使单片机与其他外部设备进行数据交互和通信。

本文将介绍51单片机串口通信的相关例程,并提供一些实用的编程代码。

二、串口通信基础知识1. 串口通信原理串口通信是通过串行数据传输的方式,在数据传输过程中,将信息分为一个个字节进行传输。

在51单片机中,常用的串口通信标准包括RS232、RS485等。

其中,RS232是一种常用的串口标准,具有常见的DB-9或DB-25连接器。

2. 串口通信参数在进行串口通信时,需要设置一些参数,如波特率、数据位、停止位和校验位等。

波特率表示在单位时间内传输的比特数,常见的波特率有9600、115200等。

数据位表示每个数据字节中的位数,一般为8位。

停止位表示停止数据传输的时间,常用的停止位有1位和2位。

校验位用于数据传输的错误检测和纠正。

三、串口通信例程介绍下面是几个常见的51单片机串口通信的例程,提供给读者参考和学习:1. 串口发送数据```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_SendChar(unsigned char dat){SBUF = dat; // 发送数据while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志}void main(){UART_Init(); // 初始化串口while (1){UART_SendChar('A'); // 发送字母A}}```2. 串口接收数据```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_Recv(){unsigned char dat;if (RI) // 检测是否接收到数据{dat = SBUF; // 读取接收到的数据 RI = 0; // 清除接收中断标志// 处理接收到的数据}}void main(){UART_Init(); // 初始化串口EA = 1; // 允许中断ES = 1; // 允许串口中断while (1)// 主循环处理其他任务}}```3. 串口发送字符串```C#include <reg51.h>void UART_Init(){TMOD = 0x20; // 设置计数器1为工作方式2(8位自动重装) TH1 = 0xFD; // 设置波特率为9600SCON = 0x50; // 设置串口工作方式1,允许串行接收TR1 = 1; // 启动计数器1}void UART_SendString(unsigned char *str){while (*str != '\0')SBUF = *str; // 逐个发送字符while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志str++; // 指针指向下一个字符}}void main(){UART_Init(); // 初始化串口while (1){UART_SendString("Hello, World!"); // 发送字符串}}```四、总结本文介绍了51单片机串口通信的基础知识和相关编程例程,包括串口发送数据、串口接收数据和串口发送字符串。

电脑与AT89S51单片机串口通信的51端程序 LCD显示

电脑与AT89S51单片机串口通信的51端程序 LCD显示

电脑与AT89S51单片机串口通信的51端程序要求在电脑上运行串口调试助手软件,在发送框输入字符,点击发送后,在下位机51系列单片机上接受并送到液晶1602上显示,求下位机的编程,实现接收PC发来的数据并在让它在1602液晶上显示.#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS = P2^0;sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};uchar data RXDdata[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 };uchar temp,buf,m,count;bit playflag=0;uchar code cdis1[ ] = {" SERILA TRANFER "};uchar code cdis2[ ] = {" "};/**********************************************************延时子程序**********************************************************/void delay1(uint ms){uchar k;while(ms--){for(k = 0; k < 120; k++);}}/******************************************************************//*检查LCD忙状态*//*lcd_busy为1时,忙,等待。

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();

51单片机串口多机通信的实现和编程

51单片机串口多机通信的实现和编程

51 单片机串口多机通信的实现和编程
一、51 单片机的主从模式,首先要设定工作方式3:(主从模式+波特率可变)
SCON 串口功能寄存器:SM0=1;SM1=1(工作方式3)
注:主机和从机都要为工作方式3。

【工作方式2 (SM0 SM1 :1 0):串行口为11 位异步通信接口。

发送或接收
一帧信息包括1 位起始位0、8 位数据位、1 位可编程位、1 位停止位1。


送数据:发送前,先根据通信协议由软件设置TB8 为奇偶校验位或数据标识位,然后将要发送的数据写入SBUF,即能启动发送器。

发送过程是由执行任何一条以SBUF 为目的寄存器的指令而启动的,把8 位数据装入SBUF,
同时还把TB8 装到发送移位寄存器的第9 位上,然后从TXD(P3.1)端口输出
一帧数据。

接收数据:先置REN=1,使串行口为允许接收状态,同时还要将RI 清0。

然后再根据SM2 的状态和所接收到的RB8 的状态决定此串行口在
信息到来后是否置R1=1,并申请中断,通知CPU 接收数据。

当SM2=0 时,
不管RB8 为0 还是为1,都置RI=1,此串行口将接收发送来的信息。


SM2=1 时,且RB8=1,表示在多机通信情况下,接收的信息为地址帧, 此时
置RI=1,串行口将接收发来的地址。

当SM2=1 时,且RB8=0,表示在多机通
信情况下,接收的信息为数据帧, 但不是发给本从机的,此时RI 不置为1,。

深入理解51单片机串口通信及通信实例

深入理解51单片机串口通信及通信实例

深入理解51单片机串口通信及通信实例串口通信的原理串口通信(SerialCommunicaTIons)的概念非常简单,串口按位(bit)发送和接收字节。

尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。

它很简单并且能够实现远距离通信。

比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。

典型地,串口用于ASCII码字符的传输。

通信使用3根线完成,分别是地线、发送、接收。

由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。

其他线用于握手,但不是必须的。

串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。

对于两个进行通信的端口,这些参数必须匹配。

a,波特率:这是一个衡量符号传输速率的参数。

指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。

一般调制速率大于波特率,比如曼彻斯特编码)。

通常电话线的波特率为14400,28800和36600。

波特率可以远远大于这些值,但是波特率和距离成反比。

高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。

b,数据位:这是衡量通信中实际数据位的参数。

当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。

如何设置取决于你想传送的信息。

比如,标准的ASCII码是0~127(7位)。

扩展的ASCII码是0~255(8位)。

如果数据使用简单的文本(标准ASCII码),那么每个数据包使用7位数据。

每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。

由于实际数据位取决于通信协议的选取,术语包指任何通信的情况。

51系列串口通讯例程(参考仅供)

51系列串口通讯例程(参考仅供)

51系列串口通讯例程.rar > serial.c,1.// 题目:串口初始化C代码2.// 要求:3.// 1.波特率1200bps,无奇偶校验,停止位1,数据位84.// 2.定时器T1做波特率发生器5.// 软件模拟测试说明:6.// 1.这个测试采用查询方式进行串口通讯7.// 2.将软件仿真环境的晶震设为11.0592 MHz8.// 3.软件模拟全速运行, 观察波特率是1200bps9.// 4.在串口1中输入数字或字母,可观察到通讯是否有误。

10.//#pragma src11.#include <REG51.H>12.//串口初始化13.void serial_init(void)14.{15.//ET1 = 0; //CLR 0ABH ;禁止T1中断16. TMOD = 0x20; //MOV 89H,#20H ;timer 1 mode 2: 8-Bit reload(定时器T1 模式2: 8位自动初值重装)17. TH1 = 0xE8; //MOV 8DH,#0E8H18. TL1 = 0xE8; //MOV 8BH,#0E8H ;1200bps, 11.05919. TR1 = 1; //SETB 8EH ;启动定时器120. SCON = 0x50; // mode 1: 10-bit UART, enable receiver//(模式1: 10位异步发送/接收, 使能接收允许位)21.//SM1 = 1; // ;串行口模式122.//SM0 = 0;23.//REN = 1; // ;允许串行中断接收24. SM2 = 1; //SETB O9DH ;收到有效的停止位时才将RI置125. ES = 1; //SETB 0ACH ;允许串行中断26. EA = 1; //SETB 0AFH ;总中断开27.}28.//中断方式处理串口数据29.void serial(void) interrupt 4 using 130.{31.if(RI)32. {33.// RI = 0;34.// 串口接收, 采用临时缓冲35. }36.#if 037.if(TI)38. {39.// TI = 0;40.// 串口发送, 没有必要使用中断方式41. }42.#endif43.}44.// 查询方式接收串口数据45.unsigned char getchar(void)46.{47.while(!RI);// 没有收到串口数据则一直等待48. RI=0;49.return SBUF;50.}51.// 查询方式发送串口数据52.void putchar(unsigned char ch)53.{54. SBUF=ch;55.while(!TI);56. TI=0;57.}58.code unsigned char HEX_TAB []="0123456789ABCDEF";59.void puthex(unsigned char ch)60.{61. unsigned char i,j;62. i=ch>>4;63. j=ch&0x0f;64. putchar(HEX_TAB[i]);65. putchar(HEX_TAB[j]);66.}51系列串口通讯例程.rar > test.c1.// 采用查询方式进行串口通讯的例子2.// 采用这种方式的弊端:3.// 1.如果对方没有发送数据,则本机无限等待,而不能做其它事情4.// 2.如果对方发送数据而本机正做其它事情,那么有可能丢失数据。

51单片机串口通信连续发送接收字节

51单片机串口通信连续发送接收字节

51单片机串口通信连续发送接收字节当使用单片机串口通信,连续发送字节时,如何处理呢?使用串口中断接收发送字节,中断内的程序尽可能简单,因为考虑到占用时间。

本文以连续发送4个字节为例,给出例程如下所示:本例程使用的单片机型号为:IAP15W4K58S//工作频率为11.0592MHz#include "reg51.h"#include "intrins.h"typedef unsigned char BYTE;typedef unsigned int WORD;#define FOSC 11059200L //系统频率//#define BAUD 115200 //#define BAUD 9600 //定义串口波特率#define Num_byte 4 //接收数据4个字节BYTE Data_temp[Num_byte]={0,0,0,0};sfr P0M1 = 0x93;sfr P0M0 = 0x94;sfr P1M1 = 0x91;sfr P1M0 = 0x92;sfr P2M1 = 0x95;sfr P2M0 = 0x96;sfr P3M1 = 0xb1;sfr P3M0 = 0xb2;sfr P4M1 = 0xb3;sfr P4M0 = 0xb4;sfr P5M1 = 0xC9;sfr P5M0 = 0xCA;sfr P6M1 = 0xCB;sfr P6M0 = 0xCC;sfr P7M0 = 0xE2;sfr AUXR = 0x8e; //辅助寄存器sfr T2H = 0xd6; //定时器2高8位sfr T2L = 0xd7; //定时器2低8位sfr P_SW1 = 0xA2; //外设功能切换寄存器1sbit LED1=P1^1;sbit LED2=P1^2;bit busy=0; //定义是否接收完4个字节BYTE num=0; //记录4个字节的数据void SendData(BYTE dat);void SendString(char *s);BYTE read_Byte();void delay();void main(){P0M0 = 0x00;P0M1 = 0x00;P1M0 = 0x00;P1M1 = 0x00;P2M0 = 0x00;P2M1 = 0x00;P3M0 = 0x00;P3M1 = 0x00;P4M0 = 0x00;P4M1 = 0x00;P5M0 = 0x00;P5M1 = 0x00;P6M0 = 0x00;P7M0 = 0x00;P7M1 = 0x00;P_SW1 &= 0x3F; //(P3.0/RxD, P3.1/TxD)SCON = 0x50; //8位可变波特率,允许接收T2L = (65536 - (FOSC/4/BAUD)); //设置波特率重装值T2H = (65536 - (FOSC/4/BAUD))>>8;AUXR = 0x15; //T2为1T模式, 并启动定时器2,选择定时器2为串口1的波特率发生器ES = 1; //使能串口1中断EA = 1;//SendString("STC15F2K60S2\r\nUart Test !\r\n");while(1){if(busy){ES=0;for(num=0;num<Num_byte;num++){SBUF= Data_temp[num]+0x05;while(!TI);TI=0;}num=0;ES=1;busy=0;}//SendData(3);//delay();//delay();;}/*----------------------------UART 中断服务程序-----------------------------*/void Uart() interrupt 4 using 1{ES=0;RI = 0; //清除RI位Data_temp[num++]= SBUF;if(num==Num_byte)busy=1;ES=1;}/*----------------------------发送串口数据----------------------------*/void SendData(BYTE dat){while (busy); //等待前面的数据发送完成SBUF = dat; //写数据到SBUF寄存器busy = 1;}/*----------------------------发送字符串----------------------------*/void SendString(char *s){while (*s) //检测字符串结束标志{SendData(*s); //发送当前字符s++;}//接收1个字节BYTE read_Byte(){ BYTE character;character = SBUF;return character;}void delay(){ BYTE i,j;for(i=220;i--;i>0)for(j=220;j--;j>0); }。

51单片机串口通信(相关例程)

51单片机串口通信(相关例程)

51单片机串口通信1./*打开串口调试程序,将波特率设置为9600,无奇偶校验晶振11.0592MHz,发送和接收使用的格式相同,如都使用字符型格式,在发送框输入hello,I Love MCU ,在接收框中同样可以看到相同字符,说明设置和通信正确*/#include <REG52.H>/*主程序*/void main (void){SCON = 0x50; /* SCON: 模式1, 8-bit UART, 使能接收*/TMOD |= 0x20; /* TMOD: timer 1, mode 2,8-bit reload*/TH1 = 0xFD; /* TH1: **********************************/ TR1 = 1; /* TR1: timer 1 run */EA = 1; /*打开总中断*/ES = 1; /*打开串口中断*/while (1) /*主循环不做任何动作*/{}}void UART_SER (void) interrupt 4 //串行中断服务程序{unsigned char Temp; //定义临时变量if(RI) //判断是接收中断产生{RI=0; //标志位清零Temp=SBUF; //读入缓冲区的值P1=Temp; //把值输出到P1口,用于观察SBUF=Temp; //把接收到的值再发回电脑端}if(TI) //如果是发送标志位,清零TI=0;}2.51单片机与电脑串口通信的C程序,最好是中断方式的#include <reg51.h>#include <string.h>unsigned char ch;bit read_flag= 0 ;void init_serialcom( void ) //串口通信初始设定{SCON = 0x50 ; //UART为模式1,8位数据,允许接收TMOD |= 0x20 ; //定时器1为模式2,8位自动重装PCON |= 0x80 ; //SMOD=1;TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHzIE |= 0x90 ; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}//向串口发送一个字符void send_char_com( unsigned char ch){SBUF=ch;while (TI== 0);TI= 0 ;}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 ; //取数标志清0send_char_com(ch);}}}3.// 单片机串行口发送/接收程序,每接收到字节即发送出去// 和微机相接后键入的字符回显示在屏幕上// 可用此程序测试#include <reg51.h>#define XTAL 11059200 // CUP 晶振频率#define baudrate 9600 // 通信波特率void main(void){unsigned char c;TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器0赋初值SCON = 0x50;PCON = 0x00;TR1 = 1;IE = 0x00; // 禁止任何中断{while(RI == 0);RI = 0;c = SBUF; // 从缓冲区中把接收的字符放入c中SBUF = c; // 要发送的字符放入缓冲区while(TI == 0);TI = 0;}}4.//////////////// ///////////////////////////////////////////////////////////E51Pro.c//Easy 51Pro编程器主程序,负责通讯,管理编程操作/////////////////////////////////////////////////////////////////////////#include <E51Pro.h>BYTE ComBuf[18];//串口通讯数据缓存,发送和接收都使用UINT nAddress;//ROM中地址计数UINT nTimeOut;//超时计数ProWork pw;//编程器一般操作void Delay_us(BYTE nUs)//微秒级延时<255us{TH0=0;TL0=0;TR0=1;while(TL0<nUs)//利用T0做定时计数器,循环采样,直到达到定时值{}TR0=0;}void Delay_ms(UINT nMs)//豪秒级的延时<65535ms{UINT n=0;TR0=1;while(n<nMs)////利用T0做定时计数器,循环采样,直到达到定时值{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOL WaitComm()//等待上位机的命令,18字节{RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return 0;}ComBuf[n]=SBUF;RI=0;}return 1;}BOOL WaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return 0;}}RI=0;ComBuf[0]=SBUF;return 1;}BOOL WaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTE n;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return 0;}}RI=0;ComBuf[n]=SBUF;}return 1;}void SendData()//发送数据或回应操作完成,18字节{BYTE n=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}void SendResp()//回应上位机1个字节,在写器件函数中使用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}void SetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}void SetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}void SetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}void RstPro()//编程器复位{pw.fpProOver();//直接编程结束SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同}void ReadSign()//读特征字{pw.fpReadSign();SendData();//通知上位机,送出读出器件特征字}void Erase()//擦除器件{pw.fpErase();SendData();//通知上位机,擦除了器件}void Write()//写器件{BYTE n;pw.fpInitPro();//编程前的准备工作SendData();//回应上位机表示进入写器件状态,可以发来数据while(1){if(WaitData())//如果等待数据成功{if(ComBuf[0]==0x07)//判断是否继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!pw.fpWrite(ComBuf[n]))//<<< <<<<<<调用写该器件一个单元的函数{pw.fpProOver();//出错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据出错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}else if(ComBuf[0]==0x00)//写器件结束break;else//可能是通讯出错了{pw.fpProOver();return;}}else//等待数据失败{pw.fpProOver();return;}}pw.fpProOver();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Read()//读器件{BYTE n;pw.fpInitPro();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}else if(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块{ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}pw.fpProOver();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Lock()//写锁定位{pw.fpLock();SendData();}///////////////////////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加/////////////////////////////////////////////////////////////////////////////extern void PreparePro00();//FID=00:AT89C51编程器extern void PreparePro01();//FID=01:AT89C2051编程器extern void PreparePro02();//FID=02:AT89S51编程器void main(){SP=0x60;SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0// 0 0 1 0 0 0 0 1TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI// 0 1 0 1 0 0 0 0SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//如果超时,通讯出错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针{case 0: //at89c51编程器PreparePro00(); break;case 1: //at89c2051编程器PreparePro01(); break;case 2: //at89s51编程器PreparePro02(); break;//case 3:支持新器件时,请继续向下添加// break;//case 4:// break;default: ComBuf[0]=0xff;ComBuf[1]=0xff; //表示无效的操作break;}switch(ComBuf[0])//根据操作ID跳到不同的操作函数{case 0x00:RstPro();break; / /编程器复位case 0x01:ReadSign();break; //读特征字case 0x02:Erase();break;//擦除器件case 0x03:Write();break;//写器件case 0x04:Read();break;//读器件case 0x05:Lock();break;//写锁定位default: SendData();break;}}}5.v oid InitSerial(void){TMOD = 0x20; // T1 方式2PCON=0x00; // PCON=00H,SMOD=0 PD = PCON.2 = 1 进入掉电模式TH1 = TL1 = BAUD_9600; // BAUD: 9600SCON = 0x50; // 串行通信方式1 REN=1 允许接收ET1 = 0; // 不允许中断TR1 = 1; // 开启定时器1IE = 0; // 关闭所有中断允许位memset(&SerialBuf, 0x00, SERIAL_BUF_LEN); // 初始化SerialBuf[SERIAL_BUF_LEN] }/**********************************************************名称:SendByte()**功能:串口发送一个字节**输入:ucData**返回:无**说明:无********************************************************/void SendByte(unsigned char ucData){SBUF = ucData;while(!TI){_CLRWDT_;}TI = 0;}RS232串口通信程序#include <AT89X52.H>unsigned char code dispcode1[]={" welcome! "}; unsigned char code dispcode2[]={""}; unsigned char i,j,k,l,DData;sbit RS = P3^5;sbit RW = P3^6;sbit E = P3^7;unsigned char m=0;void delay(){for(l=0;l<=100;l++){}}void enable() //write order{RS=0;RW=0;E=0;delay();E=1;}void enable2() //write data{RS=1;RW=0;E=0;delay();E=1;}void initializtion() //lcd initializtion{for(i=0;i<=100;i++)P0=0x01;enable();P0=0x38;enable();P0=0x0f;enable();P0=0x06;enable();}void Display(m,DData) // display data{P0=0xC0+m; //write addressenable();P0=DData; //write dataenable2();}void Esisr() interrupt 4 //串口接收中断服务程序{unsigned char temp;ES=0;if(RI == 1){RI = 0;temp = SBUF; //接收数据SBUF=temp; //将接收到的数据发送至PC机Display(m,temp); //将接收到的数据送LCD显示while(!TI); //等待数据发送完成TI=0;m++;if(m>16)m=0;}ES=1;}void system_initial(void) //system initializtion{TMOD=0x21;// 定时器1工作方式2,定时器0工作方式1PCON=0x00;//数据传输率选择。

51单片机串行通讯

51单片机串行通讯

51单片机串行通讯在当今的电子世界中,单片机的应用无处不在,从家用电器到工业自动化,从智能仪表到航空航天,都能看到它的身影。

而在单片机的众多功能中,串行通讯是一项非常重要的技术。

首先,咱们来了解一下什么是串行通讯。

简单来说,串行通讯就是指数据一位一位地按顺序传送。

与并行通讯(数据的各位同时传送)相比,串行通讯虽然速度相对较慢,但它只需要少数几条线就能完成数据传输,大大降低了硬件成本和连线的复杂性。

51 单片机的串行通讯有两种工作方式:同步通讯和异步通讯。

异步通讯是比较常用的一种方式。

在异步通讯中,数据是以字符为单位进行传输的。

每个字符由起始位、数据位、奇偶校验位和停止位组成。

起始位是一个低电平信号,用于通知接收方数据即将开始传输。

数据位通常是 5 到 8 位,可以表示一个字符的信息。

奇偶校验位用于检验传输数据的正确性,而停止位则是高电平,标志着一个字符传输的结束。

同步通讯则是在发送和接收两端使用同一个时钟信号来控制数据的传输。

这种方式传输速度快,但硬件要求相对较高。

51 单片机的串行口结构包括发送缓冲器和接收缓冲器。

发送缓冲器只能写入不能读出,而接收缓冲器只能读出不能写入。

在进行串行通讯时,我们需要对 51 单片机的串行口进行初始化设置。

这包括设置波特率、数据位长度、奇偶校验位和停止位等参数。

波特率是指每秒传输的位数,它决定了数据传输的速度。

通过设置定时器 1 的工作方式和初值,可以得到不同的波特率。

在编程实现串行通讯时,我们可以使用查询方式或者中断方式。

查询方式相对简单,但会占用大量的 CPU 时间,影响系统的实时性。

中断方式则可以在数据接收或发送完成时触发中断,提高系统的效率。

比如说,我们要实现 51 单片机与 PC 机之间的串行通讯。

在 PC 端,我们可以使用串口调试助手等软件来发送和接收数据。

在单片机端,通过编写相应的程序,设置好串行口的参数,然后根据接收的数据执行相应的操作,或者将需要发送的数据发送出去。

51单片机_串口通信、秒表

51单片机_串口通信、秒表

《51系列单片机_串口通信》源文件此程序使用单片机89SC52//1.说明:首先由上位机发送一个字符数据给单片机,单片机接收到字符数据后产生中断,由中断程序将接收到的字符存储到tmp中// 然后由单片机将字符串"Get the char: "和接收到的字符发送给上位机#include<reg52.h>char str[]=" Get the char: ", flag, tmp;//串行通信初始化void init(){ //设置通信波特率TMOD = 0x20; //设置T1定时器工作于方式2(8位计数自动重装)TH1 = TL1 = 0xfd; //此计数初值,使得晶振11.0592MHZ串口通信方式1产生波特率9600bps的通信速率TR1 = 1; //开启定时器1//设置串行通信模式SCON = 0x50; //01(设置串行口工作于10位数据异步通信) 01(允许串行口接收数据) 0000EA = 1; //开总中断ES = 1; //开串行口中断}//发送字符cvoid send(char c){SBUF = c; //将字符c存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1TI = 0; //发送完成后将TI请0}//发送字符串strvoid sendS(char str[]){int i=0;while(str[i++]!=0) //字符串未到达结尾时,发送字符{SBUF = str[i]; //将字符str[i]存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1TI = 0; //发送完成后将TI请0}}//使用串行口中断接收数据void ser_Int() interrupt 4 //串行口中断,接收完数据(RI置1) 或发送完数据(TI置1)时,产生中断{tmp = SBUF; //将接收到的数据放入tmp中保存flag = 1; //标志位置1,表示接收到新数据RI = 0; //接收完数据,清除中断标志}void main(){init(); //串行口初始while(1){if(flag==1) //当接收到新数据tmp时,将字符串str[]="Get the char: " 和tmp一起发送给上位机{ES = 0; //发送数据时暂时关闭串口中断,使得数据发送完成时不进入串口中断,串口中断在此程序中即用于接收数据sendS(str); //发送字符串strsend(tmp); //发送字符tmpES = 1; //数据发送完成重启串口中断flag = 0; //标志位清0}}}//2.串口通信应用秒表简单记录秒数值//说明:上位机发送一个字符数据'S'或者'C'给单片机,单片机根据接收到的字符数据控制定时器T0进行计时和暂停操作,并将计数值用数码管加以显示#include<reg52.h>#define iniNum 45872 //晶振频率为11.0592计时50ms的计数值int num, count;char str[]=" 'S' to start or stop the timer; 'C' to continue timing ", flag, tmp;void delay_ms(unsigned int n){ //软件延时函数,延时n毫秒unsigned int i, j;for(i=n;i>0;i--)for(j=110;j>0;j--);}void display(int num,int rep) //控制数码管按位输出显示数值num,显示时间为2*rep 毫秒{char BitSet[8] ={0x7f, 0xbf, 0xdf, 0xef,0xf7, 0xfb, 0xfd, 0xfe}; //用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管char NumberCode[16] ={0x3f, 0x06, 0x5b, 0x4f,0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71,}; //用于设置(共阴极)数码管的段选信号,从0~f共16个数值int n, r = rep, i;while(r-- > 0){n = num;i = 0;while(n>=0){P0 = 0xff; //关闭数码管当前位的显示,共阳极关闭显示段选信号P2 = BitSet[i]; //选中数码管对应的位P0 = ~NumberCode[n%10]; //向数码管的对应位中送入该位数值对应的段选信号delay_ms(2); //每一位延时显示2msP2 = 0xff; //关闭所有位选i++; //位标记n=n/10; //取数值n的商if(n==0) break; //当取得的商为0时退出while循环}}}//发送字符cvoid send(char c){SBUF = c; //将字符c存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1TI = 0; //发送完成后将TI请0}//发送字符串strvoid sendS(char str[]){int i=0;while(str[i++]!=0) //字符串未到达结尾时,发送字符{SBUF = str[i]; //将字符str[i]存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1TI = 0; //发送完成后将TI请0}}void int_T0() interrupt 1 //定时器T0中断,此程序中用于计时{count++;TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256;}//使用串行口中断接收数据void ser_Int() interrupt 4 //串行口中断,接收完数据(RI置1) 或发送完数据(TI置1)时,产生中断{tmp = SBUF; //将接收到的数据放入tmp中保存flag = 1; //标志位置1,表示接收到新数据RI = 0; //接收完数据,清除中断标志}void main(){TMOD = 0x21; //设置T1定时器工作于方式2(8位计数自动重装),T0定时器工作于方式方式1(16位定时计数)//设置通信波特率TH1 = TL1 = 0xfd; //此计数初值,使得晶振11.0592MHZ串口通信方式1产生波特率9600bps的通信速率TR1 = 1; //开启定时器1//设置串行通信模式SCON = 0x50; //01(设置串行口工作于10位数据异步通信) 01(允许串行口接收数据) 0000EA = 1; //开总中断ES = 1; //开串行口中断//为定时器0装入初值TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256; //计iniNum数,每次计时50msET0=1; //开定时器0中断ES = 0; //发送数据时暂时关闭串口中断sendS(str); //发送操作提示字符串,给出提示信息ES = 1; //数据发送完成重启串口中断while(1){if(flag==1) //当接收到新数据tmp时{ES = 0; //发送数据时暂时关闭串口中断,使得数据发送完成时不进入串口中断,串口中断在此程序中即用于接收数据//开始计时if(tmp=='S' | tmp=='s'){if(TR0==0) //当计时器停止时启动计时{num=0; //计数值清0,计数器重装初值TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256;TR0=1; //启动定时器0,进行计时sendS(" the tiner started ");}if(TR0==1) //当计时器已经启动时{TR0=0; //暂停计时sendS(" the tiner paused ");}}//继续计时else if(tmp=='C' | tmp=='c'){TR0=1; //启动定时器0,继续计时sendS(" tiner continue ");}else sendS(str);//发送操作提示字符串ES = 1; //数据发送完成重启串口中断flag = 0; //标志位清0}if(count==20) //每20次中断即每1s,处理一次{num++; //显示数值加1count=0;P1=~P1; //指示灯状态取反}display(num, 1); //用数码管输出显示num}}//3.串口通信应用秒表按时分秒格式显示//说明:上位机发送一个字符数据'S'或者'C'给单片机,单片机根据接收到的字符数据控制定时器T0进行计时和暂停操作,并将计数值用数码管加以显示#include<reg52.h>#define iniNum 45872 //晶振频率为11.0592计时50ms的计数值int count, time[4]=0;char str[]=" 'S' to start or stop the timer; 'C' to continue timing ", flag, tmp;void delay_ms(unsigned int n){ //软件延时函数,延时n毫秒unsigned int i, j;for(i=n;i>0;i--)for(j=110;j>0;j--);}void timer_display(int time[], int rep)//控制数码管按位输出显示time数组中的时分秒值数值,显示时间为2*rep 毫秒{char BitSet[8] ={0x7f, 0xbf, 0xdf, 0xef,0xf7, 0xfb, 0xfd, 0xfe}; //用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管char NumberCode[16] ={0x3f, 0x06, 0x5b, 0x4f,0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71,}; //用于设置(共阴极)数码管的段选信号,从0~f共16个数值int n, r = rep, i, j, zero=0;while(r-- > 0){i = 0;for(j=3; j>=0; j--){n = time[j];if((j==2|j==1|j==0) & time[j]<10) zero=1;//当时、分、秒三位的数值小于10时,显示对应数值后在高位添加一个0while(n>=0){P0 = 0xff; //关闭数码管当前位的显示,共阳极关闭显示段选信号P2 = BitSet[i]; //选中数码管对应的位if(i==1|i==3|i==5){ //在数码管倒数第1,3,5(时,分,秒)三个位置的数值后加上小数点P0 = ~(NumberCode[n%10]+0x80);}else{ //向数码管的对应位中送入该位数值对应的段选信号P0 = ~NumberCode[n%10];}delay_ms(2); //每一位延时显示2msP2 = 0xff; //关闭所有位选i++; //位标记n=n/10; //取数值n的商if(n==0) break;//当取得的商为0时退出while循环}if(zero==1) //在数码管高位添加0{P0 = 0xff; //关闭数码管显示P2 = BitSet[i]; //选中数码管对应的位P0 = ~NumberCode[0]; //显示数值0delay_ms(2); //每一位延时显示2msP2 = 0xff; //关闭所有位选i++; //位标记zero=0;}}}}//发送字符cvoid send(char c){SBUF = c; //将字符c存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1 TI = 0; //发送完成后将TI请0}//发送字符串strvoid sendS(char str[]){int i=0;while(str[i++]!=0) //字符串未到达结尾时,发送字符{SBUF = str[i]; //将字符str[i]存入SBUF中,由CPU自行发送while(!TI); //等待发送完毕,发送完成时TI会被置1TI = 0; //发送完成后将TI请0}}void int_T0() interrupt 1 //定时器T0中断,此程序中用于计时{count++;TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256;}//使用串行口中断接收数据void ser_Int() interrupt 4 //串行口中断,接收完数据(RI置1) 或发送完数据(TI置1)时,产生中断{tmp = SBUF; //将接收到的数据放入tmp中保存flag = 1; //标志位置1,表示接收到新数据RI = 0; //接收完数据,清除中断标志}void main(){TMOD = 0x21; //设置T1定时器工作于方式2(8位计数自动重装),T0定时器工作于方式方式1(16位定时计数)//设置通信波特率TH1 = TL1 = 0xfd; //此计数初值,使得晶振11.0592MHZ串口通信方式1产生波特率9600bps的通信速率TR1 = 1; //开启定时器1//设置串行通信模式SCON = 0x50; //01(设置串行口工作于10位数据异步通信) 01(允许串行口接收数据) 0000EA = 1; //开总中断ES = 1; //开串行口中断//为定时器0装入初值TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256; //计iniNum数,每次计时50msET0=1; //开定时器0中断ES = 0; //发送数据时暂时关闭串口中断sendS(str); //发送操作提示字符串,给出提示信息ES = 1; //数据发送完成重启串口中断while(1){if(flag==1) //当接收到新数据tmp时{ES = 0; //发送数据时暂时关闭串口中断,使得数据发送完成时不进入串口中断,串口中断在此程序中即用于接收数据//开始计时if(tmp=='S' | tmp=='s'){if(TR0==0) //当计时器停止时启动计时{int i;for(i=0; i<4;i++) time[i]=0; //计数值清0,计数器重装初值TH0=(65536-iniNum)/256;TL0=(65536-iniNum)%256;TR0=1; //启动定时器0,进行计时sendS(" the tiner started ");}if(TR0==1) //当计时器已经启动时{TR0=0; //暂停计时sendS(" the tiner paused ");}}//继续计时else if(tmp=='C' | tmp=='c'){TR0=1; //启动定时器0,继续计时sendS(" tiner continue ");}else sendS(str);//发送操作提示字符串ES = 1; //数据发送完成重启串口中断flag = 0; //标志位清0}if(count==2) //每2次中断即每0.1s,处理一次{time[4]++; //秒表最低位(1/10秒)值加1if(time[4]==10) //进位{time[4]=0; //清零time[3]++; //秒进位if(time[3]==60){time[3]=0;time[2]++; //分进位if(time[2]==60){time[2]=0;time[1]++; //时进位}}}count=0;}timer_display(time, 1); //用数码管输出显示秒表计数值}}。

C51单片机和电脑串口通信电路图与源码

C51单片机和电脑串口通信电路图与源码

C51单片机和电脑串口通信电路图与源码51单片机有一个全双工的串行通讯口,所以单片机和电脑之间可以方便地进行串口通讯。

进行串行通讯时要满足一定的条件,比如电脑的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换,虽然也可以用几个三极管进行模拟转换,但是还是用专用芯片更简单可靠。

我们采用了三线制连接串口,也就是说和电脑的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。

这是最简单的连接方法,但是对我们来说已经足够使用了,电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。

串口通讯的硬件电路如上图所示在制作电路前我们先来看看要用的MAX232,这里我们不去具体讨论它,只要知道它是TTL和RS232电平相互转换的芯片和基本的引脚接线功能就行了。

通常我会用两个小功率晶体管加少量的电路去替换MAX232,可以省一点,效果也不错,下图就是MAX232的基本接线图。

按图7-3加上MAX232就可以了。

这大热天的拿烙铁焊焊,还真的是热气迫人来呀:P串口座用DB9的母头,这样就可以用买来的PC串口延长线进行和电脑相连接,也可以直接接到电脑com口上。

为了能够在电脑端看到单片机发出的数据,我们必须借助一个WINDOWS软件进行观察,这里我们利用一个免费的电脑串口调试软件。

本串口软件在本网站可以找到软件界面如上图,我们先要设置一下串口通讯的参数,将波特率调整为4800,勾选十六进制显示。

串口选择为COM1,当然将网站提供的51单片机实验板的串口也要和电脑的COM1连接,将烧写有以下程序的单片机插入单片机实验板的万能插座中,并接通51单片机实验板的电源。

串口实验的源程序如下所示:;这是一个S51单片机实验开发板向PC机的串口单向发送数据AF的演示程序;采用MAX232专用芯片作RS232/TTL电平转换.;通讯波特率为4800KBPS,只要按下一次K1(就是P3.6引脚变成低电平);就发送一个16进制的AF字符ORG 0000HMOV SCON,#50H;设置成串口1方式MOV TMOD,#20H;波特率发生器T1工作在模式2上MOV PCON,#80H;波特率翻倍为2400x2=4800BPSMOV TH1,#0F3H;预置初值(按照波特率2400BPS预置初值)MOV TL1,#0F3H;预置初值(按照波特率2400BPS预置初值)SETB TR1;启动定时器T1;以上完成通讯初始化设置WRIT:JB P3.6,$;判断K1是否按下,如果没有按下就等待ACALL DELAY10;延时10毫秒消触点抖动JB P3.6,WRIT;去除干扰信号JNB P3.6,$;等待按键松开MOV A,#0AFH;将16进制的字符AF发送到串口去MOV SBUF,A;将AF通过串口发送出去AJMP WRIT;10毫秒延时子程序DELAY10:MOV R4,#20D2:MOV R5,#248DJNZ R5,$DJNZ R4,D2RETEND;=============两机串口通讯程序(主机)===================== ; 功能: 使用串行中断,接收数据并显示; 硬件环境: 自制单片机实验板; 软件环境: 伟福 V3.20; Create date: 2004_07_26; First Modify: 2004_07_26; second Modify:; Last Modify: 2004_07_26; Author: Sujiande;;===========预定义===================LED0 EQU 40H ;预定义数码管LED1 EQU 41H ;预定义数码管LED2 EQU 42H ;预定义数码管LED3 EQU 43H ;预定义数码管LED4 EQU 44H ;预定义数码管LED5 EQU 45H ;预定义数码管LED6 EQU 46H ;预定义数码管LED7 EQU 47H ;预定义数码管SDA BIT P0.1 ; 定义数据线引脚定义SCL BIT P0.0 ; 定义时钟线引脚定义;---------------------------ORG 0000H ;主程序入口AJMP MAIN ;跳转到主程序ORG 0100H ;主程序在ROM中存放位置;===============主程序=====================MAIN:MOV LED0,#00H ;赋初值MOV LED1,#00HMOV LED2,#16 ;赋初值为16, 数码管显示代码为: 灭MOV LED3,#16MOV LED4,#16MOV LED5,#16MOV LED6,#16MOV LED7,#16;--------------------;MOV DPTR,#TABLE ; 赋显示代码首地址MOV R1,#00H ; 给R1赋初值00HACALL DISPLAY ; 调显示子程序MOV SP, #30H ; 给堆栈指针赋初值;--------------------------; 使用定时器1,作为波特率发生器,设定波特率=9600,; 定时器初值为:FAH; 串行控制器设置:SM0=0,SM1=1,SM2=0,REN=1,TB8=0,; RB8=0,TI=0,RI=0 即0101 0000B; 波特率加倍;-----------------------------MOV TMOD,#20H ;设置定时器1,工作方式2MOV TH1,#0FAh ;赋初值: FAMOV TL1,#0FAh ;赋初值: FAMOV SCON, #50h ;设置串行口控制寄存器MOV PCON, #80h ;设置电源控制寄存器, 让波特率加倍(2X) SETB TR1 ;启动定时;*****************主程序结束************************ LP8: MOV A,R1 ;将1的数据装到A中;-----------------------MOV SBUF,A ;将A的数据送到缓冲区JNB TI,$ ;等待数据发送完毕CLR TI ;清发送中断标志;-----------------------INC R1CJNE R1,#99,LP3MOV R1,#00HLP3: ACALL SEPERATE ;调拆分程序ACALL DISPLAY ;调显示子程序ACALL DELAY_1S ;调延时子程序AJMP LP8;=================拆分程序===================== SEPERATE: ANL A,#0Fh ;与操作得到个位数据MOV LED0,A ;个位送LED0MOV A,R1ANL A,#0F0H ;与操作得到十位数据SWAP AMOV LED1,A ;十位送LED1RET;===============显示子程序===================== DISPLAY:MOV DPTR,#TABLE ; 赋显示代码首地址MOV A,LED0 ;查表数据送AMOVC A,@A+DPTR ;查表,得到显示代码ACALL SHIFT ;调移位子程序MOV A,LED1MOVC A,@A+DPTRACALL SHIFTMOV A,LED2MOVC A,@A+DPTRACALL SHIFTMOV A,LED3MOVC A,@A+DPTRACALL SHIFTMOV A,LED4MOVC A,@A+DPTRACALL SHIFTMOV A,LED5MOVC A,@A+DPTRACALL SHIFTMOV A,LED6MOVC A,@A+DPTRACALL SHIFTMOV A,LED7MOVC A,@A+DPTRACALL SHIFTRET;---------显示代码表---------TABLE: DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H ;0,1,2,3,4,5,6,7,8,9, DB 50H,1CH,39H,16H,38H,78H, 0FFH,0FEH,0EFH ;10,11,12,13,14,15,灭,-;================移位子程序============================SHIFT: PUSH A ; 进栈暂存A值MOV R0,#8 ; 循环8次CLR C ;清进位标志CLR SCL ;时钟线,先钳位为0LP2: RLC AMOV SDA,CNOPNOPSETB SCLNOPNOPCLR SCLNOPNOPDJNZ R0,LP2POP A ; 出栈恢复A值RET;=============延时子程序===============DELAY_1S:MOV R7,#0ffHLOOP7: MOV R6,#0ffHLOOP6: NOPNOPNOPNOPNOPNOPDJNZ R6,LOOP6DJNZ R7,LOOP7RET;------------------------------END;=============两机串口通讯程序(从机)===================== ; 功能: 使用串行中断,接收数据并显示; 硬件环境: 自制单片机实验板; 软件环境: 伟福 V3.20; Create date: 2004_07_26; First Modify: 2004_07_26; second Modify:; Last Modify: 2004_07_26; Author: Sujiande;===========预定义===================LED0 EQU 40H ;预定义数码管LED1 EQU 41H ;预定义数码管LED2 EQU 42H ;预定义数码管LED3 EQU 43H ;预定义数码管LED4 EQU 44H ;预定义数码管LED5 EQU 45H ;预定义数码管LED6 EQU 46H ;预定义数码管LED7 EQU 47H ;预定义数码管SDA BIT P0.1 ; 定义数据线引脚定义SCL BIT P0.0 ; 定义时钟线引脚定义;---------------------------ORG 0000H ;主程序入口AJMP MAIN ;跳转到主程序ORG 0023H ;中断入口地址AJMP S_INT ;跳转到中断程序ORG 0100H ;主程序在ROM中存放位置;==============主程序========================MAIN:MOV LED0,#00H ;赋初值MOV LED1,#00HMOV LED2,#16 ;赋初值为16, 数码管显示代码为: 灭MOV LED4,#16MOV LED5,#16MOV LED6,#16MOV LED7,#16;------------------------------MOV DPTR,#TABLE ; 赋显示代码首地址ACALL DISPLAY ; 调显示子程序MOV SP, #30H ; 给堆栈指针赋初值;--------------------------------------------; 使用定时器1,作为波特率发生器,设定波特率=9600,; 定时器初值为:FAH; 串行控制器设置:SM0=0,SM1=1,SM2=0,REN=1,TB8=0,; RB8=0,TI=0,RI=0 即0101 0000B; 波特率加倍;---------------------------------------------MOV TMOD,#20H ;设置定时器1,工作方式2MOV TH1,#0FAh ;赋初值: FAMOV TL1,#0FAh ;赋初值: FAMOV SCON, #50h ;设置串行口控制寄存器MOV PCON, #80h ;设置电源控制寄存器, 让波特率加倍(2X);---------------------------------------SETB EA ; 启动总中断SETB ES ; 启动串行中断SETB TR1 ;启动定时AJMP $ ; 等待中断;*****************主程序结束************************;===============中断服务程序============================= S_INT:MOV R1, SBUF ;将缓冲区的数据送到R1ACALL SEPERATE ;调拆分程序ACALL DISPLAY ;调显示子程序CLR RI ;清接收中断标志RETI ;中断返回;=================拆分程序===================== SEPERATE: MOV A,R1ANL A,#0Fh ;与操作得到个位数据MOV LED0,A ;个位送LED0MOV A,R1ANL A,#0F0H ;与操作得到十位数据SWAP A ;MOV LED1,A ;十位送LED1RET;===============显示子程序======================MOV A,LED0 ;查表数据送AMOVC A,@A+DPTR ;查表,得到显示代码ACALL SHIFT ;调移位子程序MOV A,LED1MOVC A,@A+DPTRACALL SHIFTMOV A,LED2MOVC A,@A+DPTRACALL SHIFTMOV A,LED3MOVC A,@A+DPTRACALL SHIFTMOV A,LED4MOVC A,@A+DPTRACALL SHIFTMOV A,LED5MOVC A,@A+DPTRACALL SHIFTMOV A,LED6MOVC A,@A+DPTRACALL SHIFTMOV A,LED7MOVC A,@A+DPTRACALL SHIFTRET;---------显示代码表---------TABLE: DB 11H,0D7H,32H,92H,0D4H,98H,18H,0D3H,10H,90H ;0,1,2,3,4,5,6,7,8,9, DB 50H,1CH,39H,16H,38H,78H, 0FFH,0FEH,0EFH ;10,11,12,13,14,15,灭,-;================移位子程序============================SHIFT: PUSH A ; 进栈暂存A值MOV R0,#8 ; 循环8次CLR C ;清进位标志CLR SCL ;时钟线,先钳位为0LP2: RLC AMOV SDA,CNOPNOPSETB SCLNOPNOPCLR SCLNOPNOPDJNZ R0,LP2POP A ; 出栈恢复A值RET;=============延时子程序=============== DELAY_1S:MOV R7,#0ffHLOOP7: MOV R6,#0ffHLOOP6: NOPNOPNOPNOPNOPNOPDJNZ R6,LOOP6DJNZ R7,LOOP7RET;------------------------------END。

51单片机串口通信

51单片机串口通信

51单片机串口通信串行口通信是一种在计算机和外部设备之间进行数据传输的通信方式,其中包括了并行通信、RS-232通信、USB通信等。

而在嵌入式系统中,最常见、最重要的通信方式就是单片机串口通信。

本文将详细介绍51单片机串口通信的原理、使用方法以及一些常见问题与解决方法。

一、串口通信的原理串口通信是以字节为单位进行数据传输的。

在串口通信中,数据传输分为两个方向:发送方向和接收方向。

发送方将待发送的数据通过串行转并行电路转换为一组相对应的并行信号,然后通过串口发送给接收方。

接收方在接收到并行信号后,通过串行转并行电路将数据转换为与发送方发送时相对应的数据。

在51单片机中,通过两个寄存器来实现串口通信功能:SBUF寄存器和SCON寄存器。

其中,SBUF寄存器用于存储要发送或接收的数据,而SCON寄存器用于配置串口通信的工作模式。

二、51单片机串口通信的使用方法1. 串口的初始化在使用51单片机进行串口通信之前,需要进行串口的初始化设置。

具体的步骤如下:a. 设置波特率:使用波特率发生器,通过设定计算器的初值和重装值来实现特定的波特率。

b. 串口工作模式选择:设置SCON寄存器,选择串行模式和波特率。

2. 发送数据发送数据的过程可以分为以下几个步骤:a. 将要发送的数据存储在SBUF寄存器中。

b. 等待发送完成,即判断TI(发送中断标志位)是否为1,如果为1,则表示发送完成。

c. 清除TI标志位。

3. 接收数据接收数据的过程可以分为以下几个步骤:a. 等待数据接收完成,即判断RI(接收中断标志位)是否为1,如果为1,则表示接收完成。

b. 将接收到的数据从SBUF寄存器中读取出来。

c. 清除RI标志位。

三、51单片机串口通信的常见问题与解决方法1. 波特率不匹配当发送方和接收方的波特率不一致时,会导致数据传输错误。

解决方法是在初始化时确保两端的波特率设置一致。

2. 数据丢失当发送方连续发送数据时,接收方可能会出现数据丢失的情况。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机串口通信1./*打开串口调试程序,将波特率设置为9600,无奇偶校验晶振11.0592MHz,发送和接收使用的格式相同,如都使用字符型格式,在发送框输入hello,I Love MCU ,在接收框中同样可以看到相同字符,说明设置和通信正确*/#include <REG52.H>/*主程序*/void main (void){SCON = 0x50; /* SCON: 模式1, 8-bit UART, 使能接收*/TMOD |= 0x20; /* TMOD: timer 1, mode 2,8-bit reload*/TH1 = 0xFD; /* TH1: **********************************/ TR1 = 1; /* TR1: timer 1 run */EA = 1; /*打开总中断*/ES = 1; /*打开串口中断*/while (1) /*主循环不做任何动作*/{}}void UART_SER (void) interrupt 4 //串行中断服务程序{unsigned char Temp; //定义临时变量if(RI) //判断是接收中断产生{RI=0; //标志位清零Temp=SBUF; //读入缓冲区的值P1=Temp; //把值输出到P1口,用于观察SBUF=Temp; //把接收到的值再发回电脑端}if(TI) //如果是发送标志位,清零TI=0;}2.51单片机与电脑串口通信的C程序,最好是中断方式的#include <reg51.h>#include <string.h>unsigned char ch;bit read_flag= 0 ;void init_serialcom( void ) //串口通信初始设定{SCON = 0x50 ; //UART为模式1,8位数据,允许接收TMOD |= 0x20 ; //定时器1为模式2,8位自动重装PCON |= 0x80 ; //SMOD=1;TH1 = 0xFD ; //Baud:19200 fosc="11".0592MHzIE |= 0x90 ; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}//向串口发送一个字符void send_char_com( unsigned char ch){SBUF=ch;while (TI== 0);TI= 0 ;}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 ; //取数标志清0send_char_com(ch);}}}3.// 单片机串行口发送/接收程序,每接收到字节即发送出去// 和微机相接后键入的字符回显示在屏幕上// 可用此程序测试#include <reg51.h>#define XTAL 11059200 // CUP 晶振频率#define baudrate 9600 // 通信波特率void main(void){unsigned char c;TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器0赋初值SCON = 0x50;PCON = 0x00;TR1 = 1;IE = 0x00; // 禁止任何中断{while(RI == 0);RI = 0;c = SBUF; // 从缓冲区中把接收的字符放入c中SBUF = c; // 要发送的字符放入缓冲区while(TI == 0);TI = 0;}}4.//////////////// ///////////////////////////////////////////////////////////E51Pro.c//Easy 51Pro编程器主程序,负责通讯,管理编程操作/////////////////////////////////////////////////////////////////////////#include <E51Pro.h>BYTE ComBuf[18];//串口通讯数据缓存,发送和接收都使用UINT nAddress;//ROM中地址计数UINT nTimeOut;//超时计数ProWork pw;//编程器一般操作void Delay_us(BYTE nUs)//微秒级延时<255us{TH0=0;TL0=0;TR0=1;while(TL0<nUs)//利用T0做定时计数器,循环采样,直到达到定时值{}TR0=0;}void Delay_ms(UINT nMs)//豪秒级的延时<65535ms{UINT n=0;TR0=1;while(n<nMs)////利用T0做定时计数器,循环采样,直到达到定时值{TH0=0;TL0=20;while(TH0<4){}n++;}TR0=0;}BOOL WaitComm()//等待上位机的命令,18字节{RI=0;while(!RI){}//等待第一个字节ComBuf[n]=SBUF;RI=0;n++;for(n;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000)//后17个字节都有超时限制return 0;}ComBuf[n]=SBUF;RI=0;}return 1;}BOOL WaitResp()//等待上位机回应,1字节,有超时限制{nTimeOut=0;RI=0;while(!RI){nTimeOut++;if(nTimeOut>50000){return 0;}}RI=0;ComBuf[0]=SBUF;return 1;}BOOL WaitData()//写器件时等待上位机数据,18字节,有超时限制{BYTE n;RI=0;for(n=0;n<=17;n++){nTimeOut=0;while(!RI){nTimeOut++;if(nTimeOut>10000){return 0;}}RI=0;ComBuf[n]=SBUF;}return 1;}void SendData()//发送数据或回应操作完成,18字节{BYTE n=0;for(n;n<=17;n++){TI=0;SBUF=ComBuf[n];while(!TI){}TI=0;}}void SendResp()//回应上位机1个字节,在写器件函数中使用{TI=0;SBUF=ComBuf[0];while(!TI){}TI=0;}void SetVpp5V()//设置Vpp为5v{P3_4=0;P3_3=0;}void SetVpp0V()//设置Vpp为0v{P3_3=0;P3_4=1;}void SetVpp12V()//设置Vpp为12v{P3_4=0;P3_3=1;}void RstPro()//编程器复位{pw.fpProOver();//直接编程结束SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同}void ReadSign()//读特征字{pw.fpReadSign();SendData();//通知上位机,送出读出器件特征字}void Erase()//擦除器件{pw.fpErase();SendData();//通知上位机,擦除了器件}void Write()//写器件{BYTE n;pw.fpInitPro();//编程前的准备工作SendData();//回应上位机表示进入写器件状态,可以发来数据while(1){if(WaitData())//如果等待数据成功{if(ComBuf[0]==0x07)//判断是否继续写{for(n=2;n<=17;n++)//ComBuf[2~17]为待写入数据块{if(!pw.fpWrite(ComBuf[n]))//<<< <<<<<<调用写该器件一个单元的函数{pw.fpProOver();//出错了就结束编程ComBuf[0]=0xff;SendResp();//回应上位机一个字节,表示写数据出错了WaitData();//等待上位机的回应后就结束return;}nAddress++;//下一个单元}ComBuf[0]=1;//回应上位机一个字节,表示数据块顺利完成,请求继续SendResp();}else if(ComBuf[0]==0x00)//写器件结束break;else//可能是通讯出错了{pw.fpProOver();return;}}else//等待数据失败{pw.fpProOver();return;}}pw.fpProOver();//编程结束后的工作Delay_ms(50);//延时等待上位机写线程结束ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Read()//读器件{BYTE n;pw.fpInitPro();//先设置成编程状态SendData();//回应上位机表示进入读状态while(1){if(WaitResp())//等待上位机回应1个字节{if(ComBuf[0]==0)//ComBuf[0]==0表示读结束{break;}else if(ComBuf[0]==0xff)//0xff表示重发{nAddress=nAddress-0x0010;}for(n=2;n<=17;n++)//ComBuf[2~17]保存读出的数据块{ComBuf[n]=pw.fpRead();//<<<<<<<<<<调用写该器件一个单元的函数nAddress++;//下一个单元}ComBuf[0]=6;//向上位机发送读出的数据块SendData();}elsebreak;//等待回应失败}pw.fpProOver();//操作结束设置为运行状态ComBuf[0]=0;//通知上位机编程器进入就绪状态SendData();}void Lock()//写锁定位{pw.fpLock();SendData();}///////////////////////////////////////////////////////////////////////////////////所支持的FID,请在这里继续添加/////////////////////////////////////////////////////////////////////////////extern void PreparePro00();//FID=00:AT89C51编程器extern void PreparePro01();//FID=01:AT89C2051编程器extern void PreparePro02();//FID=02:AT89S51编程器void main(){SP=0x60;SetVpp5V();//先初始化Vpp为5vSCON=0x00;TCON=0x00;//PCON=0x00;//波特率*2IE=0x00;//TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0// 0 0 1 0 0 0 0 1TMOD=0x21;//T0用于延时程序TH1=0xff;TL1=0xff;//波特率28800*2,注意PCON//SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI// 0 1 0 1 0 0 0 0SCON=0x50;TR1=1;Delay_ms(1000);//延时1秒后编程器自举ComBuf[0]=0;SendData();while(1)//串口通讯采用查询方式{if(!WaitComm())//如果超时,通讯出错{Delay_ms(500);ComBuf[0]=0;//让编程器复位,使编程器就绪}switch(ComBuf[1])//根据FID设置(ProWork)pw中的函数指针{case 0: //at89c51编程器PreparePro00(); break;case 1: //at89c2051编程器PreparePro01(); break;case 2: //at89s51编程器PreparePro02(); break;//case 3:支持新器件时,请继续向下添加// break;//case 4:// break;default: ComBuf[0]=0xff;ComBuf[1]=0xff; //表示无效的操作break;}switch(ComBuf[0])//根据操作ID跳到不同的操作函数{case 0x00:RstPro();break; / /编程器复位case 0x01:ReadSign();break; //读特征字case 0x02:Erase();break;//擦除器件case 0x03:Write();break;//写器件case 0x04:Read();break;//读器件case 0x05:Lock();break;//写锁定位default: SendData();break;}}}5.v oid InitSerial(void){TMOD = 0x20; // T1 方式2PCON=0x00; // PCON=00H,SMOD=0 PD = PCON.2 = 1 进入掉电模式TH1 = TL1 = BAUD_9600; // BAUD: 9600SCON = 0x50; // 串行通信方式1 REN=1 允许接收ET1 = 0; // 不允许中断TR1 = 1; // 开启定时器1IE = 0; // 关闭所有中断允许位memset(&SerialBuf, 0x00, SERIAL_BUF_LEN); // 初始化SerialBuf[SERIAL_BUF_LEN] }/**********************************************************名称:SendByte()**功能:串口发送一个字节**输入:ucData**返回:无**说明:无********************************************************/void SendByte(unsigned char ucData){SBUF = ucData;while(!TI){_CLRWDT_;}TI = 0;}RS232串口通信程序#include <AT89X52.H>unsigned char code dispcode1[]={" welcome! "}; unsigned char code dispcode2[]={""}; unsigned char i,j,k,l,DData;sbit RS = P3^5;sbit RW = P3^6;sbit E = P3^7;unsigned char m=0;void delay(){for(l=0;l<=100;l++){}}void enable() //write order{RS=0;RW=0;E=0;delay();E=1;}void enable2() //write data{RS=1;RW=0;E=0;delay();E=1;}void initializtion() //lcd initializtion{for(i=0;i<=100;i++)P0=0x01;enable();P0=0x38;enable();P0=0x0f;enable();P0=0x06;enable();}void Display(m,DData) // display data{P0=0xC0+m; //write addressenable();P0=DData; //write dataenable2();}void Esisr() interrupt 4 //串口接收中断服务程序{unsigned char temp;ES=0;if(RI == 1){RI = 0;temp = SBUF; //接收数据SBUF=temp; //将接收到的数据发送至PC机Display(m,temp); //将接收到的数据送LCD显示while(!TI); //等待数据发送完成TI=0;m++;if(m>16)m=0;}ES=1;}void system_initial(void) //system initializtion{TMOD=0x21;// 定时器1工作方式2,定时器0工作方式1PCON=0x00;//数据传输率选择。

相关文档
最新文档