51单片机汇编模拟串口通信程序

合集下载

51单片机模拟spi串行接口程序

51单片机模拟spi串行接口程序
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=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单片机模拟串口的三种方法

//先传低位
} //查询计数器溢出标志位 void WaitTF0( void ) { while(!TF0); TF0=0; } 接收的程序,可以参考下一种方法,不再写出。这种办法个人感觉不错,接收和 都很准确,另外不需要计算每条语句的指令周期数。 方法三:中断法
中断的方法和计数器的方法差不多,只是当计算器溢出时便产生一次中断,用户 在中断程序中置标志,程序不断的查询该标志来决定是否发送或接收下一位,当然程 断进行初始化,同时编写中断程序。本程序使用Timer0中断。 #define TM0_FLAG P1_2 //设传输标志位 //计数器及中断初始化 void S2INI(void) { TMOD =0x02; //计数器0,方式2 TH0=0xA0; //预值为256-96=140,十六进制A0 TL0=TH0; TR0=0; //在发送或 接收才开始使用 TF0=0; ET0=1; //允许定时
//发送启始
位 Delay2cp(39); //发送8位数据位 while(i--) { TXD=(bit)(input&0x01); Delay2cp(36); input=input>>1; } //发送校验位(无) TXD=(bit)1; 位 Delay2cp(46); } //从串口读一个字节 uchar RByte(void) { uchar Output=0; uchar i=8; uchar temp=RDDYN; //发送8位数据位 Delay2cp(RDDYN*1.5); while(i--) { Output >>=1; if(RXD) Output Delay2cp(35); 占用26个指令周期 } while(--temp) 时间内搜寻结束位。 { Delay2cp(1); if(RXD)break; } return Output;

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码

STC51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码STC 51单片机普通IO口模拟IIC(I2C)接口通讯的程序代码原文:(改自周立功软件包)#include <reg51.h>#include <intrins.h>#define uchar unsigned char /*宏定义*/#define uint unsigned intextern void Delay1us(unsigned char );sbit SDA=P1^6; /*模拟I2C数据传送位*/sbit SCL=P1^7; /*模拟I2C时钟控制位*/bit ack; /*应答标志位*//************************************************************** *****起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.*************************************************************** *****/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/Delay1us(1);SCL=1;Delay1us(5); /*起始条件建立时间大于4.7us,延时*/SDA=0; /*发送起始信号*/Delay1us(5); /* 起始条件锁定时间大于4μs*/SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay1us(2);}/************************************************************** *****结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.*************************************************************** *****/void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/Delay1us(1); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4us*/Delay1us(5);SDA=1; /*发送I2C总线结束信号*/Delay1us(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(uchar c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

51单片机模拟串口的三种方法

51单片机模拟串口的三种方法

51单片机模拟串口的三种方法51单片机模拟串口的三种方法随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。

这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。

本文所说的模拟串口,就是利用51的两个输入输出引脚如P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。

至于串口通信的波特率,说到底只是每位电平持续的时间,波特率越高,持续的时间越短。

如波特率为9600BPS,即每一位传送时间为1000ms/9600=0.104ms,即位与位之间的延时为为0.104毫秒。

单片机的延时是通过执行若干条指令来达到目的的,因为每条指令为1-3个指令周期,可即是通过若干个指令周期来进行延时的,单片机常用11.0592M的的晶振,现在我要告诉你这个奇怪数字的来历。

用此频率则每个指令周期的时间为(12/11.0592)us,那么波特率为9600BPS每位要间融多少个指令周期呢?指令周期s=(1000000/9600)/(12/11.0592)=96,刚好为一整数,如果为4800BP S则为96x2=192,如为19200BPS则为48,别的波特率就不算了,都刚好为整数个指令周期,妙吧。

至于别的晶振频率大家自已去算吧。

现在就以11.0592M的晶振为例,谈谈三种模拟串口的方法。

方法一:延时法通过上述计算大家知道,串口的每位需延时0.104秒,中间可执行96个指令周期。

