C51编程这是网友牛毅编的一个C51串口通讯程序!
51单片机的串口通信程序(C语言)
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
C51编写 串口通信程序
异步通信的数据格式 :
一个字符帧 空 闲 起 始 位 数据位 校 验 位 停 止 位 空 闲
下一字符 起始位
LSB
MSB
异步通信的特点:不要求收发双方时钟的 严格一致,实现容易,设备开销较小,但 每个字符要附加2~3位用于起止位,各帧 之间还有间隔,因此传输效率不高。
2、同步通信
同步通信时要建立发送方时钟对接收方时钟的直接控制, 使双方达到完全同步。此时,传输数据的位之间的距离均 为“位间隔”的整数倍,同时传送的字符间不留间隙,即 保持位同步关系,也保持字符同步关系。发送方对接收方 的同步可以通过两种方法实现。
串行通信是将数据字节分成一位一位的形 式在一条传输线上逐个地传送。
接 收 设 备
D0 D7
8位顺次传送
发 送 设 备
串行通信的特点:传输线少,长距离传送时 成本低,且可以利用电话网等现成的设备, 但数据的传送控制比并行通信复杂。
7.1.1 串行通信的基本概念
一、异步通信与同步通信
1、异步通信 异步通信是指通信的发送与接收设备使用各自的时钟 控制数据的发送和接收过程。为使双方的收发协调,要求 发送和接收设备的时钟尽可能一致。
面向位的同步格式 :
8位 01111110 8位 地址场 8位 控制场 ≥0位 信息场 16位 校验场 8位 01111110
此时,将数据块看作数据流,并用序列01111110作为开始 和结束标志。为了避免在数据流中出现序列01111110时引起 的混乱,发送方总是在其发送的数据流中每出现5个连续的1 就插入一个附加的0;接收方则每检测到5个连续的1并且其后 有一个0时,就删除该0。 典型的面向位的同步协议如ISO的高级数据链路控制规程 HDLC和IBM的同步数据链路控制规程SDLC。 同步通信的特点是以特定的位组合“01111110”作为帧的 开始和结束标志,所传输的一帧数据可以是任意位。所以传 输的效率较高,但实现的硬件设备比异步通信复杂。
Labview与C51单片机实现串口通信
Labview与C51单片机实现串口通信
Labview 串口通信学会两种方法,一种是利用visa(虚拟仪器软件构架),另一种是调用activeX 控件。
第一种方法(VISA)程序如图
首先,设置串口参数,串口初始化,循环内利用VISA WITE 实现对串口的写操作,延时200 毫秒,用VISA READ 实现读操作,中间有个端口属性节点的作用是计算端口的总的字节数。
非常简单,但我花了一天时间搞懂。
第二种方法调用active X 程序图如下所示
ACTIVE X 串口通信的最大优点是可以利用中断实现数据的传送或对下位机的控制,MSCOMM32 控件实现串口通信主要是通过对其属性节点的设置来实现的。
并利用到了事件回调方法实现中断程序。
tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。
51单片机通信协议
///////////////////////////////////////////////////////////////////// //函 数 名:HexToChar() //功能描述:把 16 进制转换为 ASCII 字符 //函数说明: //调用函数: //全局变量: //输 入:16 进制 //返 回:ASCII 字符 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// unsigned char HexToChar(unsigned char bHex) { if((bHex>=0)&&(bHex<=9))
//public 变量 unsigned char databuf[FIELD_MAXBUF],errframe_cnt; //函数
///////////////////////////////////////////////////////////////////// //函 数 名:send() //功能描述:向串口发送一个字符 //函数说明: //调用函数: //全局变量: //输 入:ch-要发送的 ASCII 字符 //返 回:无 //设 计 者:牛毅 //修 改 者: //版 本: ///////////////////////////////////////////////////////////////////// void send(unsigned char ch) { SBUF=ch; while(TI==0); TI=0; }
C51语言编程-单片机与 PC 串口通信程序
ucharidatatrdata3[]={
‘Y’,’I’,’N’,’G’,’Y’,’O’,’N’,’G’,’K’,’E’,’X’,’U’,’E’,’X’,’U’,’E’,’Y’,’U’,’A’,’N’,0x0
d,0x0a,0x00};
YINGYONGKEXUEXUEYUAN。
PC机上的串口调试软件,会在窗口显示出单片机送回来相应字符串;
如果接送的字符串不正确,单片机不响应。
采用html
//---------------------------------------------------------
TMOD=0x20;//T1定时方式2
TH1=0xfd;//波特率9600bps@fosc=11.0592MHz
TL1=0xfd;
TR1=1;//启动T1
ES=1;//开串口中断.
EA=1;//开总中断.
}
//---------------------------------------------------
voidUart_INT(void)interrupt4//串口中断函数
{
ucharTcv=0;
if(RI){//接收?.
RI=0;//标志位清零.
RxBuf[Rx_i]=SBUF;
if((RxBuf[Rx_i-1]==‘g’)&&(RxBuf[Rx_i]==‘o’))Rx_p=1;
ucharidatatrdata1[]={
‘W’,’E’,’L’,’C’,’O’,’M’,’E’,’‘,’T’,’O’,’
‘,’C’,’H’,’I’,’N’,’A’,’!’,0x0d,0x0a,0x00};
51单片机串口通信程序
51单片机串口通信程序51单片机是我国自主研发的一款微控制器,在国内广泛应用于各种电子设备中。
在很多应用场景中,需要通过串口进行通信,以实现数据传输。
本文将介绍51单片机串口通信程序的编写方法。
一、串口介绍串口是一种通信接口,用于在电子设备之间传输数据。
其主要特点是一条通信线路同时只能传输一位数据,因此称为串口。
串口和并口属于不同的通信接口标准。
串口的优点是具有通信距离远、传输速率快、可靠性高等优点,因此广泛应用于各种场合中。
串口有两种工作模式:同步模式和异步模式。
在实际应用中,异步串口通信更为常见。
二、异步串口通信原理在异步串口通信中,数据的传输是通过发送端和接收端的时钟信号不同步实现的。
在发送数据时,发送端会发出一个起始位,接下来是数据位,最后是一个或多个停止位。
在接收端,当检测到起始位时,开始接收数据。
根据通信协议,在接收完数据位后,接收端会判断是否正确,然后再结束本次通信。
1. 硬件连接在51单片机和电脑之间进行串口通信,需要用到串口转USB线。
将串口转USB线的TxD接口与51单片机的P3.1接口相连,RxD接口与P3.0接口相连。
此外,需要一个5V的电源供给51单片机。
2. 准备工作在编写程序之前,需要进行一些准备工作:(1)将P3口设为外部中断P3口的最低2位是外部中断的2个输入端,需要将它们设为中断输入。
EA=1;EX0=1;(2)设置波特率串口通信需要设置波特率。
常见的波特率有9600、19200、38400等。
对应的波特率常数为0xFD、0xFA、0xF4等。
TH1=0xFD;//波特率9600(3)使能串口中断在发送和接收数据时,会不断产生中断,需要将中断使能。
ES=1;//允许串口中断3. 编写程序(1)发送数据void SendData(unsigned char SendBuff[],unsigned int ULength){unsigned int i;for(i=0;i<ULength;i++){SBUF=SendBuff[i];//发送数据while(TI==0); //等待,直到发送完成TI=0;}}(2)接收数据(3)主函数TMOD|=0x20;//定时器1工作方式2TH1=0xFD;//波特率9600TR1=1;//打开定时器1SCON=0x50;//串口方式1,8位数据,无校验,1停止位EA=1;//开总中断ES=1;//开串口中断while(1){SendData(pSendData,4);//发送数据 RecvData(pRecvData,4);//接收数据if(pRecvData[0]=='K'){P0=0x01;//点亮LED}else{P0=0x00;//关闭LED}}}四、总结。
51串口通信程序带详细注释
51串口通信程序(带详细注释)#include;#include; //后面有一个比较函数#define uchar unsigned char#define uint unsigned intbit UART_Flag=0; //定义串口接收标志位uchar str[50];//定义一数组uchar length=0; //数组长度从0开始void init() //初始化uart{TMOD=0X20; //定时器1定时器方式工作模式2,可自动重载的8位计数器常把定时/计数器1以模式2作为串行口波特率发生器SCON=0X50; //选择工作模式1使能接收,允许发送,允许接收EA=1; //开总中断ES=1; //打开串口中断ET1=0; //打开定时器中断PCON=0X80; //8位自动重载,波特率加倍TH1=0XFF; //用22.1184 mhz波特率TL1=0XFF;TR1=1; //打开中时器}void UART_Putch(uchar dat) //输出一个字符{SBUF=dat; //把数据送给sbuf缓存器中while(TI!=1);//发送标志位 TI如果发送了为1,没发送为0,没发送等待,到了退出循环TI=0; //到了,TI清为0}void init1() interrupt 4 //uart中断,4为串口中断{if(RI==1) //收到数据{uchar m=SBUF; //m为计算机发送给串口的数据,例,open //总体思想是,计算机通知串口,我要发数据了RI=0;//收到清0if(m=='\r')//判断m这位数据有无\r{UART_Putch('\r'); //回车UART_Putch('\n'); // 换行str[length]='\0'; //数据最后位加0标志位表示发完了数据UART_Flag=1; // 传完标志位}else if(m=='\n'){}else if(m=='\b')//b表退格 //下面几句表删锄{UART_Putch('\b');UART_Putch(' ');UART_Putch('\b');length=length-1; //删锄了后总长度减一}else{str[length++]=m; //比如m为open,先传0后传p,length加一UART_Putch(m);//输出比如open}}}void check(char *str) //计算机发一数据,我来检查,{if( strcmp("open",str)==0 ) //比较两数是否相同,相同为0,不同为1 //要加string.h头文件{UART_Putch('o'); //计算机中写入open我回复ok UART_Putch('k');UART_Putch('\r'); //回车是跑到这一行的最前UART_Putch('\n'); //换行是跳到下一行}else if( strcmp("close",str)==0 ) {UART_Putch('o');UART_Putch('k');UART_Putch('\r');UART_Putch('\n'); }else//否则出错{UART_Putch('e'); UART_Putch('r');UART_Putch('r');UART_Putch('o');UART_Putch('r');UART_Putch('!'); UART_Putch('\r'); UART_Putch('\n'); }}void main(){init();while(1){if(UART_Flag==1) //接收标志位表示接收完成 {check(str);//检查length=0; //长度清0UART_Flag=0;//标志位清0}}}。
c51串口通信原理
c51串口通信原理
C51串口通信的原理主要涉及到串行数据传输的方式。
在C51中,串口通
信可以通过串行数据通信模式进行,包括单工通信、半双工通信和全双工通信。
在串行通信中,数据是一位一位地进行传输的。
每一位数据在传输中都占据一个固定的时间长度。
串行通信的一个主要优点是传输线少,占用引脚资源少,成本低,适合远距离传送。
具体到C51的串口通信,其工作方式可以分为方式0、方式1等。
在方式0时,串行口作为同步移位寄存器的输入输出方式,数据由RXD()引脚输
入或输出,同步移位脉冲由TXD()引脚输出。
发送和接收均为8位数据,低位在先,高位在后。
在方式1时,它是10位数据的异步通信口,TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式包括1位起始位、8位数据位和1位停止位。
此外,关于串行口的波特率,PCON中有一位SMOD与串行口工作有关:SMOD()波特率倍增位。
在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。
复位时,SMOD=0。
以上是C51串口通信的基本原理,如需了解更多信息,建议咨询专业技术人员或查阅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。
C51单片机串口通讯通用模块代码(可用于操作系统串口通讯)
C51单片机串口通讯通用模块代码(可用于操作系统串口通讯)#include#include "UART1.h"#include "commdriver.h"//当前适用于C51//可以根据具体CPU型号,修改宏定义和串口初始化代码就可以#define CPU_XTAL 22118400 //CPU频率#define FUNCTION_NULL 0 //没有定义函数#define COM_TI TI //发送中断寄存器#define COM_TI0() {TI = 0;} //发送中断寄存器清零#define COM_TI1() {TI = 1;} //发送中断寄存器置一( 强行置一触发发送中断)#define COM_TI_SBUF(dat) {SBUF = dat;} //发送数据到硬件缓冲区#define COM_TI_End() {return;} //发送结束处理函数#define COM_RI RI //接收中断寄存器#define COM_RI0() {RI = 0;} //接收中断寄存器清零#define COM_RI1() {RI = 1;} //接收中断寄存器置一#define COM_RI_SBUF(dat) {dat = SBUF;} //提取接收硬件缓冲区数据#define COM_TI_FLAG COM_TI //发送中断标志寄存器(非中断发送方式使用)#define COM_TI_FLAG0() COM_TI0() //发送中断标志寄存器清零(非中断发送方式使用)void (*COM1RevEvent)(unsigned char dat); //数据接收事件#define LenTxBuf 30 //发送缓冲区长度#define LenRxBuf 1 //接收缓冲区长度volatile unsigned char TxBuf1[LenTxBuf],RxBuf1[LenRxBuf]; //收发缓冲区实体volatile unsigned char *inTxBuf1,*outTxBuf1,*inRxBuf1,*outRxBuf1; //收发缓冲区读写指针volatile unsigned char TIflag1=1;//Note:It must be 1. //发送缓冲区为空标志//*********************#define _TxBuf TxBuf1#define _RxBuf RxBuf1#define _inTxBuf inTxBuf1#define _outTxBuf outTxBuf1#define _inRxBuf inRxBuf1#define _outRxBuf outRxBuf1#define _TIflag TIflag1/*************函数声明****************/#define _COMRevEvent COM1RevEvent //串口接收事件#define _USART_IRQ void USART1_IRQHandler(void) interrupt 4 //串口中断服务程序#define _COM_Buffer_Init void COM1_Buffer_Init(void) //串口缓冲区初始化#define _COM_Open void COM1_Open(unsigned int baudrate,void (*revevent)(unsigned char dat)) // 串口初始化#define _COM_Close void COM1_Close(void) //关闭串口#define _COM_GetOneByte unsigned charCOM1_GetOneByte(unsigned char *ch) //获取一个字节#define _COM_GetPChar unsigned char COM1_GetPChar(unsigned char *ch,unsigned char len) //获取指定长度字节数组#define _COM_RxByte unsigned char COM1_RxByte(void) //获取接收字节个数//********缓冲区中断方式发送(安全性高)#define _COM_SendOneByte unsigned char COM1_SendOneByte(unsigned char one_byte) // 发送一个字节#define _COM_SendPChar void COM1_SendPChar(unsigned char *P,unsigned char Len) //发送定长字节数组#define _COM_SendString void COM1_SendString(unsigned char *P) //发送字符串//********非缓冲区中断方式发送#define _COM_PrintOneByte void COM1_PrintOneByte(unsigned char c) // 发送一个字节#define _COM_PrintPChar void COM1_PrintPChar(unsigned char *buf,unsigned int len) //发送定长字节数组#define _COM_PrintString void COM1_PrintString(unsigned char *P) //发送字符串//*************内部引用模型函数(外部不关心,移植时修改后面函数名,要与上面对应的外部声明的函数名一致)*******************#define COM_GetOneByte_(ptr) COM1_GetOneByte(ptr) //与上面获取一个字节的函数对应#define COM_SendOneByte_(dat) COM1_SendOneByte(dat) //与上面发送一个字节的函数对应#define COM_PrintOneByte_(dat) COM1_PrintOneByte(dat) //与上面发送一个字节的函数对应//*********************函数模型定义区(不需要修改)*****************/****************************函数模型:void USART_IRQHandler(void)函数功能:串口中断服务程序入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_USART_IRQ //串口1中断{volatile unsigned char *t;if(COM_RI){COM_RI0(); //清接收标记if(_COMRevEvent != FUNCTION_NULL) //自定义接收事件{COM_RI_SBUF(*_inRxBuf);_COMRevEvent(*_inRxBuf);}else{t = _inRxBuf;t++;if(t == (_RxBuf + LenRxBuf)) t = _RxBuf;if(t != _outRxBuf) //RxBuf No Full{COM_RI_SBUF(*_inRxBuf);_inRxBuf = t;}}}if(COM_TI){COM_TI0();if(_inTxBuf == _outTxBuf) {_TIflag = 1;COM_TI_End();};//TxBuf1 EmptyCOM_TI_SBUF(*_outTxBuf); _outTxBuf++;if(_outTxBuf == (_TxBuf+LenTxBuf)) _outTxBuf = _TxBuf;}}/****************************函数模型:void COM1_Buffer_Init(void)函数功能:串口1缓冲区初始化入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Buffer_Init{_inTxBuf = _TxBuf;_outTxBuf = _TxBuf;_inRxBuf = _RxBuf;_outRxBuf = _RxBuf;}/****************************函数模型:void COM_Open(unsigned int baudrate,void (*revevent)(unsigned char dat))函数功能:系统串口初始化入口参数: unsigned int baudrate:串口波特率返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Open{//定时器1做波特率发生器TI = 0; /* clear transmit interrupt */TR1 = 0; /* stop timer 1 */ET1 = 0; /* disable timer 1 interrupt */PCON |= 0x80; /* 0x80=SMOD: set serial baudrate doubler */ TMOD &= ~0xF0; /* clear timer 1 mode bits */TMOD |= 0x20; /* put timer 1 into MODE 2 */TH1 = (unsigned char) (256 - (CPU_XTAL / (16L * 12L * baudrate)));TR1 = 1; /* start timer 1 *///设置串口1模式SM0 = 0; SM1 = 1; /* serial port MODE 1 */SM2 = 0;REN = 1; /* enable serial receiver */RI = 0; /* clear receiver interrupt */TI = 0; /* clear transmit interrupt */ES = 1; /* enable serial interrupts */PS = 1; /* set serial interrupts to low priority */_COMRevEvent = revevent;}/****************************函数模型:void COM1_Close(void)函数功能:关闭系统串口入口参数:无返回值:无修改者:修改时间:修改内容简要:***************************/_COM_Close{}/****************************函数模型:unsigned char COM1_GetOneByte(unsigned char *ch)函数功能:获取一个字节入口参数:unsigned char *ch:接收字节指针返回值: unsigned char *ch:接收字节指针unsigned char :获取状态;0:成功,1:失败(缓冲区为空)修改者:修改时间:修改内容简要:***************************/_COM_GetOneByte{if(_inRxBuf == _outRxBuf) {return 0;}; //RxBuf Empty*ch = *_outRxBuf; _outRxBuf++;if(_outRxBuf==_RxBuf+LenRxBuf) _outRxBuf = _RxBuf;return 1;}/****************************函数模型:unsigned char COM_GetPChar(unsigned char *ch,unsigned char len)函数功能:获取指定长度字节数组入口参数: unsigned char *ch:接收字节数组指针unsigned char len:接收字节个数返回值: unsigned char *ch:接收字节数组指针unsigned char:实际接收字节个数修改者:修改时间:修改内容简要:***************************/_COM_GetPChar{unsigned char i = 0;do{len--;if(!COM_GetOneByte_(ch)) break;i++;ch++;}while(len);return i;}/****************************函数模型:unsigned char COM_RxByte(void)函数功能:获取接收缓冲区有效字节个数入口参数:无返回值: unsigned char:接收缓冲区有效字节个数修改者:修改时间:修改内容简要:***************************/_COM_RxByte{if(_inRxBuf>=_outRxBuf) return (_inRxBuf-_outRxBuf);else return LenRxBuf-(_outRxBuf-_inRxBuf);}/****************************函数模型:unsigned char COM_SendOneByte(unsigned char one_byte)函数功能:发送一个字节入口参数: unsigned char one_byte:发送的字节返回值:unsigned char:发送状态,0:成功,1:失败(缓冲区满)修改者:修改时间:修改内容简要:***************************/_COM_SendOneByte{volatile unsigned char *t;if(_TIflag){_TIflag = 0;COM_TI1();}t = _inTxBuf;t++;if(t == _TxBuf + LenTxBuf) t = _TxBuf;if(t == _outTxBuf) {return 1;};//TxBuf Full*_inTxBuf = one_byte;_inTxBuf = t;return 0;}/****************************函数模型:void COM_SendPChar(unsigned char *P,unsigned char Len)函数功能:发送定长字节数组入口参数: unsigned char *P:字节数组指针unsigned char Len:发送长度返回值:无修改者:修改时间:修改内容简要:***************************/_COM_SendPChar{while(Len){//while(COM1_SendOneByte(*P)); //发送失败,继续发送,知道发送成功COM_SendOneByte_(*P);P++;Len--;}}/****************************函数模型:void COM_SendString(unsigned char *P)函数功能:发送字符串入口参数: unsigned char *P:字符串指针返回值:无修改者:修改时间:修改内容简要:***************************/_COM_SendString{while(*P){COM_SendOneByte_(*P);P++;}}//**************** 非缓冲区中断方式发送/****************************函数模型:void COM_PrintOneByte(unsigned char c)函数功能:发送一个字节入口参数: unsigned char one_byte:发送的字节返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintOneByte{COM_TI_FLAG0();COM_TI_SBUF(c); //发送数据while(!COM_TI_FLAG) ; //等待发送结束}/****************************函数模型:void COM_PrintPChar(unsigned char *buf,unsigned int len)函数功能:发送定长字节数组入口参数: unsigned char *P:字节数组指针unsigned char Len:发送长度返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintPChar{while(len){COM_PrintOneByte_(*buf);buf ++;len--;}}/****************************函数模型:void COM_PrintString(unsigned char *P) 函数功能:发送字符串入口参数: unsigned char *P:字符串指针返回值:无修改者:修改时间:修改内容简要:***************************/_COM_PrintString{while(*P){COM_PrintOneByte_(*P);P++;}}。
51单片机的串口通信程序(C语言)
#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;unsigned int Key3_flag = 0;unsigned int Key4_flag = 0;unsigned char b;unsigned char code Num[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; }else if(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 int temp,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;}void main(){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单片机串口通信C语言程序2**************************************************************; 平凡单片机工作室;ckss.asm;功能:反复向主机送AA和55两个数;主机使用一个串口调试软件设置19200,n,8,1***************************************************************/#include "reg51.h"#define uchar unsigned char#define uint unsigned int//延时程序//////////////////由Delay参数确定延迟时间*/void mDelay(unsigned int Delay){ unsigned int i;for(;Delay>0;Delay--){ for(i=0;i<124;i++){;}}}//////////////////// 主程序////////////////////void main(){ uchar OutDat; //定义输出变量TMOD=0x20; //TMOD=0TH1=0xf3; //12MHZ ,BPS:4800,N,8,1TL1=0xf3;PCON=0x80; //方式一TR1=1; //?????????????????????????????SCON=0x40; //串口通信控制寄存器模式一OutDat=0xaa; //向串口发送固定数据值for(;;) //循环程序{SBUF=OutDat;//发送数据for(;;){ if(TI) //发送中断位当发送停止位时置1,表示发送完成break;}mDelay(500);TI=0; //清零中断位OutDat=~OutDat; //显示内容按位取反}}。
单片机串口通讯程序
单片机串口通讯程序(C51)自己用C51写的串口通讯程序/*定义为中断方式串口处理*/#define INTERSENDSTR/*不为8032系列芯片*///#define CHIP_8032#include <absacc.h>#include <reg51.h>#include <string.h>#include "err.h"#ifdef INTERSENDSTRunsigned char xdata sSendComBuf[256],sRecComBuf[256];unsigned char data bOut,bIn,bSout,bSin;#else#define DEFSENDCHAR TI=0;SBUF=ACC;while(!TI);TI=0;#endif//bps设置9600 就是PSetBps(96)(11.0592Mhz)unsigned char PSetBps(unsigned int bps) SMALL{unsigned int t1;unsigned char t2;#ifdef INTERSENDSTR/*如果使用中断方式发送数据,必须等待发送数据完毕才能更换波特率*/ while(bSin!=bSout){;}ES=0;#endif#ifdef CHIP_8032if(3456%bps){return ERR_SET_BPS;}t1=3456/bps;t1--;t1=~t1;RCAP2H=t1/256;RCAP2L=t1;T2MOD=0x00;/*使用定时器2 做波特率发生器*/T2CON=0x34;/*TF2=0;EXF2=0;RCLK=1;TCLK=1;EXEN2=0;TR2=1;C/T2=0;CP/RL2=0 */#elset1=576/bps;if((576%bps)||((t1==0))||(t1>=2*256)){return ERR_SET_BPS;}if(t1>256){PCON=00;t2=256-(288/bps);}else{PCON=0x80;t2=256-t1;}TH1=t2;TL1=t2;TR1=1;#endif/*模式3*/SM0=0;RI=0;TI=0;REN=1;SM1=1;SM2=1;#ifdef INTERSENDSTRbOut=bIn;bSout=bSin;ES=1;#endifreturn OK;}void PSendChar(unsigned char ch) SMALL{#ifdef INTERSENDSTRunsigned char tch;tch=bSin+1;while(tch==bSout){}sSendComBuf[bSin]=ch;ES=0;if((bSout==bSin)){SBUF=sSendComBuf[bSin];bSin++;}else{bSin++;}ES=1;#elseACC=ch;DEFSENDCHAR;#endif}unsigned char PGetChar() SMALL{unsigned char ch;#ifdef INTERSENDSTRch=sRecComBuf[bOut];bOut++;return ch;#elsech=SBUF;RI=0;#endif}bit PCharInCom() SMALL{#ifdef INTERSENDSTRif(bIn!=bOut){return 1;}return 0;#elsereturn RI;#endif}void PSendString(unsigned char *st) SMALLwhile(*st){PSendChar(*st);st++;}}void PSendArray(unsigned char *st,unsigned int len) SMALL {unsigned int ii;for(ii=0;ii<len;ii++){PSendChar(st[ii]);}}#ifdef INTERSENDSTRvoid PSerialInt() interrupt 4{if(RI){sRecComBuf[bIn]=SBUF;bIn++;RI=0;}if(TI){TI=0;if(bSout!=bSin){bSout++;}if(bSout!=bSin){SBUF=sSendComBuf[bSout];}}}#endif。
C51串口通信示例
//串口中断服务程序 void UART0_ISR() interrupt 4 { uchar i; if(RI) //串口接收中断 { i=SBUF; RI=0; if(RXFRMOK==0) //如果 RXFRMOK=1 表示前台程序未处理完当前数据,丢弃 { if(RXAAOK) //接收到 0xAA { RXBUF[Rx_P]=i; if((Rx_P>3)&&(RXBUF[Rx_P-3]==0xCC)&&(RXBUF[Rx_P-2]==0x33)&&(RXBUF[Rx_P-1]==0xC3)&&(RXBUF[RX_P]= =0x3C)) {RXFRMOK=1; RXAAOK=0;} Rx_P++;} if(!RXAAOK&&(i==0xaa)) { RXAAOK=1; Rx_P=0;}} } if(TI) { TI=0; TI0FLAG=1;} //对于 DSP、ARM 等带 FRAME_ERROR 中断的 CPU,此处应添加对 FSTA 寄存器的清零 }
400 018 9008
{
if(RXFRMOK) if(RXBUF[0]==0x78) {} if(RXBUF[0]==0x7C) {} RXFRMOK=0; }
//前台主程序检查串口有没有收到 HMI 数据 //触控按钮 //触摸屏拼音输入结束 //处理完毕,清除消息
北京迪文科技有限公司
ห้องสมุดไป่ตู้- 41 -
专业.诚信.成功
迪文 HMI 用户软件开发指南
Ver3.0
附录 4 C51 串口通信程序参考
#define uchar unsigned char #define uint unsigned int bit RXAAOK; //串口接收到 0xAA 帧头 bit RXFRMOK;//串口收到一个有效数据帧 bit TI0FLAG;//传回给主程序的串口发送 1 个字节结束(TI)标记 uchar RXBUF[32]; uchar Rx_P; //串口接收缓冲区,存储时把 0xAA 帧头去掉,HMI 应答不是固定格式的都有长度返回,故 //不需要记录长度 //串口接收,保存数据位置
C51串口通讯
#include <C8051F060.h> // SFR declarations#include <stdio.h>//----------------------------------------------------------------------------- // 16-bit SFR Definitions for 'F06x//-----------------------------------------------------------------------------sfr16 RCAP2 = 0xCA; // Timer2 capture/reloadsfr16 TMR2 = 0xCC; // Timer2//----------------------------------------------------------------------------- // Global Constants//-----------------------------------------------------------------------------#define BAUDRATE 4800 // Baud rate of UART in bps#define BAUDRATE1 9600#define SYSTEMCLOCK 3062500//----------------------------------------------------------------------------- // Function Prototypes//-----------------------------------------------------------------------------void OSCILLATOR_Init (void);void PORT_Init (void);void UART0_Init (void);void UART1_Init (void);//----------------------------------------------------------------------------- // Global Variables//-----------------------------------------------------------------------------#define UART0_BUFFERSIZE 8unsigned char UART0_Buffer[UART0_BUFFERSIZE];unsigned char UART0_Buffer_Size = 0;unsigned char UART0_Input_First = 0;unsigned char UART0_Output_First = 0;unsigned char isfirstdata,k,k1;unsigned char UART0_R_Buf[UART0_BUFFERSIZE];unsigned char check1(void);unsigned char check2(void);void SendMesUart0(unsigned char adr);void delay(unsigned long tim){while (tim!=0)tim--;}unsigned char u1bufre[8];unsigned char u1REpnt;unsigned char u1buftr[8];unsigned char u1TRpnt;unsigned char resend;unsigned char resend1;//----------------------------------------------------------------------------- // main() Routine//-----------------------------------------------------------------------------void main (void){SFRPAGE = CONFIG_PAGE;WDTCN = 0xDE; // Disable watchdog timerWDTCN = 0xAD;OSCILLATOR_Init (); // Initialize oscillatorPORT_Init (); // Initialize crossbar and GPIOUART0_Init (); // Initialize UART0UART1_Init ();EA = 1;u1buftr[0]=0x31;u1buftr[1]=0x32;u1buftr[2]=0x33;u1buftr[3]=0x34;u1buftr[4]=0x35;u1buftr[5]=0x36;u1buftr[6]=0x37;u1buftr[7]=check1();SFRPAGE = UART0_PAGE;// SendMesUart0(0x80);while (1){// SFRPAGE = UART0_PAGE;// SendMesUart0(0x01);if (resend==1){SFRPAGE = UART0_PAGE;// SendMesUart0(0x80);resend=0;}if (resend1==1){resend1=0;SFRPAGE = UART1_PAGE;u1TRpnt=0;SBUF1=u1buftr[u1TRpnt];u1TRpnt++;}}}//----------------------------------------------------------------------------- // Initialization Subroutines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // OSCILLATOR_Init//----------------------------------------------------------------------------- //// Return Value : None// Parameters : None//// This function initializes the system clock to use an external 22.1184MHz// crystal.////----------------------------------------------------------------------------- void OSCILLATOR_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = CONFIG_PAGE; // Set SFR page// OSCICN = 0x80; // Set internal oscillator to run// at its slowest frequencySFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE}//----------------------------------------------------------------------------- // PORT_Init//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- void PORT_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = CONFIG_PAGE; // Set SFR pageSFRPAGE = CONFIG_PAGE;XBR0 = 0x04;XBR2 = 0xC4;P0MDOUT = 0x05;SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}//----------------------------------------------------------------------------- // UART0_Init Variable baud rate, Timer 2, 3//----------------------------------------------------------------------------- void UART0_Init (void){char SFRPAGE_SAVE;SFRPAGE_SAVE = SFRPAGE; // Preserve SFRPAGESFRPAGE = TMR2_PAGE;//TMR2CF = 0x08; //19200//RCAP2L = 0xF6;//RCAP2H = 0xFF;TMR2CN = 0x00; // Timer in 16-bit auto-reload up timer mode TMR2CF = 0x08; // SYSCLK is time base; no output;// up count onlyRCAP2 = - ((long) SYSTEMCLOCK/BAUDRATE/16);TMR2 = RCAP2;TR2= 1; // Start Timer2SFRPAGE = UART0_PAGE;SCON0 = 0xD0;SCON0 &= 0xFC; //将TI0和RI0清零SSTA0 = 0x5; // Clear all flags; DISable baud rate doubler Use Timer2 as RX and TX baud rate source;ES0 = 1;SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE}//----------------------------------------------------------------------------- // Interrupt Service Routines//-----------------------------------------------------------------------------//----------------------------------------------------------------------------- // UART0_Interrupt//----------------------------------------------------------------------------- //// This routine is invoked whenever a character is entered or displayed on the // Hyperterminal.////-----------------------------------------------------------------------------void UART0_Interrupt (void) interrupt 4{SFRPAGE=0x00;if(SCON0&0x01){UART0_R_Buf[k1]=SBUF0;k1++;SCON0&=0xfe;if(k1>=8){k1=0;if (UART0_R_Buf[7]==check2()){//if (UART0_R_Buf[5]=0xff){u1buftr[0]=UART0_R_Buf[0];u1buftr[1]=UART0_R_Buf[1];u1buftr[2]=UART0_R_Buf[2];u1buftr[3]=UART0_R_Buf[3];u1buftr[4]=UART0_R_Buf[4];u1buftr[5]=UART0_R_Buf[5];u1buftr[6]=UART0_R_Buf[6];u1buftr[7]=UART0_R_Buf[7];resend1=1;// return error from io resend}}}}if(SCON0&0x02){if(isfirstdata){SCON0&=0xf7;isfirstdata=0;k1=0;}if(k<8){SBUF0=u1bufre[k];k++;}else{k=0;}SCON0&=0xfd;}}void UART1_Init (void){char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR pageSFRPAGE = UART1_PAGE;SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RXSFRPAGE = TIMER01_PAGE;TMOD &= ~0xF0;TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reloadif (SYSTEMCLOCK/BAUDRATE1/2/256 < 1) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2);CKCON |= 0x10; // T1M = 1; SCA1:0 = xx} else if (SYSTEMCLOCK/BAUDRATE1/2/256 < 4) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/4);CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x01; // T1M = 0; SCA1:0 = 01} else if (SYSTEMCLOCK/BAUDRATE1/2/256 < 12) {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/12);CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00} else {TH1 = -(SYSTEMCLOCK/BAUDRATE1/2/48);CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x02; // T1M = 0; SCA1:0 = 10}TL1 = TH1; // init Timer1TR1 = 1; // START Timer1EIE2 = 0x40; // Enable UART1 interrupts SFRPAGE = UART1_PAGE;SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}void UART1_Interrupt (void) interrupt 20{SFRPAGE = UART1_PAGE;if(RI1){ ///if (u1REpnt<8){u1bufre[u1REpnt]=SBUF1;u1REpnt++;RI1=0;}if (u1REpnt>=8){u1REpnt=0;RI1=0;if (u1bufre[7]==check1()){SFRPAGE = UART0_PAGE;k=1;SendMesUart0(u1bufre[0] & 0x0f); //SBUF0=u1bufre[0];}else{u1buftr[0]=u1bufre[0];u1buftr[5]=0xff;u1buftr[6]=0xff;u1buftr[7]=0xff;}}} ///if(TI1){SFRPAGE=1;if (u1TRpnt<8){SBUF1=u1buftr[u1TRpnt];u1TRpnt++;}else{u1TRpnt=0;}TI1=0;}}void SendMesUart0(unsigned char adr){SFRPAGE=0x00;SCON0|=0x08;isfirstdata=1;。
C51程序设计范文
C51程序设计范文C51程序设计是指使用C语言编程来控制C51单片机的各种功能,包括输入输出、定时器、串口通信、中断等。
C51程序设计的特点之一是语言简洁、易读易写,对程序员来说较为友好。
相比于汇编语言,C51程序设计可以更快速地编写程序,并且具有更好的可读性。
首先,我们需要了解C51单片机的硬件特性。
C51单片机通常有多个GPIO引脚,可以用来控制外部设备。
我们可以通过在程序中设置GPIO引脚的电平来控制外部设备的开关状态。
下面是一个简单的C51程序设计示例,用于控制一个LED灯的亮暗状态:```#include <reg52.h>sbit LED = P1^0; // 定义LED在P1引脚的位置void maiwhile(1)LED=1;//点亮LEDdelay(1000); // 延时1秒LED=0;//熄灭LEDdelay(1000); // 延时1秒}void delay(unsigned int t)unsigned int i, j;for(i = 0; i < t; i++)for(j = 0; j < 1000; j++)}}```在这个示例中,我们首先定义了LED的位置,即P1引脚的第0位。
然后在主函数中,通过循环控制LED灯的亮暗状态。
在每次循环中,我们先将LED引脚设置为高电平,即LED灯点亮,然后延时1秒。
接下来将LED引脚设置为低电平,即LED灯熄灭,再次延时1秒。
通过不断循环这个过程,可以让LED灯以固定的频率闪烁。
这是一个非常简单的例子,但它展示了C51程序设计的基本原理和应用。
实际上,C51程序设计可以实现更为复杂的功能,比如通过按键控制LED的开关,通过串口通信控制外部设备等。
C51程序设计的灵活性使得它成为嵌入式系统开发中的重要工具。
总结一下,C51程序设计是一种基于C语言的嵌入式系统编程语言,用于开发C51单片机的应用程序。
它具有语言简洁、易读易写的特点,适用于多种领域的嵌入式系统开发。
简单实用C51单片机烧录程序串口安装步骤与教程
C51单片机烧录程序串口安装步骤
一、根据烧写程序的下载线不同,可以根据下载口型号到淘宝搜出。
(直接输
入某型号下载线即可。
淘宝中宝贝详情有附送下载包,可查找到资料下载网址和安装包,可以点击链接下载。
)
二、(如果不知型号可以打开下载线外壳查看里面芯片型号)这样有针对性
的下载无论XP还是win7的都可以快速解决效果非常好省去很多步奏
三、双击图标照常安装即可。
(装完后重启。
以下为win7示范!)
四、重启后,插上下载线后查看右下角安装图标点击进入后点击查看状态。
五、点击跳过windows update 获得驱动程序软件
六、弹出这窗口点是。
七、安装成功,关闭
八、打开控制面板主页,点击设备管理
九、安装成功
十、配合下载软件即可
希望能帮到需要帮助的朋友。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C51编程:这是网友牛毅编的一个C51串口通讯程序!//PC读MCU指令结构:(中断方式,ASCII码表示)//帧:帧头标志|帧类型|器件地址|启始地址|长度n|效验和|帧尾标志//值: 'n' 'y'| 'r' | 0x01 | x | x | x |0x13 0x10//字节数: 2 | 1 | 1 | 1 | 1 | 1 | 2//求和:///////////////////////////////////////////////////////////////////////公司名称:***//模块名:protocol.c//创建者:牛毅//修改者://功能描述:中断方式:本程序为mcu的串口通讯提供(贞结构)函数接口,包括具体协议部分//其他说明:只提供对AT89c51具体硬件的可靠访问接口//版本:1.0//信息:QQ 75011221/////////////////////////////////////////////////////////////////////#include <reg51.h>#include <config.h>//预定义//帧#define F_ST1 0x6e //帧头标志n#define F_ST2 0x79 //帧头标志y#define F_R 0x72 //帧类型读r#define F_W 0x77 //帧类型写w#define F_D 0x64 //帧类型数据帧d#define F_B 0x62 //帧类型写回应帧b#define F_C 0x63 //帧类型重发命令帧c#define F_Q 0x71 //帧类型放弃帧q#define F_ADDR 0x31 //器件地址0-9#define F_END 0x7a //帧尾标志z#define F_SPACE 0x30 //空标志0#define F_ERR1 0x31 //错误标志1,flagerr 1#define F_ERR2 0x32 //错误标志2 2//常数#define S_MAXBUF 16 //接收/发送数据的最大缓存量#define FIELD_MAXBUF 48 //最小场缓存,可以大于48字节,因为协议是以20字节为单位传输的#define communicationing P1_7 //正在通讯(1)标志#define ERRFRAME_MAX 5 //连续NOFRAME_CNT次帧不正确#define ERR_NOCNTMAX_RESEND if(++errframe_cnt<=ERRFRAME_MAX)resend_frame(); else errframe_cnt=communicationing=0;//若超过ERRFRAME_MAX 次则令通讯停止ERR_NOCNTMAX_RESEND//public 变量unsigned char databuf[FIELD_MAXBUF],errframe_cnt;//函数///////////////////////////////////////////////////////////////////////函数名:send()//功能描述:向串口发送一个字符//函数说明://调用函数://全局变量://输入:ch-要发送的ASCII字符//返回:无//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////void send(unsigned char ch){SBUF=ch;while(TI==0);TI=0;}///////////////////////////////////////////////////////////////////////函数名:receive()//功能描述:从串口接收一个字符//函数说明://调用函数://全局变量://输入:无//返回:一个ASCII字符//设计者:牛毅//修改者://版本://///////////////////////////////////////////////////////////////////unsigned char receive(void){while(RI==0);RI=0;}///////////////////////////////////////////////////////////////////// //函数名:CharToHex()//功能描述:把ASCII字符转换为16进制//函数说明://调用函数://全局变量://输入:ASCII字符//返回:16进制//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// unsigned char CharToHex(unsigned char bChar){if((bChar>=0x30)&&(bChar<=0x39))bChar -= 0x30;else if((bChar>=0x41)&&(bChar<=0x46))//大写字母bChar -= 0x37;else if((bChar>=0x61)&&(bChar<=0x66))//小写字母bChar -= 0x57;else bChar = 0xff;return bChar;}///////////////////////////////////////////////////////////////////// //函数名:HexToChar()//功能描述:把16进制转换为ASCII字符//函数说明://调用函数://全局变量://输入:16进制//返回:ASCII字符//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// unsigned char HexToChar(unsigned char bHex){if((bHex>=0)&&(bHex<=9))bHex += 0x30;else if((bHex>=10)&&(bHex<=15))//大写字母else bHex = 0xff;return bHex;}///////////////////////////////////////////////////////////////////// //函数名:com_int()//功能描述:初始化串口//函数说明:默认其他参数为[baud_rate],n,8,1//调用函数://全局变量://输入:baud_rate 波特率//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void com_init(unsigned int baud_rate){EA=1;ES=1;//ET1=1;SCON = 0x50; /* 0x52;//SCON */TMOD = 0x20; /*0x20;// TMOD */TCON = 0x60; /*0x60;// TCON */PCON=PCON&0x7f;switch(baud_rate){ //波特率设置case 1200:TL1=0xe8;TH1=0Xe8;break; //1200case 2400:TL1=0xf4;TH1=0Xf4;break; //2400case 4800:TL1=0xfa;TH1=0Xfa;break; //4800case 9600:TL1=0xfd;TH1=0Xfd;break; //9600case 19200:PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break; //19200case 38400:PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break; //38400 default:TL1=0xfd;TH1=0Xfd;break;//9600}}///////////////////////////////////////////////////////////////////// //函数名:resend_frame()//函数说明:通知PC重发//调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void resend_frame(void){send(F_ST1);send(F_ST2);send(F_C);send(F_SPACE);send(F_SPACE);//发送效验和send(F_END);}///////////////////////////////////////////////////////////////////// //函数名:quit_frame()//功能描述:发送放弃帧//函数说明:通知PC放弃通讯//调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void quit_frame(void){send(F_ST1);send(F_ST2);send(F_Q);send(F_ERR1);send(F_ERR1);//发送效验和send(F_END);}///////////////////////////////////////////////////////////////////// //函数名:com_int()//函数说明://调用函数://全局变量://输入:无//返回:无//设计者:牛毅//修改者://版本:///////////////////////////////////////////////////////////////////// void com_int()interrupt 4{unsigned char i,csaddr,clen,csum,tempbuf[S_MAXBUF];csum=0;if(receive()==F_ST1){//是侦if(receive()==F_ST2){//头判断完communicationing=1;//设置通讯状态为正常即启动通讯switch(receive()){case F_R://是读指令帧rif(receive()==F_ADDR){P1_2=!P1_2;//地址正确csaddr=CharToHex(receive())<<4;csaddr+=CharToHex(receive());clen=CharToHex(receive())<<4;clen+=CharToHex(receive()); csum=csaddr+clen;i=CharToHex(receive())<<4;i+=CharToHex(receive());if(i==csum){//效验和正确if(receive()==F_END){//结束标志正确//开始发送数据帧csum=0;send(F_ST1);send(F_ST2);send(F_D);send(HexToChar((clen&0xf0)>>4));send(HexToChar(clen&0x0f));csum+=clen;for(i=0;i<clen;i++){send(HexToChar((databuf[i+csaddr]&0xf0)>>4));send(HexToChar(databuf[i+csaddr]&0x0f));csum+=databuf[i+csaddr];}//if(csum>127)csum-=128;send(HexToChar((csum&0xf0)>>4));send(HexToChar(csum&0x0f));send(F_END);//发送数据帧完毕P1_0=!P1_0;}else{ERR_NOCNTMAX_RESEND break;}//结束标志错误}else{ERR_NOCNTMAX_RESENDbreak;}//效验和错误}//地址不正确break;case F_W://是PC写指令帧wif(receive()==F_ADDR){//地址正确csaddr=CharToHex(receive())<<4;csaddr+=CharToHex(receive());clen=CharToHex(receive())<<4;clen+=CharToHex(receive());csum=csaddr+clen;for(i=0;i<clen;i++){tempbuf[i+csaddr]=CharToHex(receive())<<4; tempbuf[i+csaddr]+=CharToHex(receive());csum+=tempbuf[i+csaddr];}i=CharToHex(receive())<<4;i+=CharToHex(receive()); if(csum!=i){ERR_NOCNTMAX_RESEND break;}//效验和错误if(F_END!=receive()){ERR_NOCNTMAX_RESENDbreak;}//结束标志错误for(i=csaddr;i<clen+csaddr;i++)databuf[i-csaddr]=tempbuf[i-csaddr];//正确则保存数据}//从PC获得数据写完毕//开始发送写回应帧send(F_ST1);send(F_ST2);send(F_B);send(F_SPACE);send(F_SPACE);//发送效验和send(F_END);//写回应帧发送完毕P1_1=!P1_1;break;case F_Q://检测接收放弃帧csaddr=receive();csum+=csaddr;//csaddr兼做放弃帧码标志if(csaddr!=F_ERR1 && csaddr!=F_ERR2){ERR_NOCNTMAX_RESEND break;}if(csum!=receive()){ERR_NOCNTMAX_RESENDbreak;}if(F_END!=receive()){ERR_NOCNTMAX_RESENDbreak;}communicationing=0;//出错退出通讯break;default:resend_frame();//要求从发}}//忽略}//忽略if(!communicationing)quit_frame();//调用放弃帧,通知PC 放弃通讯}///////////////////////////////////////////////////////////////////主函数/////////////////////////////////////////////////////////////////void main(void){unsigned char i;for (i=0;i<FIELD_MAXBUF;i++) databuf=i+0x30;com_init(38400);while(1){/*可以处理非串口任务*/}。