微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > UART串口通讯转单线设计求解(stc89c52)

UART串口通讯转单线设计求解(stc89c52)

时间:10-02 整理:3721RD 点击:
这是硬件图,这个通讯是有自发自收的功能的,且使得串口的距离可以大大提高,线材好的情况下有600米!是别人的东西,现在想学学,由于本人学术不精,有许多地方不明白的,请高手进来讲解讲解。感谢啦@!



一、就是想知道,这个大概的思路是怎么样的?
二、“INT8U XDATA U8_Transmit_State        =0;” “  INT8U IDATA temp;:像这些定义中,都在变量前”XDATA“"IDATA"谁知道这样定义的作用和好处?
三、这个“Tx_Len          =  1;”代表标志位嘛?
UART.C如下:
#include "..\H\MAIN.H"
#include "..\H\UART.H"
#include "..\H\OS_Q.H"
#include "..\h\Reload_TX_Data.h"          
#include "..\H\DO_COMMAND.H"
#include "stdlib.h"
/********************************************************************************************************/
bit ReadySendCode(INT8U Command, INT8U N_Tx );
INT8U ReadTransmitData(void);
void TxSoftTime(void);
void TransmittConter(void);
void StopSend(void);
/*********************************************************************************************************/
                               
INT8U XDATA U8_Transmit_State        =0;
INT8U XDATA SerialOutData[SERILOUTNUM];
INT8U XDATA SerialInData[SERILINNUM];
static INT8U XDATA  Tx_Len                         = 0;
static INT8U XDATA  N_TxData                = 0;
static INT8U XDATA  TransmitCode         = 0;
static INT8U XDATA  TransmittTime0        = 0;
static INT16U XDATA TransmittTime1        = 0;
static INT16U XDATA TransmittTime2        = 0;
static INT16U XDATA TransmitOverTm        = 0;