#define uchar unsigned charsbit P1_0 = 0x90;sbit P1_1 = 0x91;sbit P1_2 = 0x92;#define RXD P1_0#define TXD P1_1#define WRDYN 44 //写延时#define RDDYN 43 //读延时//往串口写一个字节void WByte(uchar input){uchar i=8;TXD=(bit)0; //发送启始位Delay2cp(39);//发送8位数据位while(i--){TXD=(bit)(input&0x01); //先传低位Delay2cp(36);input=input>>1;}//发送校验位(无)TXD=(bit)1; //发送结束位Delay2cp(46);}//从串口读一个字节uchar RByte(void){uchar Output=0;uchar i=8;uchar temp=RDDYN;//发送8位数据位Delay2cp(RDDYN*1.5); //此处注意,等过起始位 while(i--){Output >>=1;if(RXD) Output |=0x80; //先收低位Delay2cp(35); //(96-26)/2,循环共占用26个指令周期}while(--temp) //在指定的时间内搜寻结束位。

51单片机两机串口通信c程序

51单片机两机串口通信c程序

51单片机两机串口通信c程序(共2页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--发送机#include<>#define uchar unsigned char#define uint unsigned intuchar code xuehao1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar code xuehao2[]={2,0,0,9,0,5,4,0,2,1,5,3};void send(uchar dat){SBUF=dat; //将待发送的数据写入发送缓存器中while(TI==0) //只要接收中断标志位; //空操作TI=0; //为了接收下一帧数据,需用软件降RI清零}void delay(){uchar m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}void main(){uchar i;TMOD=0x20;//定时器T1工作于方式2SCON=0x50;//串口工作方式1PCON=0x00;//电源控制寄存器,波特率不加倍TH1=0xfd; //波特率为 9600()TL1=0xfd;TR1=1; //启动定时器T1while(1){for(i=0;i<12;i++){send(xuehao1[xuehao2[i]]); //发送数据idelay();delay();delay();delay();}}}接受机#include<>#define uchar unsigned char#define uint unsigned intuchar receive(){uchar dat;while(RI==0); //只要接收中断标志位RI=0; //为了接收下一帧数据,需用软件降RI清零dat=SBUF; // 将接收缓存器中的数据存于datreturn dat; //将接收到的数据返回}void main(){TMOD=0x20;//定时器T1工作于方式2SCON=0x50;//串口工作方式1PCON=0x00;TH1=0xfd; //波特率为 9600()TL1=0xfd;TR1=1; //启动定时器T1REN=1; //允许接收while(1){P0=receive();}}。

51单片机模拟串口的三种方法

51单片机模拟串口的三种方法

随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。

这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51系列只提供一个串口,那么另一个串口只能靠程序模拟。

本文所说的模拟串口,就是利用51的两个输入输出引脚如P1.0和P1.1,置1或0分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1或置0。

至于串口通信的波特率,说到底只是每位电平持续的时间,波特率越高,持续的时间越短。

如波特率为9600BPS,即每一位传送时间为1000ms/9600=0.104ms,即位与位之间的延时为为0.104毫秒。

单片机的延时是通过执行若干条指令来达到目的的,因为每条指令为1-3个指令周期,可即是通过若干个指令周期来进行延时的,单片机常用11.0592M的的晶振,现在我要告诉你这个奇怪数字的来历。

用此频率则每个指令周期的时间为(12/11.0592)us,那么波特率为9600BPS每位要间融多少个指令周期呢?指令周期s=(1000000/9600)/(12/11.0592)=96,刚好为一整数,如果为4800BPS则为96x2=192,如为19200BPS则为48,别的波特率就不算了,都刚好为整数个指令周期,妙吧。

至于别的晶振频率大家自已去算吧。

现在就以11.0592M的晶振为例,谈谈三种模拟串口的方法。

方法一:延时法通过上述计算大家知道,串口的每位需延时0.104秒,中间可执行96个指令周期。

#define uchar unsigned charsbit P1_0 = 0x90;sbit P1_1 = 0x91;sbit P1_2 = 0x92;#define RXD P1_0#define TXD P1_1#define WRDYN 44 //写延时#define RDDYN 43 //读延时//往串口写一个字节void WByte(uchar input){uchar i=8;TXD=(bit)0; //发送启始位Delay2cp(39);//发送8位数据位while(i--){TXD=(bit)(input&0x01); //先传低位Delay2cp(36);input=input>>1;}//发送校验位(无)TXD=(bit)1; //发送结束位Delay2cp(46);}//从串口读一个字节uchar RByte(void){uchar Output=0;uchar i=8;uchar temp=RDDYN;//发送8位数据位Delay2cp(RDDYN*1.5); //此处注意,等过起始位while(i--){Output >>=1;if(RXD) Output |=0x80; //先收低位Delay2cp(35); //(96-26)/2,循环共占用26个指令周期}while(--temp) //在指定的时间内搜寻结束位。

51单片机与PC串口通信程序及硬件电路图

51单片机与PC串口通信程序及硬件电路图

51单片机与PC串口通信程序及硬件电路图#include <reg51.h>#define BUFFERLEGTH 10//----------------------------------------------------------------- void UART_init(); //串口初始化函数void COM_send(void); //串口发送函数char str[20];char j;//-------------------------------------------------------------------void main(void){unsigned char i;UART_init();j=0; //初始化串口for(i = 0;i < 10 ;i++){COM_send(); //首先发送一次数据作为测试用};while(1);}//-------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 函数名称: UART_init()串口初始化函数// 函数功能:在系统时钟为11.059MHZ时,设定串口波特率为9600bit/s// 串口接收中断允许,发送中断禁止//--------------------------------------------------------------------------------------------------void UART_init(){//初始化串行口和波特率发生器SCON =0x50; //选择串口工作方式1,打开接收允许TMOD =0x20; //定时器1工作在方式2,定时器0工作在方式1 TH1 =0xfA; //实现波特率9600(系统时钟11.0592MHZ)PCON = 0x80;TR1 =1; //启动定时器T1ET1 =0;ES=1; //允许串行口中断PS=1; //设计串行口中断优先级EA =1; //单片机中断允许}//------------------------------------------------------------void COM_send(void){unsigned char point = 0;for(point=0;str[point]!='\0';point++) //连续发送二十位数据 //把缓存区的数据都发送到串口 {SBUF=str[point];while(!TI);TI=0;//str[point]='\0';}}//--------------------------------------------------------------//--------------------------------------------------------------------------------------------------// 函数名称: com_interrup()串口接收中断处理函数// 函数功能:接收包括起始位'S'在内的十位数据到数据缓冲区//--------------------------------------------------------------------------------------------------void com_interrupt(void) interrupt 4 using 3{unsigned char RECEIVR_buffer;bit flag=1;if(RI) //处理接收中断{RI=0; //清除中断标志位RECEIVR_buffer=SBUF; //接收串口数据str[j]=SBUF;if (RECEIVR_buffer == '$'){ ES=0;str[j]='\0';SCON =0x40; //接收不允许COM_send(); //发送数据ES=1;j=0;flag=0;SCON=0x50; //接收允许}if(flag)j++;}}。

单片机IO口模拟串口程序(发送+接收)

单片机IO口模拟串口程序(发送+接收)

单片机IO口模拟串口程序(发送+接收)前一阵一直在做单片机的程序,由于串口不够,需要用IO口来模拟出一个串口。

经过若干曲折并参考了一些现有的资料,基本上完成了。

现在将完整的测试程序,以及其中一些需要总结的部分贴出来。

程序硬件平台:11.0592M晶振,STC单片机(兼容51)/************************************** ************************** 在单片机上模拟了一个串口,使用P2.1作为发送端* 把单片机中存放的数据通过P2.1作为串口TXD发送出去*************************************** ************************/#include <reg51.h>#include <stdio.h>#include <string.h>typedef unsigned char uchar;int i;uchar code info[] ={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5 5,0x55,0x55,0x55,0x55,0x55,0x55,0x55 };sbit newTXD = P2^1;//模拟串口的发送端设为P2.1void UartInit(){SCON = 0x50; // SCON: serail mode 1, 8-bit UARTTMOD |= 0x21; // T0工作在方式1,十六位定时PCON |= 0x80; // SMOD=1;TH0 = 0xFE; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=11.0592MHzTL0 = 0x7F; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=11.0592MHz// TH0 = 0xFD; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHz// TL0 = 0x7F; // 定时器0初始值,延时417us,目的是令模拟串口的波特率为2400bps fosc=18.432MHz}void WaitTF0(void){while(!TF0);TF0=0;TH0=0xFE; // 定时器重装初值fosc=11.0592MHzTL0=0x7F; // 定时器重装初值fosc=11.0592MHz// TH0 = 0xFD; // 定时器重装初值 fosc=18.432MHz// TL0 = 0x7F; // 定时器重装初值 fosc=18.432MHz}void WByte(uchar input){//发送启始位uchar j=8;TR0=1;newTXD=(bit)0;WaitTF0();//发送8位数据位while(j--){newTXD=(bit)(input&0x01); //先传低位WaitTF0();input=input>>1;}//发送校验位(无)//发送结束位newTXD=(bit)1;WaitTF0();TR0=0;}void Sendata(){for(i=0;i<sizeof(info);i++)//外层循环,遍历数组{WByte(info[i]);}}void main(){UartInit();while(1){Sendata();}}########################################## ####################################/************************************** ************************** 模拟接收程序,这个程序的作用从模拟串口接收数据,然后将这些数据发送到实际串口* 在单片机上模拟了一个串口,使用P3.2作为发送和接收端* 以P3.2模拟串口接收端,从模拟串口接收数据发至串口*************************************** ************************/#include<reg51.h>#include<stdio.h>#include<string.h>typedef unsigned char uchar ;//这里用来切换晶振频率,支持11.0592MHz 和18.432MHz//#define F18_432#define F11_0592uchar tmpbuf2[64]={0};//用来作为模拟串口接收数据的缓存struct{uchar recv :6 ;//tmpbuf2数组下标,用来将模拟串口接收到的数据存放到tmpbuf2中uchar send :6 ;//tmpbuf2数组下标,用来将tmpbuf2中的数据发送到串口}tmpbuf2_point={0,0};sbit newRXD=P3^2 ;//模拟串口的接收端设为P3.2void UartInit(){SCON=0x50 ;// SCON: serail mode 1, 8-bit UARTTMOD|=0x21 ;// TMOD: timer 1, mode 2, 8-bit reload,自动装载预置数(自动将TH1送到TL1);T0工作在方式1,十六位定时PCON|=0x80 ;// SMOD=1;#ifdef F11_0592TH1=0xE8 ;// Baud:2400 fosc=11.0592MHz 2400bps为从串口接收数据的速率TL1=0xE8 ;// 计数器初始值,fosc=11.0592MHz 因为TH1一直往TL1送,所以这个初值的意义不大TH0=0xFF ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHzTL0=0xA0 ;// 定时器0初始值,延时208us,目的是令模拟串口的波特率为9600bps fosc=11.0592MHz#endif#ifdef F18_432TH1=0xD8 ;// Baud:2400fosc=18.432MHz 2400bps为从串口接收数据的速率TL1=0xD8 ;// 计数器初始值,fosc=18.432MHz 因为TH1一直往TL1送,所以这个初值的意义不大TH0=0xFF ;// 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHzTL0=0x60 ;// 定时器0初始值,延时104us,目的是令模拟串口的波特率为9600bps fosc=18.432MHz#endifIE|=0x81 ;// 中断允许总控制位EA=1;使能外部中断0TF0=0 ;IT0=1 ;// 设置外部中断0为边沿触发方式TR1=1 ;// 启动TIMER1,用于产生波特率}void WaitTF0(void){while(!TF0);TF0=0 ;#ifdef F11_0592TH0=0xFF ;// 定时器重装初值模拟串口的波特率为9600bps fosc=11.0592MHz TL0=0xA0 ;// 定时器重装初值模拟串口的波特率为9600bps fosc=11.0592MHz #endif#ifdef F18_432TH0=0xFF ;// 定时器重装初值 fosc=18.432MHzTL0=0x60 ;// 定时器重装初值 fosc=18.432MHz#endif}//接收一个字符uchar RByte(){uchar Output=0 ;uchar i=8 ;TR0=1 ;//启动Timer0#ifdef F11_0592TH0=0xFF ;// 定时器重装初值模拟串口的波特率为9600bps fosc=11.0592MHz TL0=0xA0 ;// 定时器重装初值模拟串口的波特率为9600bps fosc=11.0592MHz #endif#ifdef F18_432TH0=0xFF ;// 定时器重装初值fosc=18.432MHzTL0=0x60 ;// 定时器重装初值fosc=18.432MHz#endifTF0=0 ;WaitTF0();//等过起始位//接收8位数据位while(i--){Output>>=1 ;if(newRXD)Output|=0x80 ;//先收低位WaitTF0();//位间延时}TR0=0 ;//停止Timer0return Output ;}//向COM1发送一个字符void SendChar(uchar byteToSend){SBUF=byteToSend ;while(!TI);TI=0 ;}void main(){UartInit();while(1){if(tmpbuf2_point.recv!=tmpbuf2_point.send)//差值表示模拟串口接收数据缓存中还有多少个字节的数据未被处理(发送至串口){SendChar(tmpbuf2[tmpbuf2_point.send++]);}}}//外部中断0,说明模拟串口的起始位到来了void Simulated_Serial_Start()interrupt 0{EX0=0 ;//屏蔽外部中断0tmpbuf2[tmpbuf2_point.recv++]=RByte(); //从模拟串口读取数据,存放到tmpbuf2数组中IE0=0 ;//防止外部中断响应2次,防止外部中断函数执行2次EX0=1 ;//打开外部中断0}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~以上是两个独立的测试程序,分别是模拟串口发送的测试程序和接收的测试程序上面两个程序在编写过程中参考了这篇文章《51单片机模拟串口的三种方法》(在后文中简称《51》),但在它的基础上做了一些补充,下面是若干总结的内容:1、《51》在接收数据的程序中,采用的是循环等待的方法来检测起始位(见《51》的“附:51 IO 口模拟串口通讯C源程序(定时器计数法)”部分),这种方法在较大程序中,可能会错过起始位(比如起始位到来的时候程序正好在干别的,而没有处于判断起始位到来的状态),或者一直在检测起始位,而没有办法完成其他工作。

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

51单片机的串口通信程序之欧阳数创编
while(1) { ScanKey(); KeyProc(); if(RI) { Disbuf[0] = 0; Disbuf[1] = 20; Disbuf[2] = SBUF>>4; Disbuf[3] = SBUF&0x0f; RI = 0; } else; }}
时间:2021.03.02
创作:欧阳数
sbit 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 codeDisdigit[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++) {} }}
//-----------------------------------------------------

