⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hard232.c

📁 用C51和汇编混合实现4个软串口的程序
💻 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 + -