单片机串口_单片机串口通信 - CSDN
精华内容
参与话题
  • 51单片机系列(串口理解)

    千次阅读 2018-02-24 12:01:59
    串口,通信方式的一种。串口的数据发送接受单位为字节,一个字节即为8位二进制数。对一个字节进行发送时,为一位一位的发送,先低位后高位。例如十进制的9,对其发送时,首先将其转化为二进制0000 1001。然后按照从...

     串口,通信方式的一种。串口的数据发送接受单位为字节,一个字节即为8位二进制数。对一个字节进行发送时,为一位一位的发送,先低位后高位。例如十进制的9,对其发送时,首先将其转化为二进制0000 1001。然后按照从低位到高位的发送顺序为1001 0000。当我们在示波器或是在Protues仿真中可以看到单片机的I/O口波形为

    第一位为0(起始位),最后一位1(结束位)。总共有十位。

    当单片机进行数据发送时,I/O口会发出上述的波形(中间的八位高低电平代表数据),每发送一个数据会有一个上述的波形在I/O口中出现。

    当单片机进行数据接收时,I/O口也会有一个上述的波形出现,单片机对该波形进行读取,就可以读到数据。但问题来了,单片机在读取的时候,每间隔多长时间来进行一次读取呢?这个时间不能大于或者小于波形中高低电平的时间,负责就会错乱。

    所以接收和发送方,在开始通信之前,就必须约定好,波形中高低电平的持续时间。这个持续时间就是串口通信中的重要概念之一————————波特率。

    波特率就是单片机发送二进制数据位的速率,发送一位二进制的持续时间就是1/波特率。


    利用单片机I/O口模拟串口通信,可以更加深入的理解其原理。上述的数据波形图,不一定要用单片机来产生,用波形发生器等等都可以,在读取数据的时候,用肉眼也可以,只要你知道高低电平代表的意思就好。

    上述就是串口通信的基本原理,下来再结合51芯片手册,理解各种寄存器即可。


    51单片机中,有两个SBUF寄存器,这两个寄存器共用一个地址,这两个寄存器一个是只读(也叫接收寄存器),一个是只写(发送寄存器)。当51单片机的I/O口,一旦检测有下降沿时,就会启动接收模块(发送方先发送0这个起始位)。经过模块之后,执行

    DAT=SBUF;   //
    

    这个语句,就会读出接收到的数据。  对于模块的具体运作方式,看芯片手册上面有非常详细的介绍。


        




    展开全文
  • 51单片机串口通信(一)

    万次阅读 多人点赞 2018-12-02 18:27:07
    串口通信好东西,但我没用过。 下面照着普中科技的ppt搬运下。  随着多微机系统的广泛应用和计算机网络技术的普及,计算机的通信功能愈来愈显得重要。计算机通信是指计算机与外部设备或计算机与计算机之间的信息...

    串口通信好东西,但我没用过。

    下面照着普中科技的ppt搬运下。


           随着多微机系统的广泛应用和计算机网络技术的普及,计算机的通信功能愈来愈显得重要。计算机通信是指计算机与外部设备或计算机与计算机之间的信息交换。

    通信方式

    并行通信串行通信两种。

    并行通信通常是将数据字节的各位用多条数据线同时进行传送 。

    图一:并行通信

    串行通信是将数据字节分成一位一位的形式在。

    图二:串行同行

     

     

     

     

     

    串行通信的传输方向

    单工是指数据传输仅能沿一个方向,不能实现反向传输。

    半双工是指数据传输可以沿两个方向,但需要分时进行。

    全双工是指数据可以同时进行双向传输。

     

    串行通信常见的错误校验 

    奇偶校验、循环冗余校验

     

    传输速率(比特率):

    比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。

     

    80C51串行口的结构

    图三:串口结构

     有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H ;接收器是双缓冲结构 ;发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误。

     

    串行口的控制寄存器(SCON)(有点复杂,没咋整明白,以后用的时候再说)

    用以设定串行口的工作方式、接收/发送控制以及设置状态标志:

    图四:SCON

    SM0和SM1为工作方式选择位,可选择四种工作方式:

    图五:工作方式

    SM2,多机通信控制位,主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。

    REN,允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。

    TB8,在方式2或方式3中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。在方式0和方式1中,该位未用。

    RB8,在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位。在方式1时,若SM2=0,则RB8是接收到的停止位。

    TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请

    RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。 

    PCON中只有一位SMOD与串行口工作有关

    图六:PCON

    SMOD(PCON.7)  波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。 

     

    波特率的计算(用波特率计算器)

    方式0的波特率 =  fosc/12

    方式2的波特率 =(2SMOD/64)· fosc

    方式1的波特率 =(2SMOD/32)·(T1溢出率)

    方式3的波特率 =(2SMOD/32)·(T1溢出率)

     T1 溢出率 = fosc /{12×[256 -(TH1)]}

           在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。

    图七:波特率

    串口如何使用 

    确定串行口控制(编程SCON寄存器);

    确定T1的工作方式(编程TMOD寄存器);

    计算T1的初值,装载TH1、TL1;

    启动T1(编程TCON中的TR1位);

    PC和单片机通信:

    #include<reg52.h>
    
    typedef unsigned char uchar;
    
    void Serial_comInit()
    {
    	SCON=0X50;			//设置为工作方式1 ,既然是方式一,自然要确定波特率,设置定时器1
    	TMOD=0X20;//8位重装载
    	PCON=0X80;
    	TH1=0xF3;//波特率4800
    	TL1=0XF3;
    	ES=1;						//打开通信中断
    	EA=1;						//打开总中断
    	TR1=1;					//打开计数器
    }
    
    void main(void)
    {
    	Serial_comInit();
    	while(1);
    }
    
    void communication() interrupt 4
    {
    	uchar receiveData;
    	receiveData=SBUF;//出去,接,收到的数据
    	RI = 0;//清除接收中断标志位
    	SBUF=receiveData;//将接收到的数据放入到发送寄存器
    	while(!TI);			 //等待发送数据完成
    	TI=0;						 //清除发送完成标志位
    }

     

     电脑发送数据到单片机:

    (来源:https://blog.csdn.net/u014453898/article/details/57123007

    
    #include<reg52.h>
    
    #define uchar unsigned char
    
    #define uint  unsigned int
    uchar buf;
    
    #define led P2
    
    void main(void)
    
    {
    
    SCON=0x50;//设定串口工作方式0101 0000
    
    PCON=0x00;
    
    TMOD=0x20;
    
    EA=1;
    
    ES=1;
    
    TL1=0xfd;//波特率9600
    
    TH1=0xfd;
    
    TR1=1;
    
    while(1);
    
    }
    
     
    
    //串行中断服务函数
    
    void serial() interrupt 4
    
    	{
    
    	ES=0;		//暂时关闭串口中断
    
    	RI=0;
    
    	buf=SBUF;	//把收到的信息从SBUF放到buf中。
    
    	switch(buf)
    
    	{
    
    	case 0x31: led=0xfe;break;   //二进制 0011 0001  十进制 49 控制字符 1  16进制 0X31
    
    	case 0x32: led=0xfd;break;	 //1111 1101
    
    	case 0x33: led=0xfb;break;
    
    	case 0x34: led=0xf7;break;
    
    	case 0x35: led=0xef;break;   
    
    	case 0x36: led=0xdf;break;	
    
    	case 0x37: led=0xbf;break;
    
    	case 0x38: led=0x7f;break;
    
    	}
    
    	ES=1;		//重新开启串口中断
    
    	SBUF=buf;
    	while(!TI);
    	TI=0;
    
    }
    
     
    

     我的串口助手有点智障,不过程序应该没有啥大问题。

     

    参考文章:

    C51学习五)单片机与PC通过串口通信 

     

       

     

     

     

     

    一条传输线上逐个地传送。

     

     

     

     

    展开全文
  • 51系列单片机 单片机串口通信接收发送数据程序
  • 51单片机串口驱动,个人正在使用中,比较好用。
  • 51单片机串口通信

    万次阅读 多人点赞 2018-05-15 15:59:13
    好记性不如烂笔头,以前总以为自己记性比较好,但事实总是一次一次的打我脸,刚开始学习单片机的时候在串口通信这一块发了一段时间,才将这一块弄懂了个七七八八,这几天回头想一下那一方面的知识,感觉忘得差不多了...

        好记性不如烂笔头,以前总以为自己记性比较好,但事实总是一次一次的打我脸,刚开始学习单片机的时候在串口通信这一块发了一段时间,才将这一块弄懂了个七七八八,这几天回头想一下那一方面的知识,感觉忘得差不多了,现在重新理一遍,里面的程序大部分都是以前抄袭大佬的,但具体是哪一位大佬的博客现在也找不到了,希望大佬见谅。

        首先了解串口通信先要熟悉SCON,PCON,TMOD三个寄存器

        串口工作方式寄存器SCON,

    D7D6D5D4D3D2D1D0
    功能SM0SM1SM2RENTB8RB8TIRI

    RI:接收中断标志位,数据接收结束时,标志位会自动置1,需要通过程序将其置0

    TI:发送中断标志位,数据发送结束时,标志位会自动置1,需要通过程序将其置0

    RB8:存放发送数据的第9位

    TB8:存放接收数据的第9位

    REN:串行接收允许位,0允许串行接收,1禁止串行接收

    SM2:多机控制位

    SM1,SM0:串行工作方式

    SM0SM1方式说明波特率
    000移位寄存器fosc/12
    01110位异步收发器(8位数据)可变
    10211位异步收发器(9位数据)fosc/64或fosc/32
    11311位异步收发器(9位数据)可变

        PCON寄存器

    D7D6D5D4D3D2D1D0
    功能SMOD-------

    SOMD:波特率是否加倍选择位,0波特率不加倍,1波特率加倍

        定时器工作方式寄存器TMOD

    D7D6D5D4D3D2D1D0
    功能GATEC/TM1M0GATEC/TM1M0

    高四位为定时计数器1的设置,低四位是定时计数器0设置,串口通信波特率设置占用定时计数器1,这里主要说串口通信,不过多说定时计数器,只需要设置定时计数器1的工作方式即可

    振荡周期:也称时钟周期(频率的倒数),单片机提供时钟信号的振荡源周期,频率一般有11.0592MHz,12MHz等

    状态周期:是时钟周期的2倍,

    机器周期:是包含6个状态周期,机器周期=1/单片机时钟频率

    单片机时钟频率:是外部时钟的12分频,如果是12MHz的晶振,机器周期=1/单片机时钟频率=1/(12MHz/12)=12/12M=1us

    这里一个机器周期为1us,若定时时间为1ms,则需要1000个机器周期,计算出初值;如果机器周期为2us,则只需要500个机器周期。

    定时器初值计算:初值=(65536-机器周期数量)


    波特率计算:

    当串口工作在工作方式0和2是,波特率固定,方式0时fosc/12;方式2时fosc/32或fosc/64(根据SMOD判断)。

    当串口工作在方式1时,波特率=(2^SMOD/32)*(单片机时钟频率/(256-X)),X是初值

    C/T:定时器和计数器选择位,0为定时器,1为计数器

    M1M0工作方式
    00

    工作方式0:为13位定时/计数器

    01工作方式1:为16位定时/计数器
    10工作方式2:8位初值自动重装定时/计数器
    11工作方式3:仅适用于T0,分成两个8位计数器,T1停止计数

    下面是程序结构和代码:


    mian.c

    #include "main.h"
    uchar UartRxBuffer[ 64 ] = { 0 };			//uart串口接收数据
    uchar	TX_Cnt = 0;		//发送计数
    uchar	RX_Cnt = 0;		//接收计数
    bit TX_Busy = 0;	  //发送忙标志
    void main()
    {
    	uart_init();
    	while(1)
    	{
    		if((TX_Cnt!=RX_Cnt)&&(!TX_Busy))
    		{
    			//将数组中的数据放入到发送缓冲区
    			SBUF=UartRxBuffer[TX_Cnt];			
    			if(++TX_Cnt>=64)
    			{
    				TX_Cnt=0;
    			}
    			TX_Busy==1;
    		}	
    	}
    }
    
    /*************************************************
    函数:串口程序
    功能:将接收到的数据存入到UartRxBuffer
    *************************************************/
    void UART_INT (void) interrupt 4
    {
    	if(RI)
    	{
    		RI = 0;
    		UartRxBuffer[RX_Cnt] = SBUF;//将数据写入数组
    		//防止溢出,当计数=16时,将计数清零
    		if(++RX_Cnt >= 64){
    			RX_Cnt = 0;
    		}
    	}
    	if(TI)
    	{
    		TI = 0;
    		TX_Busy = 0;
    	}
    }

    mcu_uart.c

    #include "mcu_uart.h"
    
    /*************************************************
    函数:uart_init
    功能:初始化串口
    出口:void
    入口:void
    *************************************************/
    void uart_init()
    {
        SCON = 0x50;//设置串口工作方式1
        TMOD = 0x20;//设置计数器工作方式2
        PCON = 0x00;//即SMOD=1,波特率不加倍
        TH1 = 0xFD;//计数器初值,波特率是9600,晶振为11.0592MHz
        TL1 = 0xFD;
        ES = 1;//打开接收中断
        EA = 1;//打开总中断
        TR1 = 1;//打开计数器		
    }
    
    /*************************************************
    函数:uart_tx_byte
    功能:串口发送一个字节
    出口:void
    入口:一个字节
    *************************************************/
    void uart_tx_byte(uchar str)
    {
    	SBUF=str;
    	while(!TI);
    	TI==0;
    }
    /*************************************************
    函数:uart_tx_string
    功能:串口发送一个字符串
    出口:void
    入口:字符串数组
    *************************************************/
    void uart_tx_string(uchar *str)
    {
    	while(*str!='\0')
    	{
    		uart_tx_byte(*str++);
    	}
    }
    
    /*************************************************
    函数:uart_rx_string
    功能:串口接收一个字符串
    出口:字符串的长度
    入口:字符串数组
    *************************************************/
    uchar uart_rx_string( uchar* RxBuffer )
    {
    	uchar rxLength = 0;
    	uint uartRxTimOut = 0x7FFF;	
    	while( uartRxTimOut-- )
    	{
    		if( 0 != RI )
    		{
    			RI = 0;	
    			*RxBuffer = SBUF;
    			RxBuffer++;
    			rxLength++;
    			uartRxTimOut = 0x7FFF;
    		}
    	}	
    	return rxLength;
    }

    mian.h

    #ifndef __MAIN_H__
    #define __MAIN_H__
    
    #include "mcu_uart.h"
    
    #endif

    mcu_uart.h

    #ifndef __MCU_UART_H__
    #define __MCU_UART_H__
    
    #include "mcu_type.h"
    
    void uart_init();
    #endif

    mcu_type.h

    #ifndef __MCU_TYPE_H__
    #define __MCU_TYPE_H__
    
    #include <reg52.h>
    /*无符号*/
    typedef unsigned char 			uchar;
    typedef unsigned int 				uint;
    
    #endif

    展开全文
  • 基于51 单片机串口收发数据

    万次阅读 热门讨论 2018-10-23 20:43:00
    大多数51单片机用的都是11m晶振而只有少部分用的是奇葩的12m(楼主的就是),在12m晶振进行串口通信时切忌要将波特率设置为4800以下,应为12m晶振的波特率在9600以上误差很大容易丢失数据,动手能力强的可以折腾一下用...

    在进行串口的收发数据过程中一定要注意波特率的问题。

    大多数51单片机用的都是11m晶振而只有少部分用的是奇葩的12m(楼主的就是),在12m晶振进行串口通信时切忌要将波特率设置为4800以下,应为12m晶振的波特率在9600以上误差很大容易丢失数据,动手能力强的可以折腾一下用定时器输出9600波特率。

    至于,串口中断以及波特率的设置可以参考网上例子忒多。

    在用串口助手进行串口收发数据时都会触发串口中断并且在发送数据时只能够一位一位的发送,也就是SBUF=10是不行的智能一位一位发送也就是每次只能发送(0-9或者一个字符)并且串口调试助手接收到的数据是asii码要进行下转换,发送也要进行一下转换。这只是针对串口调试助手

    话不多说直接上代码:

     

    由于代码不方便公布所以只能上图片需要的可以私聊博主

     

     转载请标明原贴出处:https://blog.csdn.net/zj490044512

    展开全文
  • 单片机C语言之串口通信协议

    万次阅读 多人点赞 2017-06-20 14:24:47
    本文详细讲述串口通信的基本原理,分析了51单片机串口协议。适合于入门。
  • 51单片机串口通讯UART

    万次阅读 多人点赞 2018-12-25 20:47:51
    1、串行通信的的基本知识 在实际的工业生产,或者生活中,计算机的CPU要与外部的设备之间进行信息的交流,数据的交换,所有的这些信息交换均可称为通信。 通信的方式有两种,分别为串行通信和并行通信。...
  • 单片机_串口通信知识详解

    千次阅读 2019-02-27 16:13:36
    单片机_串口通信详解   楼主在实际的项目开发过程中,特别是用一些比较常见的传感器,使用最多的通信方式可能就是串口通信了,特别是UART(通用异步收发器),线少,虽然传输速度没有并行传输高,但是对我们要求不高...
  • 【51单片机】(手把手教你)串口通信-基础篇

    万次阅读 多人点赞 2016-01-23 01:11:28
    通信方式 并行 适合短距离通信,并行通信控制简单、相对传输速度快(8位一起传输)。 串行 只能一位一位的传送。 ...建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为...
  • 单片机 串口编程之串口通信仿真实验

    万次阅读 多人点赞 2019-05-30 22:53:31
    单片机 串口编程之串口通信仿真实验 一、简述 记--简单的使能串口串口收发数据的例子。(使用Proteus仿真+虚拟串口调试) 代码,仿真文件打包:链接: https://pan.baidu.com/s/1nyb46fTJrYcAy_VarFdO3A 提取...
  • 最近有同学在51单片机的学习过程中困扰如何使用单片机串口在上位机串口助手上输出显示的问题,其实很多开发环境都支持使用C语言里面最常用的printf函数,Keil中也不例外,不仅仅是C52、keil下其他51系列单片机如STC...
  • 一个简易的51单片机串口接收和发送程序

    万次阅读 多人点赞 2017-08-17 08:56:24
    /********************* 程序功能:接收上位机发过来的一个字符串,然后把该字符串发送给上位机, 字符串必须以!结尾 **********************/ #include #define uchar unsigned char #define uint unsigned int ...
  • 单片机通过UART控制串口

    千次阅读 2018-11-01 22:30:14
    最近工程中需要使用瑞萨RX单片机控制迪文LCD串口屏显示。  首先需要使用迪文开发工具开发工程,定义好各类需要显示的变量... 在配置单片机串口中需要注意的有:  1、串口波特率需要根据单片机数据手册中算出; ...
  • 51单片机串口发送汉字显示乱码问题

    千次阅读 2012-03-22 11:20:44
    前一段时间做蓝牙通信,单片机串口发送汉字总显示乱码,代码如下: //发送一个字节 void SendByte(unsigned char dat) { SBUF = dat; while(!TI); TI = 0; } //发送一个字符串 void SendStr(unsigned ...
  • STC89C51单片机串口程序下载失败总结

    千次阅读 2020-05-12 16:03:28
    STC89C51单片机串口程序下载失败总结个人实践总结(win7 64): 电脑配置的问题 串口下载软件的问题 单片机本身的问题 硬件电路的问题关于电脑配置的问题:其他一切正常,只是在该电脑无法下载程序,可以在“禁用驱动...
  • Description:用中断方式实现串口数据发送 Author:Jcy Date:2012-5-2 */#include #define uint unsigned int #define uchar unsigned char uchar receive_ser; //串口接收到的数据 uchar flag=0; uchar ...
  • 本文详细介绍了串口、51单片机的ISP下载等基础知识,已经学过单片机的也可以看看,加强一下对这方面的了解。 串口 串行接口简称串口,也称串行通信接口,是采用串行通信方式的扩展接口。 ...
  • Matlab与单片机串口通信-matlab…

    万次阅读 多人点赞 2016-12-29 09:54:10
    Matlab提供了对串口进行打开、 关闭、 以及串口参数设置等操作的一系列函数。利用这些函数可以选择串口号、 设置串口通信参数( 波特率、 数据位、 停止位、 校验位等)、进行中断控制、流控制。从建立串口通信到结束...
  • 教训-单片机TTL串口电平不稳定

    千次阅读 2017-04-12 15:43:40
    目前的一个项目中,需要使用单片机串口通讯,由于外部设备的串口电平为TTL电平,故在应用中,将单片机串口IO与外部设备上直接相连的。 但是在后来的调试中,暂时不需要连接外部设备,发现单片机总是会莫名的...
1 2 3 4 5 ... 20
收藏数 30,990
精华内容 12,396
关键字:

单片机串口