📄 hard232.c
字号:
#include <intrins.h>
#include "AT89X52.H"
#include "mult232.h"
extern bit bFinEmpty0; // FiFo 0空
extern bit bFinOver0; // FiFo 0溢出
extern bit bFinEmpty1; // FiFo 1空
extern bit bFinOver1; // FiFo 1溢出
extern bit bFinEmpty2; // FiFo 2空
extern bit bFinOver2; // FiFo 2溢出
struct PACK xdata * xdata TxPackEptr; // 准备发送包
struct PACK xdata * xdata TxPackHptr; // 正在发送包的指针
unsigned int TxCount; // 中断收发计数
unsigned int TxLen; // 中断发送长度
unsigned char xdata *TxPtr; // 发送指针
xdata unsigned char TxPacks; // 待发包计数
bit bTxReady; // 发送器空闲
xdata unsigned char SerialCurDev; // 当前串口设备名称
xdata unsigned char SerialCurPort; // 当前串口信息类型
xdata unsigned char SerialCurControl; // 当前串口控制信息
xdata unsigned char xGps_Control _at_ 0x00A2; // 连接Gps的控制参数(定义见mult232.h)
xdata unsigned char xGps_Port _at_ 0x00A3; // 连接Gps的端口号(低4位)和波特率(高4位)
xdata unsigned char xGprs_Control _at_ 0x00A4; // 连接GPRS的控制参数(定义见mult232.h)
xdata unsigned char xGprs_Port _at_ 0x00A5; // 连接GPRS的端口号(低4位)和波特率(高4位)
xdata unsigned char xBox_Control _at_ 0x00A6; // 连接黑匣子的控制参数(定义见mult232.h)
xdata unsigned char xBox_Port _at_ 0x00A7; // 连接黑匣子的端口号(低4位)和波特率(高4位)
xdata unsigned char xSerialOut[cSerialOutLen] _at_ 0x2000; // 串行发送缓冲
void Init_COMM(void)
{
TMOD &= 0xF0; // 定时器0作为软串口驱动
TMOD |= 0x2; /* 自动重装载 */
TL0 = 0xA1; /* 9600 * 3Hz @ 33M 中断 */
TH0 = 0xA1;
ET0 = 1;
TR0 = 1;
PT0 = 1;
PCON |= 0x80; // 定时器2作为发送波特率
T2CON=0x30;
TR2=1;
InitSoft232(); // 软串口初始化
xBox_Port = (c9600 << 4) + 0; // 黑匣子分配在0号口,波特率9600
xGprs_Port = (c4800 << 4) + 1; // GPRS模块分配在1号口,波特率4800
xGps_Port = (c4800 << 4) + 2; // GPS模块分配在2号口,波特率4800
xBox_Control = cOpen; // 黑匣子端口有效
xGprs_Control = cOpen; // GPRS端口有效
xGps_Control = cOpen; // GPS端口有效
SetSoftBaud( (xGps_Port & 0xf), ((xGps_Port >> 4) & 0xf) );
SetSoftBaud( (xGprs_Port & 0xf), ((xGprs_Port >> 4) & 0xf) );
SetSoftBaud( (xBox_Port & 0xf), ((xBox_Port >> 4) & 0xf) );
InitTxPack(); // 发送缓冲初始化
LinkDevice( cDevGprs ); // 缺省连接GPRS
}
void SetBaud( unsigned char baudmode )
{ // 设置波特率
TR2 = 0;
// bSetBaud = 0;
switch( baudmode )
{
case c9600:
RCAP2H = 0xFF; // 9600 @ 33MHz: 33000000/(32*107)
RCAP2L = 0x95;
break;
case c4800:
RCAP2H = 0xFF; // 4800 @ 33MHz: 33000000/(32*215)
RCAP2L = 0x29;
break;
case c2400:
RCAP2H = 0xFE; // 2400 @ 33MHz: 33000000/(32*430)
RCAP2L = 0x52;
break;
case c1200:
RCAP2H = 0xFC; // 1200 @ 33MHz: 33000000/(32*859)
RCAP2L = 0xA5;
break;
case c600:
RCAP2H = 0xF9; // 600 @ 33MHz: 33000000/(32*1719)
RCAP2L = 0x49;
break;
case c300:
RCAP2H = 0xF2; // 300 @ 33MHz: 33000000/(32*3438)
RCAP2L = 0x92;
break;
}
TR2 = 1;
}
void InitTxPack( void )
{ // 发送缓冲初始化
TxPackHptr = (struct PACK xdata *)xSerialOut;
TxPackHptr->next = (struct PACK xdata *)xSerialOut; // 第一次发送的起始办法
TxPackEptr = (struct PACK xdata *)xSerialOut;
TxPackEptr->bNew = 0;
// TxPackEptr->bComplete = 0;
TxPackEptr->size = 0;
TxCount = 0;
TxPacks = 0; // 待发包计数
bTxReady = 1;
// SentBytes = 0;
}
void CloseTxPack( void )
{
// TxPackEptr->bComplete = 0;
TxPackEptr->bNew = 1;
}
unsigned char CreatTxPack( unsigned int len, unsigned char dev )
// 返回0成功
{
if( TxPackEptr >= TxPackHptr )
{
if( xSerialOut + cSerialOutLen <= (char xdata *)TxPackEptr->next + len + sizeof(struct PACK) )
{
if( (char xdata *)TxPackHptr <= xSerialOut + len + sizeof(struct PACK) )
{
return( 0xff );
}
else
{
DISABLE_INTERRUPTS;
TxPackEptr->next = (struct PACK xdata *)xSerialOut;
ENABLE_INTERRUPTS;
}
}
}
else if( (char xdata *)TxPackHptr <= (char xdata *)TxPackEptr->next + len + sizeof(struct PACK) )
return( 0xff );
if( (TxPackEptr->next > xSerialOut + cSerialOutLen)||(TxPackEptr->next < xSerialOut) )
{ // if 指针出错,初始化发送缓冲
LinkDevice( cDevGprs );
InitTxPack();
return( 0xee );
}
TxPackEptr = TxPackEptr->next;
TxPackEptr->size = len;
TxPackEptr->dev = dev;
TxPackEptr->next = (struct PACK xdata *)((char xdata *)TxPackEptr + len + sizeof(struct PACK));
(TxPackEptr->next)->bNew = 0;
// (TxPackEptr->next)->bComplete = 0;
TxPacks++;
return( 0 );
}
void LinkDevice( unsigned char dev )
// 连接逻辑设备
{
ES = 0;
TR2 = 0;
if( dev == cDevBox )
{
SerialCurPort = xBox_Port;
SerialCurControl = xBox_Control;
}
else if( dev == cDevGps )
{
SerialCurPort = xGps_Port;
SerialCurControl = xGps_Control;
}
else if( dev == cDevGprs )
{
SerialCurPort = xGprs_Port;
SerialCurControl = xGprs_Control;
}
// if( (SerialCurControl & cBit9) )
// SCON = 0xD0; // 9位数据
// else
SCON = 0x50; // 8位数据
SerialCurDev = dev;
SetBaud( ((SerialCurPort >> 4) & 0xf) ); // 波特率
P3 &= 0xCF; // 切换硬件端口(4052)
P3 |= ((SerialCurPort << 4) & 0x30);
ES = 1;
TR2 = 1;
}
void ISR_COMM(void) interrupt 4
{
unsigned char i;
if( RI == 1 )
{
RI=0;
i = SBUF;
// DelayCom_1ms = 250; // 若250ms未收到1个字节,则认为超时
// ReceiveCmd( i );
}
else
{
TI = 0;
if( TxCount < TxLen )
{ // if 正在发送
// if( (SerialCurControl & cBit9) )
// {
// ACC = *TxPtr;
//#pragma asm
// movx a, @dptr
// add a, #00H
// mov c, p
// cpl c
// mov tb8, c
// mov SBUF, a
//#pragma endasm
// }
// else
SBUF = *TxPtr;
TxPtr++;
TxCount++;
}
else
{ // else 当前包发送完毕
if( TxPacks )
TxPacks--;
TxPackHptr->bNew = 0;
bTxReady = 1; // 发送暂停,等待新的包完成.
}
}
}
void SenderDrive( void )
{ // 多串口发送驱动
if( bTxReady ) // 启动发送
{
if( (TxPackHptr->bNew == 0)&&((TxPackHptr->next)->bNew == 1) )
TxPackHptr = TxPackHptr->next; // 释放原空间
if( TxPackHptr->bNew )
{
if( TxPackHptr->dev != SerialCurDev )
{ // 发送包需要切换端口
// if( bPortFree )
// {
// bPortFree = 0;
LinkDevice( TxPackHptr->dev );
// }
// else
// return;
}
if( TxPackHptr->size == 0 )
{
TxPackHptr->bNew = 0;
TxPacks--; // 空包扔掉
}
TxLen = TxPackHptr->size; // 启动当前包发送
TxPtr = TxPackHptr->buf;
TxCount = 1;
// if( (SerialCurControl & cBit9) )
// {
// ACC = *TxPtr;
//#pragma asm
// movx a, @dptr
// add a, #00H
// mov c, p
// cpl c
// mov tb8, c
// mov SBUF, a
//#pragma endasm
// }
// else
SBUF = TxPackHptr->buf[0];
TxPtr++;
bTxReady = 0;
}
else
{ // 都发完了
}
}
}
void main()
{
unsigned char i;
Init_COMM(); // 串口初始化
while( 1 )
{
SenderDrive(); // 多串口发送驱动
if( CreatTxPack( 5, cDevBox ) ) // 往黑匣子发送5个字节
return;
TxPackEptr->buf[0] = 0x55;
TxPackEptr->buf[1] = 0x7a;
TxPackEptr->buf[2] = 0xfb;
TxPackEptr->buf[3] = 0;
TxPackEptr->buf[4] = 0x55 ^ 0x7a ^ 0xfb;
CloseTxPack();
if( CreatTxPack( 3, cDevGprs ) ) // 往GPRS发送3个字节
return;
TxPackEptr->buf[0] = 'A';
TxPackEptr->buf[1] = 'T';
TxPackEptr->buf[2] = 'H';
CloseTxPack();
while( bFinEmpty0 == 0 )
{ // 若缓冲中有数据,连续接收直到空
i = GetFiFo( 0 );
}
if( (bFinOver0)||(bFinOver1)||(bFinOver2) )
{ // if 软串口溢出,错误处理
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -