精华内容
下载资源
问答
  • 2021-03-29 10:21:13

    1、优化《51单片机——USART半双工模式通讯-波特率可选1.2版本》里的代码。

    2、主要修改了串口中断里的代码和主函数里的发送代码,接收缓存50字节(这个可自行调整串口缓存大小)

    3、此代码工作在半双工模式。

    4、使用系统输出函数之后要使用自定义函数发送则需要延迟2毫秒,要不然会出错。切记。

    测试结果:定时器1、定时器2波特率均已验证OK。4800bps~115200bps均OK。

    main.c

    #include "uart.h"
    #include <stdio.h>
    #include "delay.h"
    
    #define UART_T1 1//1的话就用定时器1产生波特率,0则为定时器2产生波特率
    //备注,此串口是全双工模式,自定义(uart.c和uart.h)缓存区RX[num]的大小,本实验50字节缓存
    //备注:上位机必须在数据后面加入'\n'或者换行
    //备注,delay经调试至少需要2毫秒延迟(在使用系统输出函数时)
    void main(void)//puts自带换行
    {
    	unsigned char num_x=0;
    	if(UART_T1)
    	{
    		UART_T1_init_config(1);//初始化串口波特率最大为57600
    		
    		ES=0;//要使用printf了,先关闭串口中断
    		TI=1;//使用系统函数前需要将TI置1
    		puts("1、定时器1产生波特率,测试结果pass");
    		printf("2、定时器1产生波特率,测试结果pass\n");
    		ES=1;//启动串口中断
    		delay_ms(2);//不知道为啥需要延迟一下,要不然接收数据会出错
    		UART_Send_string(RX);//发送默认数据
    	}
    	else
    	{
    		UART_T2_init_config(5);//初始化串口波特率最大为115200
    
    		ES=0;//要使用printf了,先关闭串口中断
    		TI=1;//使用系统函数前需要将TI置1
    		puts("1、定时器2产生波特率,测试结果pass");
    		printf("2、定时器2产生波特率,测试结果pass\n");
    		ES=1;//启动串口中断
    
    		delay_ms(2);//不知道为啥需要延迟一下,要不然接收数据会出错
    		UART_Send_string(RX);//发送默认数据
    	}
    	for(;RX[num_x]!='\n';num_x++)//清空缓存器写换行‘\n’
    	{
    		RX[num_x]='\n';
    		if(num_x%2!=0)//1个汉字占用2个字节,如果不以汉字打印可不要此行代码
    		UART_Send_string(RX);//发送擦除后的数据
    	}
    	num_x=0;
    	
    	while(1)
    	{
    		if(flag_rx)//如果接收到数据就重新发送出去
    		{
    			UART_Send_1Byte_Data(RX[num_x]);
    			if(RX[num_x]=='\n')
    			{
    				num_x=0;
    				flag_rx=0;
    			}
    			else
    			{
    				num_x++;
    			}
    		}
    	}
    }

    delay.c和delay.h太简单了就不贴代码了

    uart.h

    #ifndef __UART_H__
    #define __UART_H__
    #include <reg52.h>
    //Mode_n_bps输入示例,定时器1没有115200
    // bps4800		输入1
    // bps9600		输入2
    // bps19200		输入3
    // bps57600		输入4
    // bps115200	输入5
    
    extern bit flag_rx;
    extern unsigned char RX[53];//最大保存50个字节
    //串口初始化装载,使用定时器1产生波特率,默认为9600bps
    void UART_T1_init_config(unsigned char Mode_n_bps);
    
    //串口初始化装载,使用定时器2产生波特率
    //串口工作方式1,8位uart且波特率可变,且允许串口接收数据//默认波特率9600bps
    void UART_T2_init_config(unsigned char Mode_n_bps);
    
    //串口发送数据
    void UART_Send_1Byte_Data(unsigned char DAT);
    
    //串口发送字符串
    void UART_Send_string(unsigned char* c);
    
    #endif // !__UART_H__

    uart.c

    #include "uart.h"
    sfr IPH_    =0xB7;//中断优先级高位寄存器
    sfr SADEN_	=0xB9;//从机地址掩码寄存器
    sfr SADDR_	=0xA9;//从机地址控制寄存器
    
    static bit flag_tx=0;//发送空闲表示位
    bit flag_rx = 0;//接收忙标识位
    unsigned char RX[53]="最大只能发送二十五个汉字,结尾必须要有回车,切记哈\r\n";//最大别超过50个字节
    
    //串口初始化装载,使用定时器1产生波特率
    //串口工作方式1,8位uart且波特率可变,且允许串口接收数据
    //定时器1工作方式2,8位自动重装模式
    void UART_T1_init_config(unsigned char Mode_n_bps)//默认波特率9600bps
    {
    	SCON = 0x50;//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
    	PCON = 0x10;//最高位SMOD=1表示串口工作模式1、2、3下加倍波特率(默认PCON=0x10,波特率不加倍)
    
    	SADEN_ = 0x00;//不使用
    	SADDR_ = 0x00;//不使用
    	
    	TI=0;//清除
    	RI=0;//清除
    
    	EA = 1;//打开总中断
    	ES = 1;//打开串口中断
    
    	//串口1中断优先级0
    	IPH_ = 0x00;
    	IP = 0x00;
    	
    	TMOD |= 0x20;//开启定时器T1,并使用工作方式2(8位自动重装)
    	switch(Mode_n_bps)
    	{
    		case 1:	
    				TL1 = 250;//计数初值设置波特率4800bps
    				TH1 = 250;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
    				break;//bps4800
    		case 2:
    				TL1 = 253;//计数初值设置波特率9600bps
    				TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
    				break;//bps9600
    		case 3:
    				PCON |= 0x80;//SM0D=1,波特率加倍
    				TL1 = 253;//计数初值设置波特率19200bps
    				TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
    				break;//bps19200
    		case 4:
    				PCON |= 0x80;//SM0D=1,波特率加倍
    				TL1 = 255;//计数初值设置波特率57600bps
    				TH1 = 255;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
    				break;//bps57600
    		default://默认bps9600
    				TL1 = 253;//计数初值设置波特率9600bps
    				TH1 = 253;//装载固定初值,当TL1加满后会自动把TH1的值装载进去
    				break;//bps9600
    	}
    	ET1 = 0;//禁止定时器1发出中断
    	TR1 = 1;//启动定时器1
    }
    
    //串口初始化装载,使用定时器2产生波特率
    //串口工作方式1,8位uart且波特率可变,且允许串口接收数据
    void UART_T2_init_config(unsigned char Mode_n_bps)//默认波特率9600bps
    {
    	SCON = 0x50;//串口工作方式1,8位uart且波特率可变,且允许串口接收数据
    	T2CON |= 0x30;//定时器2用作串口波特率发生器且16位自动重装模式
    
    	SADEN_ = 0x00;//不使用,默认值
    	SADDR_ = 0x00;//不使用。默认值
    	
    	TI=0;//清除,建议清除一下
    	RI=0;//清除
    
    	EA = 1;//打开总中断
    	ES = 1;//打开串口中断
    
    	//串口1中断优先级0
    	IPH_ = 0x00;//默认值
    	IP = 0x00;//默认值
    
    	//T2MOD = 0x02;//T2OE :T2 输出允许位,当 T2OE=1 的时候,允许时钟输出到 P1.0。(仅对80C54 / 80C58 有效)
    					//DCEN:向下计数允许位。 DCEN = 1 是允许 T2 向下计数,否则向上计数。
    	switch (Mode_n_bps)
    	{
    		case 1:
    			TL2 = 0xb8;//计数初值设置波特率4800bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xb8;
    			RCAP2H = 0xff;
    			break;//bps4800
    		case 2:
    			TL2 = 0xdc;//计数初值设置波特率9600bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xdc;
    			RCAP2H = 0xff;
    			break;//bps9600
    		case 3:
    			TL2 = 0xee;//计数初值设置波特率19200bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xee;
    			RCAP2H = 0xff;
    			break;//bps19200
    		case 4:
    			TL2 = 0xfa;//计数初值设置波特率57600bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xfa;
    			RCAP2H = 0xff;
    			break;//bps57600
    		case 5:
    			TL2 = 0xfd;//计数初值设置波特率115200bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xfd;
    			RCAP2H = 0xff;
    			break;//bps115200
    		default://默认bps9600
    			TL2 = 0xdc;//计数初值设置波特率9600bps
    			TH2 = 0xff;//装载固定初值
    			RCAP2L = 0xdc;
    			RCAP2H = 0xff;
    			break;//bps9600
    	}
    	TR2 = 1;//启动定时器2
    }
    //串口发送数据
    void UART_Send_1Byte_Data(unsigned char DAT)
    {
    	while(flag_tx);//等待之前的数据发送完成
    	flag_tx=1;
    	SBUF = DAT;
    	//如果使用while(!TI);
    	//可能会出现TI=1时刚好进入串口中断,然后串口中断将TI=0;此时程序会卡死在while里的
    }
    //串口发送字符串
    void UART_Send_string(unsigned char *c)
    {
    	do
    	{
    		UART_Send_1Byte_Data(*c++);//带*c表示的是值,c表示的是地址
    	}while (*c != '\0');
    }
    
    //串口中断函数,中断号4
    //单片机串口只缓存1字节8位数据
    void UART_IT(void) interrupt 4
    {
    	static unsigned char num=0;
    	if (TI) //发送标志位
    	{
    		TI = 0;
    		flag_tx=0;
    		//使用printf()/puts()/putchar()(stdio.h)的时候,需要ES=0;TI=1;printf();(TI=0,printf使用后会自动清除)最后ES=1。
    	}
    	if (RI)	 //接收标志位
    	{
    		RX[num]=SBUF;//将接收的数据先保存起来
    		RI = 0;
    		if(RX[num]=='\n')
    		{
    			num=0;
    			flag_rx = 1;//数据接收完毕同样可以发送数据了
    		}
    		else 
    		{
    			num++;
    			if(num==2)
    				flag_rx = 1;//可以开始发送数据了
    		}
    	}
    }
    

    更多相关内容
  • 最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新单片机仿真 485全双工通信最新...
  • 双工通信,实现两个单片机之间的通信双工通信,实现两个单片机之间的通信双工通信,实现两个单片机之间的通信
  • 51系列单片机竞赛设计485全双工通信应用.rar
  • PC机与PIC单片机串行全双工通信.docx
  • Protues仿真实例-51单片机-485全双工通信.rar
  • 基于串口通信的单片机双工通信系统研究.pdf
  • 51单片机的485全双工通信程序,程序简明,适合初学者使用
  • 基于嵌入式与单片机的485全双工通信设计实现
  • 基于嵌入式与单片机的485全双工通信应用实现
  • 根据课题需要,我们设计了一种基于特高频(300M以上)无线传输方法,实际使用效果连好,能满足一般的传输和控制,可应用于微机、单片机等控制领域。对于误码率要求较高的场合,建议采用CRC编码减少误码率。
  • 单片机课程设计报告-实现单片机PC串行双工通信.doc
  • 基于89C51单片机/89C52单片机通用的485全双工通信,Proteus软件测试运行环境7.8版本,包含内容:keil vision5项目文件、C语言程序源码、hex后缀编译文件、DSN仿真后缀文件项目
  • 本文章是关于51单片机串口通信1602显示。
  • 基于AT89C51单片机实现单片机之间通信,每个单片机既是信息发送端也是信息接收端,并且可以人工控制信息的发送,
  • nRF24L01单片机双工无线通信

    热门讨论 2011-06-22 19:49:40
    nRF24L01单片机双工通信程序,主机发送命令信号,从机回应采集到的数据信号,数据采集是DS18B20数字温度传感器!!
  • 51系列单片机竞赛设计485全双工通信.rar
  • 单片机课程设计——485全双工通信(PROTEUS仿真+代码).zip
  • 单片机课程设计——485全双工通信应用(PROTEUS仿真+代码).zip
  • 如何理解单片机是什么,全双工串行通信接口怎么理解 单片机是在单个芯片中整合了计算机的大部分功能和资源,所以我们可以把它理解成一台性能很弱的计算机,与常见普通的电脑或者手机比起来,单片机的运算速度...

    如何理解单片机是什么,全双工串行通信接口怎么理解

    单片机是在单个芯片中整合了计算机的大部分功能和资源,所以我们可以把它理解成一台性能很弱的计算机,与常见普通的电脑或者手机比起来,单片机的运算速度大概是它们的百分之一,存储空间是它们的百万分之一,所以单片机比较便宜,很廉价就可以买到,单片机适合实现电子产品的简单编程控制。

    51单片机有一个可编程的全双工的异步串行通讯接口,具有通用的异步收发器的全部功能,异步串行通讯接口叫UART,指的是通用的一个异步收发器,它具有通用的异步收发器的功能,也不仅仅指具备这一个功能,同时也能够作为同步的移位寄存器来使用。

    单片机的全双工的异步串行通信接口,它有四种工作方式,其中方式0就可以作为同步的移位寄存器来使用,要想用单片机来做串行通信进行数据的发送和接收,那就要使用它的串行通信接口,通信接口是设备和设备之间或者设备和主机之间串行通信,必然需要用到引脚,51单片机在做串行通信的时候用到的两个引脚就是P3.0和P3.1,做通讯的时候一般还会用到GND,三根线就可以全双工的串行通信,全双工的异步串行通信接口,在发送的时候可以接收,在接收的时候也能够进行发送,而且它是异步的通信,不是同步。

    异步是指在做异步串行通信的时候实际上它的数据的发送是以字符帧为单位来进行发送的,一帧格式当中会包括几个东西,起始位,数据位停止位,奇偶校验位,这些构成一个帧格式,在每一帧数据和每一帧数据之间的时间间隔是任意的,每一帧数据里面数据位一帧包括十个位的异步串口通信,位和位之间的时间间隔是严格的按照波特率来规定的,比如波特率是4800,在传输这个一帧数据的时候,每一个位和另外一个位之间的时间间隔要按照这个波特率来配置,收发双方才能够知道如何去识别数据,硬件上做串行通信使用的是P3.03.1和GND这三根线,在这个功能上是一个全双工的串行口。

    异步通信包括数据起始位,停止位,奇偶校验位,这些位分别的位置在一帧格式当中,发送数据的时候每一帧数据传输都必须按照这个帧格式来进行传输,起始位和停止位是使用单片机内部的串行通信接口的话,实际上这个是由硬件来帮加的,不需要我们来管,要收发双方如何知道这根线上开始有数据来传输了,也就是这跟数据开始传输了,TSD或者SD这根线上地之间在空闲的时候是没有数据传输的,它是高电平,要想建立一次通信首先把这根线拉成低电平,就是发送方把这个线拉出来低电平就代表要发送一帧数据了,接收方也一直在监控着这根信号线,就能够知道有数据要发送了,就可以按照约定的波特率来进行收发数据。

    当发送到停止位的时候,单片机就认为是一帧数据发送完了,可以再去接收另外的帧数据,停止位让总线处于空闲状态,就可以发起另外一次的通信,传输的波特率常用的就是那些,现在的波特率还可以做得更高,这个决定了选择的芯片里面串行通信它的速度可以达到多高,还有就是时钟晶振是多高,波特率是收发双方首先要约定好当前的通信波特率是多少,然后要配置串行口来产生一个波特率,波特率是首先要约定好的,比如用工作方式一的时候,是借助单片机的定时计数器来产生波特率,并不是直接来生成一个波特率然后再去做通信,事先确定波特率然后再来根据设定的波特率来让串行通信接口来产生这个波特率,从而使收发双方按照这个约定的波特率来进行通信。

    刚开始做初始通信的时候要有一个基本的通信约定,在基本的通信约定建立起来之后,已经建立通信收发双方可以传输一个字节或者一帧数据了,数据代表一些命令还是一些参数,还要做一些上位的软件层的一些通信协议,或者叫应用层的一些通信协议的约定,通信协议实际上软件层来讲应该分成两种,一个是基本的通信约定,比如一般在做串行通信的时候,用单片机来和计算机进行通信,在计算机开始调试的时候是借助串行口的调试助手,要首先选择波特率,然后选择起始位停止位以及校验位都是什么样子的,要收发双方遵循统一的标准,或者说统一的约定,收发双方的数据通路就建立好了,收发数据就可以进行。

    对单片机感兴趣的可以查看往期分享内容希望能帮助大家在学习单片机的路上少走一些弯路想要入门单片机可以持续关注创为单片机编程回复“带我学习”查看更多内容分享

    展开全文
  • 利用comm.jar开发包实现Java与单片机双工串口通信核心分析.pdf
  • 关注+星标公众号,不错过精彩内容视频号 | strongerHuang微信公众号|strongerHuang通信的种类和方式有很多,今天为大家分享一下通信中常见的同步、异步,单工、双工...

    关注+星标公众,不错过精彩内容

    dff17371385543a0b196176de5686555.gif

    视频号 | strongerHuang

    微信公众号 | strongerHuang

    通信的种类和方式有很多,今天为大家分享一下通信中常见的同步、异步,单工、双工通信的区别。

    同步、异步通信

    通信分为串行和并行通信,一般串行通信的应用场合更多,比如:UART、 I²C、 SPI、 CAN等这些都属于串行通信。

    串行通信一般又分为同步和异步通信,同步通信需要同步时钟信号,而异步通信则不需要同步时钟信号。

    概念:

    • 同步通信:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。

    • 异步通信:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。

    c2433ae531fc26e588d4cb2b70a15bcb.png

    通过定义你应该能测到:像I²C、 SPI这种具有同步时钟的就是同步通信;像UART、 CAN这种没有同步时钟的就是异步通信。

    单工、 双工通信

    通信根据传输的方法分为单方向通信(即单工),和双向通信(即双工)。

    单工通信

    单工即数据传输只在一个方向上传输,方向是固定的,不能实现双向通信(A发送数据给B,而B不能发送数据给A),如:收音机广播,你只能听到广播站发出的广播(数据),而你不能反向给广播站发送广播。

    双工通信

    双工分为 半双工 和 全双工。

    半双工

    半双工比单工先进一点,传输方向可以切换,允许数据在两个方向上传输。

    但是某个时刻,只允许数据在一个方向上传输,可以基本双向通信。

    像485、I²C就属于半双工通信。

    全双工

    比半双工更先进的是全双工,允许数据同时在两个方向传输。发送和接收完全独立,在发送的同时可以接收信号,或者在接收的同时可以发送。它要求发送和接收设备都要有独立的发送和接收能力。

    如:RS232、SPI通信等。

    用一张图的说明:单工、半双工、全双工通信:

    a2467810d459d397df1559eb11136986.png

    最后

    通信领域需要掌握的知识比较多,还有像什么传输方式、编码方式、通信协议等。

    对于初学者可能看到这些概念都想放弃了,其实,拆解每一个知识点都不难。

    声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

    ------------ END ------------

    关注公众号后台回复『通信教程』『单片机』阅读更多相关文章。

    回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

    711538cb9003aef20ca7150353a22b98.png

    abf66fbc5d390916c4528675f9292b0c.png

    点击“阅读原文”查看更多分享

    展开全文
  • 这节我们主要讲单片机上串口的工作原理和如何通过程序来对串口进行设置,以及根据所给出的实例实现与PC 机通信。 一、原理简介 51 单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能...
  • 51单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。当串行发送完毕后,将在标志位 TI 置 1,同样,当收到了数据后,也会在 RI置 1。无论 RI 或 TI 出现了 1,只要串口中断处于开放状态,单片机...
  • 单片机课程设计-实现单片机与PC串行双工通信
  • 485全双工通信.zip

    2021-01-30 11:06:24
    单片机控制485通信传输
  • STM32LL库 SPI全双工通信GS2962.
  • 7、全双工、半双工、单工 只能是一个方向传送。 比如:A传送数据到B,并且只能B不能传送到A。可以双向传送,但在在某一时刻,只能一方为发送,另一方为接收。在同一时刻,双方可以同时接收和发送数据。...

    1、什么是通信协议?

    通信协议又称通信规程,是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传送速度,传送步骤,检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,它也叫做链路控制规程。

    总言而之:通信协议就是双方实体完成通信或服务所必须遵守的规则和约定。

    2、接口技术

    在这里插入图片描述

    3、计算机通信

    举例说明:
    在这里插入图片描述
    在上面举例的是一个具有时钟线的,即同步通信(后面就说到)
    上面举例的是一个具有时钟线的,即同步通信(后面就说到)

    4、大端序(MSB)和小端序(LSB)

    在这里插入图片描述

    5、同步与异步通信

    在这里插入图片描述

    为什么要有时钟线?

    时钟线能持续不断将逻辑级别脉冲至高位和低位,每次脉冲之间持续时间“tb”以脉冲宽度来表示。
    时钟线用于计算单个比特的持续时间,以供接收方用于在准确位置轮询管脚状态,这样接收方就能以可靠方式从串行线上提取数据。

    在这里插入图片描述

    6、并行与串行通信

    在这里插入图片描述

    并行:可同时传输多个位的数据,但是通信线路比较多,会有一定的干扰。
    串行:一下只能传输一个位
    

    7、全双工、半双工、单工

    在这里插入图片描述

    ①单工

    只能是一个方向传送。 比如:A传送数据到B,并且只能B不能传送到A。

    ②半双工

    可以双向传送,但在在某一时刻,只能一方为发送,另一方为接收。

    ③全双工

    在同一时刻,双方可以同时接收和发送数据。

    8、电平信号和差分信号

    在这里插入图片描述

    展开全文
  • 单片机串行通信(合集),单片机串口通信程序,包括单片机之间,单片机与PC之间
  • C系列单片机有一个全双工的串行口.ppt80C51系列单片机有一个全双工的串行口,这个口既可以用于网络通信,也可以实现串行异步通信,还可以作为同步移位寄存器使用。 2、串行控制寄存器SCON 3、电源控制寄存器PCON ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,941
精华内容 1,976
关键字:

单片机双工通信