51单片机串口变并口汇编程序

51单片机串口变并口汇编程序

51单片机串口变并口汇编程序51单片机是一种常用的微控制器,它具有高性能、低功耗、丰富的外设和广泛的应用领域。

其中,串口和并口是常见的通信接口方式。

本文将详细介绍51单片机串口变并口汇编程序的实现方法。

## 1. 串口和并口介绍### 1.1 串口串行通信接口(Serial Communication Interface),简称串口,是一种将数据以连续位的形式传输的通信方式。

它只需要两根线(发送线和接收线)即可实现数据传输,适用于远距离传输和多设备连接。

### 1.2 并口并行通信接口(Parallel Communication Interface),简称并口,是一种将数据以多个位同时传输的通信方式。

它需要多根线同时传输数据,适用于高速数据传输和短距离连接。

## 2. 串行通信与并行通信转换原理在51单片机中,通过软件编程可以实现串行通信与并行通信之间的转换。

下面是其基本原理:### 2.1 串行转并行在将串行数据转换为并行数据时,需要一个移位寄存器来存储接收到的串行数据,并通过时钟信号按位移出到并行总线上。

具体步骤如下:1. 初始化串口参数,包括波特率、数据位、停止位等。

2. 等待串口接收到数据。

3. 将接收到的串行数据写入移位寄存器。

