51单片机和pc通信_51单片机与pc串口通信 - CSDN
  • 1.开发步骤 2.串口模块 3.SBUF是什么 4.串口相应寄存器 5.给定波特率求定时值 6.代码实现 1.开发步骤 1.设置串口中断寄存器 2.求出给定波特率对应的T1定时器初始值(因为传统的C51是用T1定时器产生波特率的) ...

    1.开发步骤

    2.串口模块

    3.SBUF是什么

    4.串口相应寄存器

    5.给定波特率求定时值

    6.代码实现


    1.开发步骤

    1.设置串口中断寄存器

    2.求出给定波特率对应的T1定时器初始值(因为传统的C51是用T1定时器产生波特率的)

    3.写程序


    2.串口模块

    什么是串口?串口就是COM口,串口是串行发送数据的,是一位位地发送数据位,常见的是9针串口。但在一般的C51学习版和开发版上都有集成CH340转换芯片,

    使得用usb口就可以代替串口,所以用一般的学习板进行开发,只要插上usb线就可以进行串口测试。


    3.SBUF是什么

    SBUF是一个寄存器,作为一个缓冲区,当单片机准备接收数据时,会先把数据放到SBUF中,然后再接收。发送也是,当单片机准备发送数据时,会先把数据放到

    SBUF中,再发送出去


    4.串口相应寄存器

    SCON串口控制寄存器(主要用方式1)

    SM1,SM0:

    SM0 SM1 工作方式 功能 波特率
    0 0 方式0 8位同步移位寄存器 晶振频率 / 12
    0 1 方式1 10位UART 可变
    1 0 方式2 11位UART 晶振频率/32或晶振频率/64
    1 1 方式3 11位UART 可变

    SM2:----多机通信控制位(可以先不理)

    多机通信是工作在方式2和方式3的,所以SM2主要用于方式2和方式3,多级通信时,SM2=1,当SM2=1时,只有当接收到的数据帧第9位(RB8)为1时,

    单片机才把前八位数据放入自己的SBUF中,否则,将丢弃数据帧。当SM2=0时,不论RB8的值是什么,都会把串口收到的数据放到SBUF中。


    REN:-----允许接收位

    REN用于控制是否允许接收数据,REN=1时,允许接收数据,REN=0时,拒绝接收数据


    TB8:-------是要发送的第9位数据位

    在方式2和方式3中,TB8是要作为数据帧第9位被发送出去的,在多机通信中,可用于判断当前数据帧的数据是地址还是数据,TB8=0为数据,TB8=1为地址


    RB8:-------接收到的第9位数据位

    当单片机已经接收一帧数据帧时,会把数据帧中的第9位放到 RB8中。方式0不使用RB8,在方式2和方式3中,RB8为接收到的数据帧的第9位数据位。


    TI:-----发送中断标志位

    方式0中,不用管他。其他方式下,当发送数据完毕,硬件会将其置1,当 TI 被置1,会向CPU发送中断请求。我们记得要在中断服务程序中把 IT 置回0.


    RI:-----接收中断标志位

    当接受完一帧数据时,RI  由硬件置1,当RI 被置1,会向CPU请求中断。同样要在中断服务程序中把 RI 置回0。


    PCON功率控制寄存器

    这个寄存器只有一个位SMOD,在方式1,2.,3时,波特率都与SMOD有关,当SMOD=1时,波特率会增加一倍。复位时,SMOD变回0



    5.给定波特率求定时值

    串口中断要有定时器T1参加,因为C51是用定时器1来产生波特率的。

    因此就需要给 定时器T1 设置初值。


    首先,我们要选择一个合适的波特率,波特率关乎数据发送的快慢,一般我们选择9600b/s好了,你选2400也没问题。

    一般我们会选择定时器的方式2(这里不是说上面的方式2,而是最大计数为256且自动重载定时器初值的方式)

    使用这种方式是因为它能自动重载定时器初值,不用在中断服务程序中人工重设,可以减少误差。

    下面给出公式:

    Fosc:为晶振频率

    (256-X):最终要求的是X,256出现的原因是定时器的方式2最大技术是256,如果是方式1,则是65536-X

    最后把X化成16进制,高八位赋给 TH1,第八位赋给 TL1


    例子:


    或者可以直接下载一个51波特率计算器:



    6.代码实现:

    测试前提:首先要在PC机(电脑)上下载个串口助手,用于接收51单片机的数据。


    C51发送数据到电脑:

    #include <reg51.h>
    
    typedef   unsigned char  uint8;
    typedef   unsigned int   uint16;
    
    uint8 Buf[]="hello world!\n";
    
    void delay(uint16 n)
    {
    	while (n--);
    }
    
    /*波特率为9600*/
    void UART_init(void)
    {
        SCON = 0x50;        //串口方式1
    
        TMOD = 0x20;        // 定时器使用方式2自动重载
        TH1 = 0xFD;    //9600波特率对应的预设数,定时器方式2下,TH1=TL1
        TL1 = 0xFD;
    
        TR1 = 1;//开启定时器,开始产生波特率
    }
    
    /*发送一个字符*/
    void UART_send_byte(uint8 dat)
    {
    	SBUF = dat;       //把数据放到SBUF中
    	while (TI == 0);//未发送完毕就等待
    	TI = 0;    //发送完毕后,要把TI重新置0
    }
    
    /*发送一个字符串*/
    void UART_send_string(uint8 *buf)
    {
    	while (*buf != '\0')
    	{
    		UART_send_byte(*buf++);
    	}
    }
    
    main()
    {
    	UART_init();
    	
    	while (1)
    	{
    		UART_send_string(Buf);
    		delay(20000);
    	}
    
    }
    效果:串口助手连接后会不停显示 hello world。(串口助手波特率要设成和单片机发送波特率一样,COM口也是)



    电脑发送数据到单片机:

    #include<reg52.h>
    #define uchar unsigned char
    #define uint  unsigned int
    uchar buf;
    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: P1=0xfe;break;   //二进制 0011 0001  十进制 49 控制字符 1  16进制 0X31
    	case 0x32: P1=0xfd;break;	 //1111 1101
    	case 0x33: P1=0xfb;break;
    	case 0x34: P1=0xf7;break;
    	case 0x35: P1=0xef;break;   
    	case 0x36: P1=0xdf;break;	
    	case 0x37: P1=0xbf;break;
    	case 0x38: P1=0x7f;break;
    	}
    	ES=1;		//重新开启串口中断
    
    }
    
    
    效果:当用电脑的串口助手向单片机发送数字1的时候,单片机会亮起LED0,以此类推。

    展开全文
  • 单片机和PC机间的通信有很多方式,下面的程序主要用到的是51单片机的异步串行通信。  一.51单片机的串行通信管脚   P3.1为单片机的TXD管脚(Transfer Data),P3.2为单片机的RXD管脚(Receive Data)。 通过...

    单片机和PC机间的通信有很多方式,下面的程序主要用到的是51单片机的异步串行通信。
      一.51单片机的串行通信管脚 

     P3.1为单片机的TXD管脚(Transfer Data),P3.2为单片机的RXD管脚(Receive Data)。

    通过TXD管脚可以将CPU要发送的数据输出,RXD管脚可以将串行数据线传来的数据读入。

     二.51单片机的串行通信控制寄存器SCON,电源控制寄存器PCON

    SCON:


    其中,SM0,SM1控制着串行通信的工作方式。

    SM0 SM1 工作方式 说明 波特率
    0 0 0 移位寄存器 fosc/12
    0 1 1 10位异步收发器(8位数据) 可变
    1 0 2 11位异步收发器(9位数据) fosc/64或fosc/32
    1 1 3 11位异步收发器(9位数据) 可变

    其中工作方式1在使用当中比较多。

    SM2为多机通信控制位,SM2=1,允许多机通信,=0不允许,实现点对点通信。这里先不讨论。

    TB8用于储存发送数据的第9位。在方式2和方式3中,发送数据除了起始位,数据位,停止位外,还有一位校验位,存储在TB8中。

    RB8用于存储接收数据的第9位。接收到传来的代码后,数据位存储在SBUF中,而校验位就存储在RB8中。通过分析,可以判别接受的数据是否正确。

    TI为发送中断请求标志。当发送数据缓冲区为空的时候,TI通过硬件置1,通知CPU数据发送完毕,需要有软件清零。

    RI为接收中断请求标志。总线上的数据通过RXD引脚串行送入单片机内,通过移位寄存器将串行数据变成并行数据,送入SBUF中。若接收的SBUF已经满,通过硬件置1,通知CPU一帧数据已经接收完毕,可以进行读取。同样需要软件清零。

    PCON中只有最高位SMOD与串行通信有关。

    SMOD=1,波特率在原来的基础上加倍;

    否则,不加倍。

    三.波特率的计算

    对于方式1和方式3,波特率计算公式为:(2^SMOD/32)*(T1的溢出率);

    对于方式2,为fosc*(2^SMOD/64);

    对于方式1,由晶振决定,为固定值。

    T1也就是定时器1,做波特率发生器时,一般典型用法为工作在方式2,也就是自动装载的8位计数模式。TH,TL各8位,但只有TL部分计数,故最大计数值为255。溢出后,TH中的数自动装载到TL中。

    所以,T1溢出率=fosc/{12x(256-TH1)};

    所以可以列出右边为我们所要波特率的方程。同时网上也有许多波特率的计算工具,也可以拿来使用。

     

    最后总结起来,串行通信大致要有这样几步:

    1.确定定时器T1工作方式,也就是编程TMOD寄存器;

    2.装载T1的初值,也就是给TH1,TL1赋值;

    3.确定串行口工作方式,也就是编程SCON和PCON寄存器;

    4.启动T1定时器,也就是令TR1=1;

    5.如果使用中断查询的话,编写中断服务函数

     

    上面这些大概就是串口通信的基本知识了。有了这些知识,就可以编写程序来实践了。

    展开全文
  • 51单片机,WIFI通信,原创 本科毕业设计,就是关于单片机电脑间的无线通信,做得比较认真,需要的可以参考一下!
  • 51 单片机PC 串口通信程序及硬件电路图 2009-10-16 10:18 #include #define BUFFERLEGTH 10 //----------------------------------------------------------------- void UART_init(); //串口初始化...
    51 单片机与PC 串口通信程序及硬件电路图

    2009-10-16 10:18



    #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; //启动定时器T1
    ET1 =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++;
    }
    }
    展开全文
  • 这个是本人大学时期的综合课程设计,单片机和PC机的双向串行通信技术,严禁不注名的转载,后果自负,本人保留一切权利。
  • 基于USB接口的51单片机PC通信的方法,实现上位机下位机数据传输
  • 51单片机PC串口通信程序及硬件电路图2008年03月19日 星期三 21:35 #include #define BUFFERLEGTH 10//-----------------------------------------------------------------void UART_init(); /
    51单片机与PC串口通信程序及硬件电路图
    2008年03月19日 星期三 21:35

     

     

    #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;               //启动定时器T1
    ET1 =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++;
        }
    }

    展开全文
  • 51单片机PC串口通信

    2015-06-01 13:46:18
    本人最近写了一个单片机与电脑的串口通信程序,程序调试成功,希望对大家有所帮助。本程序的功能有:1、通过DS18B20采集温度并通过1602显示出来。2、单片机与电脑进行通信,上位机给单片机一个读温度指令,单片机把...
  • 做了两天终于把232通信做通了,写下总结。 第一、波特率要设置相同。 第二、要在PC机上的设备管理器里把USB转232串口设置为COM2,并且波特率要设置的软件里写的一样。 如下是写的测试程序,精简了通信...
  • 主要是51单片机pc机之间的串口通讯,其程序可由单片机发送数据到pc机,通过串口调试助手可验证是否发送成功。pc机发送数据到单片机可由led显示得以验证。其中程序包含着通讯程序、显示程序、键盘扫描程序
  • 51单片机PC机之间的串口通迅实现方法。一、pc机上的串口通信编程过程 二、单片机89C51串口通信的C语言程序。 1.建立项目 2.在项目中插入MSComm控件 3.利用ClassWizard定义CMSComm类控制对象 4.在对话框中添加控件
  • 单片机PC通信

    2017-12-27 13:09:27
    单片机获取管理传感器的数据,然后通过串口通信将数据发送给PC。 利用proteus仿真单片机和PC通信时,需要用到串口调试助手虚拟串口配置软件。 串口助手用于PC进行数据发送接收,虚拟串口用于将PC的串口...
  • VB串口通信实例:PC机与51单片机串口通信,适合初学者学习上位机与下位机通讯使用。
  • 本文介绍了51单片机PC通信知识总结。
  • 51 单片机的串行口是一个可编程的全双工的通信接口,具有 UART(通用异步收发器)的全部功能,能同时进行数据的发送接收,也可以作为同步移位寄存器使用。51 单片机的串行口主要有两个独立的串行数据缓冲寄存器 ...
  • 单片机PC机之间的通信 51系列单片机内部的串行口具有通信的功能,该串口可以作为通信接口,利用该串行口与PC机的串行口COM1或COM2进行串行通信,将单片机采集的数据传送到PC机中,由PC机的高级语言或数据库语言对...
  • 单片机接收PC机发来的指令信号,然后单片机又向PC机发送字符串。具体要求如下:当接收指令信号为:'go',单片机PC机发送字符串:WELCOME TO CHINA!;当接收指令信号为:'who',单片机PC机发送字符串:MY NAME IS...
  • 串口通信好东西,但我没用过。...有并行通信和串行通信两种。 并行通信通常是将数据字节的各位用多条数据线同时进行传送 。 图一:并行通信 串行通信是将数据字节分成一位一位的形式在。 ...
  • 昨天搞单片机的串口通信,突然一下就对前面学的中断有了进一步的理解。
1 2 3 4 5 ... 20
收藏数 3,847
精华内容 1,538
关键字:

51单片机和pc通信