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
一、就是想知道,这个大概的思路是怎么样的?
二、“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
通讯
人女人人呢柔嫩人人呢人呢呢
福利来了,福利来了福利来了,福利来了福利来了,福利来了福利来了,福利来了福利来了,福利来了
串口通讯是异步的,半双工的,
小编的问题 解决了么 真的很厉害
小编的问题 解决了么 真的很厉害