4. 通过时钟信号依次将移位寄存器中的数据按位移出到并行总线上。

### 2.2 并行转串行在将并行数据转换为串行数据时,需要一个移位寄存器来存储要发送的并行数据,并通过时钟信号按位读取并发送出去。

具体步骤如下:1. 初始化串口参数,包括波特率、数据位、停止位等。

2. 将要发送的并行数据写入移位寄存器。

3. 通过时钟信号依次从移位寄存器中读取数据,并发送出去。

## 3. 51单片机串口变并口汇编程序实现下面是一个示例程序,演示了如何在51单片机中实现串口变并口的功能。

```assembly; 定义串口接收和发送函数USART_Rx: ; 串口接收函数MOV A, SBUF ; 读取SBUF中的接收数据RETUSART_Tx: ; 串口发送函数MOV SBUF, A ; 将A寄存器中的数据写入SBUFRET; 主程序入口MAIN:MOV TMOD, #20H ; 设置定时器1为工作模式2,用于串口通信 MOV TH1, #FDH ; 设置波特率为9600SETB TR1 ; 启动定时器1; 初始化串口参数MOV SCON, #50H ; 设置串口工作模式为8位数据位、1位停止位、可变波特率; 接收数据并转换为并行数据发送CALL USART_Rx ; 调用串口接收函数,将接收到的数据存入A寄存器MOV P0, A ; 将A寄存器中的数据写入P0,并行总线; 并行数据转换为串行数据发送MOV A, P1 ; 从P1并行总线读取要发送的数据,存入A寄存器CALL USART_Tx ; 调用串口发送函数,将A寄存器中的数据发送出去SJMP MAIN ; 无限循环END```上述汇编程序通过调用USART_Rx和USART_Tx函数实现了串口接收和发送功能。

