51单片机 串口程序_51单片机串口程序 - CSDN
  • 看了很多串口通信,应该是配置问题很多代码烧进去都不对,或者没有反应。 代码控制输入,串口输出区输出自己想要的数据,下面直接上代码:(代码亲测有效) /*****************************************************...

    看了很多串口通信,应该是配置问题很多代码烧进去都不对,或者没有反应。
    代码控制输入,串口输出区输出自己想要的数据,下面直接上代码:(代码亲测有效)

    /**************************************************************************************
    *		              串口通信实验												  *
    实现现象:下载程序后打开串口调试助手,将波特率设置为4800,选择发送的数据就可以显示
    			在串口助手上。
    注意事项:无。																				  
    ***************************************************************************************/
    
    #include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
    
    typedef unsigned int u16;	  //对数据类型进行声明定义
    typedef unsigned char u8;
    
    
    /*******************************************************************************
    * 函数名         :UsartInit()
    * 函数功能		   :设置串口
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
    void UsartInit()
    {
    	SCON=0X50;			//设置为工作方式1
    	TMOD=0X20;			//设置计数器工作方式2
    	PCON=0X80;			//波特率加倍
    	TH1=0XF3;				//计数器初始值设置,注意波特率是9600的
    	TL1=0XF3;
    	ES=1;						//打开接收中断
    	EA=1;						//打开总中断
    	TR1=1;					//打开计数器
    }
    void UartPrintf(u8 *p)				//发送字符串
    {	
     	while(*p)
     	{
    	 	SBUF=*p;
    		//UartPrintASCII(*p);
    		while(!TI);
    		TI=0;
    		p++;
    	}   
    }
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {	
    	UsartInit();  //	串口初始化
      while(1)
    	{
    	 UartPrintf("********************\r\n");
    	}
    }
    
    /*******************************************************************************
    * 函数名         : Usart() interrupt 4
    * 函数功能		  : 串口通信中断函数
    * 输入           : 无
    * 输出         	 : 无
    *******************************************************************************/
    void Usart() interrupt 4
    {
    	u8 receiveData;
      //ES=0;
    	receiveData=SBUF;//出去接收到的数据
    	RI = 0;//清除接收中断标志位
    	//ES=1;//notes:加不加ES语句都对
    }
    
    

    如果对于具体配置不懂的,可以自行搜索,这里不再多说。
    由于我用的51,stc90c516rd+,晶振频率将近12MHZ(不到,只是将近),所以不同的频率或许不一样,大家可以通过波特率初值计算软件计算。
    下面是代码烧进去的情况!
    在这里插入图片描述
    注意波特率是加倍前的波特率(4800),记得打开串口,不然没办法看,上面输出的内容,大家可以自行改变。

    展开全文
  • 串口通信好东西,但我没用过。 下面照着普中科技的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单片机串口通信

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

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

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

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

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

    话不多说直接上代码:

     

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

     

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

    展开全文
  • 由于8位单片机一般只有一个串行接口,往往不够用,只能自己写一个模拟串口程序,下面这个程序是自己早先写的,放上来,对别人也许有点用,注意接收端同时接到P3.2(INT0) #include &lt;at89X52.h&gt; #...
  • #include #define uchar unsigned char unsigned char rtemp,sflag; unsigned char code Buffer[] = "Welcome To The MCU World."; //所要发送的数据 unsigned char *p; unsigned char TestBuff[3];
  • 程序功能:接收上位机发过来的一个字符串,然后把该字符串发送给上位机, 字符串必须以!结尾 **********************/ #include #define uchar unsigned char #define uint unsigned int sbit LED = P2^7; uchar ...
  • 含详细例子,RS232串口通信单片机接收发送数据的 C51程序,手把手教你用增强型51 实验板实现RS232 串口通信
  • 51单片机串口程序

    2015-08-05 00:12:48
    工作了一年多,写了不少单片机串口程序。感觉串口多字节接收部分的逻辑相对于配置寄存器跟串口回复来说,是有点难度的——寄存器配置基本上都是死的,串口回复多字节跟回复一字节只是多了一个循环。    串口接收...
  • STC89C51单片机串口程序下载失败总结个人实践总结(win7 64): 电脑配置的问题 串口下载软件的问题 单片机本身的问题 硬件电路的问题关于电脑配置的问题:其他一切正常,只是在该电脑无法下载程序,可以在“禁用驱动...
  • 51单片机串口程序,字符串16进制发送与接收.docx
  • 51单片机串口通信,是全双工的,就是可以同时收/发的,互相不影响的。 串口是可以同时收/发的,虽然都是用SBUF,但却是两个独立的寄存器,互不影响,只是都叫一个名,SBUF。 但是,对于接收或发送,确实是接收到一...
  • http://hi.baidu.com/is_water/item/711238d7043c5cc31b72b462 这篇文章主要来介绍一下51单片机串口,下面先来看一下与串口相关的寄存器。  图1 (该图来自51单片机技术文档) 下面来逐个介绍个寄存器。 SC
  • 由于大部分51单片机不支持在线调试功能,所以串口作为一种有效的调试功能,所以在51单片机程序开发时,无法进行在线调试,不妨可以多采用串口来进行调试。 1.串口配置 51单片机配置除了需要配置2个8位寄存器SCON、...
  • 利用51单片机的串口,编写了串口程序,并且编写了缓冲区处理程序。程序设计了60字节的缓冲区,自己也可以修改缓冲区的大小。
  • 51单片机串口驱动,个人正在使用中,比较好用。
  • 这篇文章将说明51串口通信的发送与接收。分为:单个字符接收,字符串接收;十进制发送与接收,十六进制发送与接收。 字符串发送与十六进制发送,参考:...程序皆由PC串口工具发送,由单片机接收,并返回接收值给PC机。
  • 51 单片机串口通信程序,RS232串口通信 含详细例子。 含详细例子,RS232串口通信单片机接收发送数据的 C51程序,手把手教你用增强型51 实验板实现RS232 串口通信 51串口通信
  • 随着单片机系统的广泛应用和计算机网络技术的普及,单片机的通信功能愈来愈显得重要。单片机通信分为并行和串行通信方式。并行通信通常是将数据字节的各位用多条数据线同时进行传送,每一位数据都需要一条传输线。...
  • C51单片机串口

    2019-07-28 16:36:25
    1、什么是串口 含义:串行接口 作用:有线通信 分类::RS232 TTL RS485 特点: 1.1 数据一位一位地顺序传送; 1.2 通信线路简单,只要一对(两根)传输线就可以通信,发送占用一条线,接收占用一条线; 1.3 ...
1 2 3 4 5 ... 20
收藏数 8,653
精华内容 3,461
关键字:

51单片机 串口程序