/********************************************************************************************************/
INT8U ReadTransmitData(void)
{
        return         TransmitCode;
/*
        if(TransmitCode)
                return FALSE;
        else
                return TRUE;
*/
}
/********************************************************************************************************/
bit ReadySendCode(INT8U Command, INT8U N_Tx )
{
        if(TransmitCode)// || (!Command) || (!N_Tx) )
                return FALSE;
        TransmitCode =         Command;
        N_TxData     =   N_Tx;   
        return TRUE;
}       
/********************************************************************************************************/
void Send(void)
{
        SBUF      = SerialOutData[0];
        Tx_Len          =  1;
}           
/********************************************************************************************************/
void StopSend(void)
{
        U8_Transmit_State = STOP_U8_TRANSMIT;
        TransmitOverTm    = 0;          
        TransmitCode             = 0;
}               
/********************************************************************************************************/
void comm(void) interrupt 4         // using 1          串口中断
{                                                                                                       
    INT8U IDATA temp;
        if (RI == 1)
        {
                RI = 0;
                temp = SBUF;         //接受数据
                #if !DEBUGUART
                if(Tx_Len)
                {
                        if(temp == SerialOutData[Tx_Len-1])
                        {
                                if(Tx_Len == SerialOutData[1])
                                {       
                                        Tx_Len = 0;
                                        U8_Transmit_State = U8_TRANSMITBYSELFOK;
                /*                        #ifdef DEBUGLED
                                        Hint_Led(1);   
                                        #endif
                */                        return;
                                }
                                SBUF = SerialOutData[Tx_Len];
                                Tx_Len++;
                                return;
                        }
                        Tx_Len = 0;
                        U8_Transmit_State = U8_COLLIDERETX;
                }
                #endif
                TransmittTime0   = 12;
        OSQIntPost(SerialInData,SBUF);
                return;
        }
        if (TI == 1)
        {
                TI = 0;
                #if  DEBUGUART
                if(Tx_Len)
                {
                        if(Tx_Len == SerialOutData[1])
                        {       
                                Tx_Len = 0;
                                U8_Transmit_State = U8_TRANSMITBYSELFOK;
                                return;
                        }
                        SBUF = SerialOutData[Tx_Len];
                        Tx_Len++;
                        return;       
                }
                #endif
        }
}
//发送数据 变量
//放入定时器 NOTICE;
/********************************************************************************************************/
/*
void TxSoftTime(void)
{
        if(TransmittTime0)
                TransmittTime0--;       
    if(TransmittTime1)
                TransmittTime1--;
        if(TransmittTime2)
                TransmittTime2--;
    if(TransmitOverTm)
        {
                if((--TransmitOverTm) == 0)
                        U8_Transmit_State = U8_TRANSMITOVERTIME;
        }
}
*/
void UARTSoftTime(INT8U gapTime)
{
        if(TransmittTime0)
                if(TransmittTime0 <= gapTime)
                {
                        TransmittTime0 = 0;          
                }
                else
                {
                        TransmittTime0 -= gapTime;
                }
//==========================================================================                       
        if(TransmittTime1)
                if(TransmittTime1 <= gapTime)
                {
                        TransmittTime1 = 0;          
                }
                else
                {
                        TransmittTime1 -= gapTime;
                }
//==========================================================================
        if(TransmittTime2)
                if(TransmittTime2 <= gapTime)
                {
                        TransmittTime2 = 0;          
                }
                else
                {
                        TransmittTime2 -= gapTime;
                }
//==========================================================================
        if(TransmitOverTm)
                if(TransmitOverTm <= gapTime)
                {
                        TransmitOverTm = 0;
                       
                        U8_Transmit_State = U8_TRANSMITOVERTIME;          
                }
                else
                {
                        TransmitOverTm -= gapTime;
                }
}
/********************************************************************************************************/
void TransmittConter(void)
{
        static INT8U IDATA step       = 0x00;
        static bit    ReTransmit = 0x00;
        if (U8_Transmit_State == STOP_U8_TRANSMIT )
            step       = 0x00;
        switch(step)
        {
                case 0 :         if(!TransmitCode)                                       
                                                break;
                                        U8_Transmit_State  = 0;
                                        ReloadTxData(TransmitCode);                     //装码
                                        TransmitOverTm     = TRANSMITOVERTIME*N_TxData*2;         //设置发码超时
                                        if(N_TxData>1)
                                        {
                                                ReTransmit = ON;
                                                TransmittTime2 = RETRANSMITTIME;// ADD延时重发
                                        }
                                        else
                                                ReTransmit = OFF;
                                        step = 1;
                                        break;
                case 1 :          if(TransmittTime0)
                                        {
                                                if(!TransmittTime1)
                                                        TransmittTime1=(TL1%5*2);
                                        }
                                        else if(!TransmittTime1)
                                        {
                                                Send();
                                                step = 3;           
                                        }
                                        goto SEG_CkTxState;
                                        break;
               
               
                case 2 :        if(!TransmittTime1)
                                        {
                                        //        U8_Transmit_State = 0x00;
                                                step = 1;
                                        }
                case 3 :           
SEG_CkTxState :        if((ReTransmit)&&(!TransmittTime2))
                                        {
                                                if((--N_TxData)==0)         
                                                {                                                                                                                  
                                                        U8_Transmit_State  =  U8_TRANSMITFALSE;//发送失败        
                                                }
                                                else  
                                                {         
                                                        step = 0x01;
                                                        TransmittTime2 = RETRANSMITTIME;// ADD延时重发
                                                }  
                                        }
                                        else if(U8_Transmit_State == U8_COLLIDERETX)
                                        {
                                                U8_Transmit_State = U8_TRANSMITCOLLIDE;
                                                TransmittTime1 = TL1%50 *2;
                                                step = 2;
                                        }
                                        if(((!ReTransmit) && (U8_Transmit_State == U8_TRANSMITBYSELFOK))||(U8_Transmit_State == U8_TRANSMITFALSE)|| (U8_Transmit_State ==
U8_TRANSMITOVERTIME)||(U8_Transmit_State == U8_TRANSMITOK))
                                        {
                                                step           = 0;
                                                TransmitOverTm = 0;
                                                TransmitCode   = 0X00;       
                                        }
                                        break;
                default:        break;               
        }
       
}
/********************************************************************************************************/
UART.H

#define TRANSMITOVERTIME   (SYSTIMEFOSC)
#define RETRANSMITTIME     SYSTIMEFOSC
#define U8_TRANSMITSAMECODE 32     
#define U8_TRANSMITOK       2           
#define U8_COLLIDERETX      16           //不能读到,因为这个状态很快就会更新到U8_TRANSMITCOLLIDE,,,,这是为什么?
#define STOP_U8_TRANSMIT        64          //由用户告知