51单片机串口通信软件程序集

51单片机串口通信软件程序集

51单片机串口通信软件程序集串口通信的单片机程序beep bit p3.7 ;蜂鸣器定义org 00hjmp mainorg 23h ;串行中断入口地址jmp com_int ;串行中断服务程序;*********** 主程序开始*******************org 30hmain: mov sp,#30h ;设置堆栈lcall rest ;初始化lcall comm ;串口初始化jmp $ ;原地等待; ************* 初始化*********************rest: mov p0,#00h ;禁止数码管显示mov p2,#255clr beep ;禁止蜂鸣器mov p1,#255 ;禁止LED显示RET ;返回; ************** 串口初始化*****************;设置串行口工作方式1,定时器1作为波特率发生器;波特率设置为2400 ;comm: mov tmod,#20h ;设置定时器T1工作方式2mov tl1,#0f3h ;定时器计数初值,波特率2400mov th1,#0f3h ;定时器重装值setb ea ;允许总的中断setb es ;允许串行中断mov pcon,#00h ;波特率不倍增mov scon,#50h ;设置串口工作方式1,REN = 1 允许接收setb tr1 ;定时器开始工作ret ;返回;*************** 串口中断服务程序***********; 如果接收0FF 表示上位机需要联机信号,单片机发送0FFH作为; 应答信号,如果接收到数字1~ n,表示相应的功能;; 这里,如果收到1 ,则单片机向计算机发送字符'H';; 如果收到2 ,则单片机向计算机发送字符'e';; 如果收到其他的数据,则发送'J';com_int: clr es ;禁止串行中断clr ri ;清除接收标志位mov a,sbuf ;从缓冲区取出数据mov p1,amov dptr,#tabcjne a,#0ffh,in_1 ;检查数据mov sbuf,#255 ;收到联机信号,发送联机信号jnb ti,$ ;等待发送完毕clr ti ;清除发送标志setb es ;允许串行中断reti ;中断返回in_1: cjne a,#1H, in_2 ;如果收到1movc a,@a+dptrmov sbuf,a ;发送'h'jnb ti,$ ;等待发送完毕clr ti ;清除发送中断标志setb es ;允许串行中断reti ;中断返回in_2: cjne a,#2,in_3 ;接收到 2movc a,@a+dptrmov sbuf,a ;发送'e'jnb ti,$ ;等待发送完毕clr ti ;清除发送中断setb es ;允许串行中断reti ;中断返回in_3: mov a,#03hmovc a,@a+dptrmov sbuf,a ;发送'j'jnb ti,$ ;等待发送完毕clr ti ;清除发送中断标志setb es ;允许串行中断reti ;返回tab: db '2','h','e','j'end51单片机串口调试程序一例/*定义为中断方式串口处理*/#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) SMALL{while(*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 INTERSENDSTR void 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。

