📄 uart.c
字号:
#define UART_GLOBALS
#include "main.h"
#include "UART.h"
//#include "string.h"
#include "delay.h"
void UART_Init()
{
PCON = 0x80; // SMOD = 1;
SCON = 0x50; // Mode 1, 8-bit UART, enable receiption
TMOD = 0x21; // Timer 1, mode 2, 8-bit auto reload,
MyAddr = 0;
BaudNum = 7;
TH1=BaudRateTable[BaudNum];
TL1=BaudRateTable[BaudNum];
TR1 = 1;
RcvStatus = RCVSTX;
SerDTValid = FALSE;
SerTmOut = 0;
SendFlag = FALSE;
SendStatus = SENDIDLE;
RS485_TXen = 0;
REN = 1;
ES = 1;
}
void UART_Isr() interrupt 4 using 1
{
INT8U temp;
static INT8U SerLen,ExtData;
static INT8U LenSend; //已发送的有效数据长度
if(RI)
{
temp = SBUF;
if(temp == STX)
{ //在任何时候收到STX,即可视为一帧的开始
RcvStatus = RCVDATA;
SerLen = 0;
RcvDTLen = 0;
SerTmOut = 2; //启动超时定时器
}
else if(temp == ETX)
{
if(RcvStatus == RCVDATA)
{
if(SerTmOut)
{ //在未超时的情况下,接收数据后又收到一个ETX,则本帧数据有效
SerDTValid = TRUE;
}
RcvStatus = RCVSTX;
}
}
else if(RcvStatus == RCVDATA)
{
if((SerTmOut==0) || (temp&0x80))
RcvStatus = RCVSTX; //超时或数据中的bit7为1,则本帧数据作废
else
{
SerTmOut = 2;
if((SerLen&0x07) == 0)
{ //扩展字节
ExtData = temp;
}
else
{
if(ExtData & 0x01)
{
temp |= 0x80;
}
SerBfr[RcvDTLen++] = temp;
ExtData >>= 1;
}
SerLen++;
}
}
if(SerDTValid)
{
SerDTValid = FALSE;
if(RcvDTLen == (SerBfr[LENGTH]+6))
{
temp = 0;
for(SerLen=0;SerLen<RcvDTLen;SerLen++)
temp ^= SerBfr[SerLen];
if(temp == 0xff)
{
if(SerBfr[RADDR] == MyAddr)
{
SerDTValid = TRUE;
}
}
}
}
RI = 0;
}
else
{
if(SendStatus == SENDSTX)
{
SBUF = STX;
SendStatus = SENDDATA; //下次中断发送数据
SerLen = 0;
LenSend = 0;
}
else if(SendStatus == SENDDATA)
{
if((SerLen&0x07) == 0)
{
ExtData = 0;
temp = LentoSend>=7?7:LentoSend; //计算扩展数据位长度
do
{
ExtData <<= 1;
if(SerBfr[LenSend+(temp-1)]&0x80)
ExtData |=0x01;
temp--;
}while(temp);
SBUF = ExtData; //发送扩展数据
}
else
{
SBUF = SerBfr[LenSend]&0x7f;
LenSend++;
LentoSend--;
if(LentoSend == 0)
{ //有效数据已发送完毕
SendStatus = SENDETX; //下次中断发送ETX
}
}
SerLen++;
}
else if(SendStatus == SENDETX)
{
SBUF = ETX; //发送ETX
SendStatus = SENDSTOP; //下次中断结束本次发送
}
else if(SendStatus == SENDSTOP)
{
RS485_TXen = FALSE;
SendFlag = FALSE;
SendStatus = SENDIDLE; //发送器空闲
}
TI = 0;
}
}
INT8U Ser_Send(INT8U SlvAddr)
{
INT8U i;
if(SendStatus == SENDIDLE)
{
SerBfr[RADDR] = SlvAddr; //从机地址
SerBfr[SADDR] = MyAddr;
LentoSend = SerBfr[LENGTH]+5;
SerBfr[LentoSend] = 0;
for(i=0;i<LentoSend;i++)
{
SerBfr[LentoSend] ^= SerBfr[i];
}
SerBfr[LentoSend] = ~SerBfr[LentoSend];
LentoSend++;
RS485_TXen = 1;
SendStatus = SENDSTX;
TI = 1;
return TRUE;
}
else
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -