zoukankan      html  css  js  c++  java
  • 基于51单片机的Uart串口通信协议

    1.串口通信协议

      嵌入式开发中,UART串口通信协议是我们常用的通信协议(UART、I2C、SPI等)之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输,它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外部设备进行全双工数据交换。

    1)起始位

      当未有数据发送时,数据线处于逻辑“1”状态;先发出一个逻辑“0”信号,表示开始传输字符。

    2)数据位

      紧接着起始位之后。资料位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟定位。

    3)奇偶校验位

      资料为加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。

    4)停止位

      它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

    5)空闲位或起始位

      处于逻辑“1”状态,表示当前线路上没有资料传送,进入空闲状态。

      处于逻辑“0”状态,表示开始传送下一数据段。

    6)波特率

      表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。

      常用的波特率有:9600、115200……

      时间间隔计算:1秒除以波特率得出的时间,例如,波特率为9600的时间间隔为1s / 9600(波特率) = 104us。

    7)接口

           接口通过两个引脚从外部连接到其它设备。任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX):
      RX:接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。
      TX:发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O 用于发送和接收数据。

     2.发送函数

      这里的发送指的是51单片机发送数据到串口,单片机的TX接串口的RX。

      首先要根据你单片机的晶振频率,调试出一个104us的延时函数,用于时序控制。

      

     void Delay_104us(void)
    {
        uint x=58;
    	while(x-- !=0)
    	{
    		_nop_();
    	}
    }
    

      这个延时是基于下图所示的频率

                                             

      然后是发送函数

    /************串口发送函数,Tx_Data为要发送的数据***********/
    void Uart_Tx(uchar Tx_Data)
     {
    	uchar uData=Tx_Data;	 
    	uint i=0;
    
    	/************拉低单片机的TX引脚104us,作为开始信号***********/
    	UART_TX=0;
    	Delay_104us();
    	/************根据一字节数据每一个比特位的不同,TX拉高或拉低,保持104us,作为数据信号***********/
    	for(i=0;i<8;i++)
    	{
    		UART_TX= uData & 0x01;
    		Delay_104us();
    		uData=uData>>1;
    
    	}
    	/************拉高单片机的TX引脚104us,作为结束信号***********/
    	UART_TX=1;
    	Delay_104us();
    }
    

     3.接收函数 

      这里的接收指的是51单片机接收串口所发的数据,单片机的RX接串口的TX。

      这里还要调试出一个52us的延时。

      

    void Delay_52us(void)
    {
        uint x=28;
    	while(x-- !=0)
    	{
    		_nop_();
    	}
    }
    

      接收函数

     /************串口接收函数,返回值为接收到的数据***********/
    uchar Uart_Rx(void)
    {
        uchar R_Data = 0x00,i;
        /************判断单片机的RX引脚是否拉低,有没有开始信号***********/    
        if( UART_RX== 0)
        {
        /************如果有,再过52us判断一次,这是防抖操作***********/    
            Delay_52us();
            if(UART_RX == 0)
          {
             /************如果是真的,就没过104us判断一次RX的电平变化,记录每一位数据***********/    
                Delay_104us();
                for(i=0;i<8;i++)
                {
                    R_Data=R_Data>>1;
                    if(UART_RX == 1)
                    {
                        R_Data=R_Data|0x80;
                    }                
                    Delay_104us();                
                }            
            }
             /************判断单片机的RX引脚是否拉高,有没有结束信号,如果有就返回和重新用串口发送接收到的数据***********/    
            Delay_104us();
            if(UART_RX == 1)
            {
                Uart_Tx(R_Data);
                return R_Data;      
            
            }
        }
       
        return 0;
    
    }

    4.其他

    (1)引脚定义

    这里面的TX和RX引脚是自定义的,只要能够拉高,拉低,延时就行,下面是我定义的,

    #define UART_TX P17
    #define UART_RX P15
    

    (2)发送汉字 

      每一个汉字都是由两个字节作为地址,在字库里索引出来的,发送就是发送汉字的地址,方法如下。

    void Uart_String(uchar *Tx_String)
    {
    	while(*Tx_String)
    	{
    		Uart_Tx(*Tx_String++);
    	}
    } 
    

    5.检验

      首先接好杜邦线,单片机的TX,RX接串口的RX,TX,还有GND线要接,VCC线可以不接。

            在主函数的while(1)循环里调用Uart_Tx(0x34),发送0x34,注意把串口助手的波特率调为9600。

       在主函数的while(1)循环里调用Uart_Rx(),单片机接收串口发送的数据

     

      在主函数的while(1)循环里调用Uart_String(),发送汉字,注意要把HEX显示去掉,不然就是16进制数了

      

  • 相关阅读:
    Codeforces Ilya and Matrix
    poj 1308 Is It A Tree?
    Codeforces Sereja and Array
    poj 1041 John's trip
    Codeforces Continued Fractions
    WM_COPYDATA实现进程间数据通信
    虚拟机中安装ubuntu后,终端模式和图形模式切换
    IIS上配置运行cgi,php,aspx运行环境
    linux c main函数参数
    Linux网络编程入门 (转载)
  • 原文地址:https://www.cnblogs.com/feiniaoliangtiangao/p/13936707.html
Copyright © 2011-2022 走看看