51单片机汇编模拟串口通信程序

51单片机汇编模拟串口通信程序

51单片机汇编模拟串口通信程序汇编编写的模拟串口通信程序T2 作为波特率控制UART_RXD 是硬中断0 或1 口,如果能进入中断,说明该线有一个起始位产生,进入中断后调用下面的接收程序。

退出硬中断之前还需要将硬中断标志重新复位。

UART_TXD是任何其它IO 即可。

UART_SEND: PUSH IE PUSH DPH PUSH DPL PUSH PSW PUSH 00H PUSH ACC CLR EA SETB UART_TXD ;START BIT MOV R0,A CLR TR2 ;TR2 置1,计数器2 启动,时间计数启动。

MOV A,RCAP2L;计数器2 重新装载值MOVTL2,A ;置计数器2 初值;T2 需要重新装载MOV A,DPH MOV A,RCAP2H MOV TH2,A MOV A,R0 SETB TR2 ;TR2 置1,计数器JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 CLR UART_TXD ;START BIT JNB TF2,$ CLR TF2 JNBTF2,$ CLR TF2 MOV R0,#08HUART_SEND_LOOP: RRC A MOV UART_TXD,C ;8 BIT JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 DJNZR0,UART_SEND_LOOP SETB UART_TXD ;END BIT JNB TF2,$ CLR TF2 JNB TF2,$ CLR TF2 POP ACC POP 00H POP PSW POP DPL POP DPH POP IE RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UART_REC: PUSH IE PUSH DPH PUSH DPL CLR EA CLR TR2 ;TR2 置1,计数器2 启动,时间计数启动。