#define U8_TRANSMITBYSELFOK 1          // 自发自收成功
#define U8_TRANSMITFALSE    4     //发码失败
#define U8_TRANSMITCOLLIDE  8          //发码冲突
#define U8_TRANSMITOVERTIME        128          //发码超时
#define SERILINNUM          20
#define SERILOUTNUM                        20
extern bit ReadySendCode(INT8U Command, INT8U N_Tx );
extern INT8U ReadTransmitData(void);
extern void TransmittConter(void);
extern void TxSoftTime(void);
extern void UARTSoftTime(INT8U gapTime);
extern void StopSend(void);
extern INT8U XDATA U8_Transmit_State;                 //只有在调用ReadySendCode()成功的情况下,发送状态会被清除,用户也可在其他程序中将其清除;
extern INT8U XDATA SerialOutData[SERILOUTNUM];
extern INT8U XDATA SerialInData[SERILINNUM];

MAIN.H
#include "reg52.h"                 
/*****************************************************************/
//宏定义
/*****************************************************************/
#define STC89                1
#define INT8U  unsigned char
#define INT16U unsigned int
#define ON    1
#define OFF   0
#define TRUE  1                                                                       
#define FALSE 0
#define XDATA                idata
#define IDATA       data
/*****************************************************************/                          
//独立波特率发生器地址定义
sfr AUXR      = 0X8E;                                //8E=10001110辅助寄存器第4位是独立波特率运行控制位,第0位是0则串口1用定时器1作波特率发生器,是1则用独立波特率发生器做
sfr AUXR1     = 0XA2;                                // sfr 是用于定义特殊寄存器的关键字
sfr BRT       = 0X9C;
#if STC89 ==1
sfr WDT_CONTR = 0XE1;                           //看门狗寄存器
#else
sfr WDT_CONTR = 0XC1;                           //看门狗寄存器
#endif
sfr CLKdiv    = 0X97;                           //分频时钟
sfr P1M0           = 0X92;
sfr P1M1           = 0x91;
sfr P3M0           = 0XB2;
sfr P3M1           = 0XB1;
/*****************************************************************/
//波特率设置初值
/*****************************************************************/
#define FOSC        6000000                     //晶振频率
#define DUL_SMOD    1
#define BUADSPEED   1250                     //串口波特率
#define SYSTIMEFOSC 200       
#define T1_FREQ                SYSTIMEFOSC       
#define T2_FREQ     SYSTIMEFOSC                        //定时器2频率 12T模式
/*****************************************************************/
#define TH1_RELOAD    ((65536 - (FOSC  / 12) / T1_FREQ ) / 256)
#define TL1_RELOAD    ((65536 - (FOSC  / 12) / T1_FREQ ) % 256)

#if DUL_SMOD == 1                                                                                //12T模式
#define T1_RELOAD   (256 - 2 * FOSC/32/12/BUADSPEED)                 //"波特率=2^(sod)*fosc/(32*12*(256-初值))"
#define BRT_RELOAD  (256 - 2*FOSC/BUADSPEED/32/12)                   //独立波特率波特率设置
#else
#define T1_RELOAD   (256 - FOSC/32/12/BUADSPEED)                         //"波特率=2^(sod)*fosc/(32*12*(256-初值))"
#define BRT_RELOAD  (256 - FOSC/BUADSPEED/32/12)                   //独立波特率波特率设置
#endif  
#define TH2_RELOAD        ((65536 - (FOSC  / 12) / T2_FREQ ) / 256)
#define TL2_RELOAD        ((65536 - (FOSC  / 12) / T2_FREQ ) % 256)
/*****************************************************************/
//调试
/*****************************************************************/
#define DEBUGUART        0

通讯



人女人人呢柔嫩人人呢人呢呢

福利来了,福利来了福利来了,福利来了福利来了,福利来了福利来了,福利来了福利来了,福利来了


串口通讯是异步的,半双工的,

小编的问题 解决了么   真的很厉害

小编的问题 解决了么   真的很厉害

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top