51单片机串口通信试验汇编程序

51单片机串口通信试验汇编程序

51单片机串口通信试验汇编程序(今天是硬生生的把它给抠出来了):PC 通过串口助手向单片机系统传递命令和数据:以A5开始,以5A结束;中间是数据,长度不一,要求把数据部分用led灯显示出来;并且要求循环显示;//This is my x_Ed program code//we use it as the pc communicated with the mcu//At the same time,we want to see the result by LCD;STFLAG BIT 00H //收到起始码标志,1为收到起始码EDFLAG BIT 01H //到结束码标志,1为收到结束码TMFLAG BIT 02H //定时时间到标志,1为定时时间到ORG 0000HSJMP Initialize//主程序入口(初始化程序)ORG 000BH //定时器0入口LJMP TIMER0 //定时器0中断ORG 0023H //串口中断程序的入口地址LJMP Transfer //跳转到接受中断入口///////////////////////////////////////////////////////////////ORG 0050HInitialize:MOV SP,#70H //设置堆栈MOV TMOD,#21H //T1工作方式2 T0工作MOV TH1,#0FDH //波特率9600MOV TL1,#0FDH //波特率9600 自动重装载MOV TH0,#3CH //定时50msMOV TL0,#0BH //定时50msMOV SCON,#50H //串口工作方式1MOV R6,#00H //定时次数计数器20一秒MOV R5,#00H //接收数据长度计数器MOV R4,#00H //控制输出控制寄存器MOV R0,#30H //数据存储地址MOV R1,#30H //控制输出的数据缓存CLR STFLAG //清起始标志位CLR EDFLAG //清结束标志位CLR TMFLAG //清时钟标志位SETB PS //提高串口中断的优先级SETB TR1 //打开定时器1;SETB ES //打开串口中断允许位SETB ET0 //定时器0中断允许位SETB EA //打开全局中断允许位/////////////////等待接受命令//////////////////////// Main: JB STFLAG,NODE3 //已经收到起始位SJMP Main //未起始继续等待NODE3: JB EDFLAG,NODE4 //已经收到结束位SJMP Main //未结束继续等待NODE4: SETB TR0 //打开定时器0;NODE5: JB TMFLAG,OUTPUTSJMP NODE5///////////////////等待上位机传送数据并记录//////// Transfer: CLR ESMOV A,SBUFCJNE A,#0A5H,NODE0 //检测到起始位SETB STFLAGSJMP JIEDIANNODE0: CJNE A,#05AH,NODE1 //检测到结束位SETB EDFLAGMOV DPH,R5MOV R4,DPHclr ES //打开串口中断允许位SJMP ret00NODE1: MOV @R0,A //既非起始码,又非结束码,则为数据INC R0INC R5MOV SBUF,#055HJIEDIAN: CLR TICLR RISETB ESret00: RETITIMER0: CLR TR0MOV TH0,#3CHMOV TL0,#0B0HINC R6CJNE R6,#20,RTNSETB TMFLAGMOV R6,#00HRTN: SETB TR0RETIOUTPUT: CLR TR0clr TMFLAGMOV A,@R1MOV P1,AINC R1DJNZ R4,NODE4MOV R1,#30HCLR TMFLAGMOV DPH,R5MOV R4,DPHSJMP NODE4RETIEND。

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; }}。

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

51单片机汇编模拟串口通信程序
T2作为波特率控制UART_RXD 是硬中断0或1口,如果能进入中断,说明该线有一个起始位产生,进入中断后调
用下面的接收程序。

退出硬中断之前还需要将硬中断标志重新复位。

UART_TXD是任何其它IO即可。

UART_SEND:
PUSH IE
PUSH DPH
PUSH DPL
PUSH PSW
PUSH 00H
PUSH ACC
CLR EA
SETB UART_TXD ;START BIT
MOV R0,A
CLR TR2 ;TR2置1,计数器2启动,时间计数启动。

MOV A,RCAP2L;计数器2重新装载值
MOV TL2,A ;置计数器2初值;T2需要重新装载
MOV A,DPH
MOV A,RCAP2H
MOV TH2,A
MOV A,R0
SETB TR2 ;TR2置1,计数器
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2
CLR UART_TXD ;START BIT
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2
MOV R0,#08H
UART_SEND_LOOP:
RRC A
MOV UART_TXD,C ;8 BIT JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2
DJNZ R0,UART_SEND_LOOP SETB UART_TXD ;END BIT JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2
POP ACC
POP 00H
POP PSW
POP DPL
POP DPH
POP IE
RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UART_REC:
PUSH IE
PUSH DPH
PUSH DPL
CLR EA
CLR TR2 ;TR2置1,计数器2启动,时间计数启动。

MOV A,RCAP2L;计数器2重新装载值
MOV TL2,A ;置计数器2初值;T2需要重新装载MOV A,DPH
MOV A,RCAP2H
MOV TH2,A
JB UART_RXD,$ ;REC
SETB TR2 ;TR2置1,计数器2启动,时间计数启动。

JNB TF2,$
CLR TF2 ;0.5 BIT
JNB TF2,$
CLR TF2 ;1 BIT
JNB TF2,$
CLR TF2 ;1.5 BIT
MOV C,UART_RXD
MOV ACC.0,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;2.5
MOV C,UART_RXD
MOV ACC.1,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;3.5
MOV C,UART_RXD
MOV ACC.2,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;4.5
MOV C,UART_RXD MOV ACC.3,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;5.5
MOV C,UART_RXD MOV ACC.4,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;6.5
MOV C,UART_RXD MOV ACC.5,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;7.5
MOV C,UART_RXD MOV ACC.6,C
JNB TF2,$
CLR TF2
JNB TF2,$
CLR TF2 ;8.5
MOV C,UART_RXD MOV ACC.7,C
JNB TF2,$
CLR TF2 ;9.5
JNB UART_RXD,$ ;等待停止位,并重新复位计数器SETB UART_RXD
POP DPL
POP DPH
POP IE
RET。

相关文档
最新文档