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

📄 com_int.h

📁 一个中断法串口通讯程序。
💻 H
字号:
/*** 串口1有关寄存器的说明 ******
   0x3f8     :	 发送缓冲器,接收缓冲器
   0x3f9     :	 中断允许寄存器.
		 D7  D6  D5  D4 D3	  D2	     D1 	   D0
		 *   *	 *   *	MODEM错  接收错  发送保持器空	接收数据完毕
   0x3f8,0x3f9,DLAB=1 : 送除法锁存器,BAUD==1.8432M/data/16.
   波特率    600 1200 1800 2000 2400 3600 4800 7200 9600
	     c0  60   40   3a	30   20   18   10   0c
	     00  00   00   00	00   00   00   00   00
   0x3fb     :	 线路控制寄存器.  D7--DLAB,D6--强迫发送停止位,D5--附加奇偶位,
		    D4--偶校,D3--奇偶允许,   D2    D1	 D0	       ,
					      0     *	  *    1个停止位
					      1     0	  0    1.5个停止位
					      1     其	它     2个停止位
		    D1 D0==00,01,10,11	分别为5,6,7,8个数据位.
   0x3fd     :	 线路状态寄存器. 串口状态,d7--未用,d6--发送移位寄存器空,
		     d5--发送保持器空,d4--停顿指示,d3---祯错,d2--奇偶错,
		     d1--数据重叠,d0--数据就绪
*********************************/
#include "dos.h"
#include "math.h"
#define HEAD 36
#define NUM_R 8
#define NUM_S 36
#define COM 0x2f8
unsigned int data_r[NUM_R],num_r=8;
unsigned int data_s[NUM_S],num_s=0;
int  error_flag=0;
void interrupt (*old)();
static unsigned int label[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,
			0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,
			0xe6,0xed,0xfd,0x87,0xff,0xef};
double data[12]={123,456,789,12,345,678,12.3,1.23,0.12,0.01,111,222};
/************ interrupt function************/
void interrupt int2()
{
  unsigned flag;
  flag=inportb(COM+5)&1;
  if(flag==1)
  { if(num_r==8)
    num_r=0;
    data_r[num_r]=inportb(COM);
    if(data_r[num_r]==HEAD)     //196回发的确认字符为收到的数据个数:36
    num_r++;
  }
  outportb(0x20,0x20);
}
/**********set new vector for com2 interruption*********/
void set_newvect()
{     _disable();
	old=_dos_getvect(0x0b);
      _dos_setvect(0x0b,int2);
      _enable();
}

/*-------恢复原串口中断向量--------*/
void restor_oldvect()
{
    _disable();
    _dos_setvect(0x0b,old);
    _enable();
}
/**********init com************/
void com_init2()
{
    _disable();
    inp(COM); 			//在发送初始化之前,要将原口数据发走;
					//而接收初始化之前,要将原口数据取走
    outportb(COM+3,0x80);			//使DLAB==1
    outportb(COM,0x0c);		//0c
    outportb(COM+1,0);			//除数=12,BAUD=9600.(BAUD=1.8432M/除数/16).
    outportb(COM+3,0x1b);			//线路控制 偶校 1 stop , 8 bits
    outportb(COM+1,0x01);			//接收中断允许
    outportb(COM+4,0x0b);
    outportb(0x21,inp(0x21)&0xf7);		//8259中断屏蔽寄存器.打开串口中断.com2 0xf7,com1 0xef
    _enable();
}
/***********detect error of communication*******/
void detect_error()
{
  if(error_flag>=8)
  {printf("communication error!!!\n\n");
  error_flag=8;
  }
  if(num_r<8)                  //判断是否收到8个确认字符
				//196应该发8个确认字符
	{printf("ERROR....\n"); 
	error_flag++;
	}
  else 
        {error_flag=0;
	printf("OK.....\n");
	}
  num_r=0;                    //接收数据个数清0
}
/*****发送数据头 或 尾********************/
void send_head()
{ unsigned flag;

  outportb(COM,HEAD);
 for(;;)
 {
     flag=inp(COM+5)&64;
     if(flag==64)
     {outportb(COM,HEAD);
      break;
      }
 }
}
/*****************send 36 data to 80c196************/
void send()
{ unsigned flag;
  detect_error();  		//每次发送前检测线路
				//检测条件为196连续8次未回发确认
  num_s=0;		//发送数据个数清0
  printf("send head...\n");
  send_head();		//发送数据头
  printf("send head ok...\n");
  printf("send data...\n");
  outportb(COM,data_s[num_s]);
  num_s++;
  for(;;)
  { flag=inp(COM+5)&64;
     if(flag==64)
     {outportb(COM,data_s[num_s]);
      num_s++;
     }
     if(num_s==NUM_S)
	break;
  }
  printf("send data ok...\n");
  printf("send end...\n");
  send_head();			//发送数据尾
  printf("send end ok...\n");
}

/**************四舍五入,返回int********/
int getint(double f1)
{
if(f1-floor(f1)>=0.5)
return ceil(f1);
else
return floor(f1);
}
/******把一个浮点数变成显示的三位数**********/
void change(double ff,unsigned int a[3])
{
	int temp1, f1;
	if(ff>=100.0)
	{       f1=getint(ff);
		temp1=f1%100;
		a[0]=label[floor(f1/100.0)];
		a[1]=label[floor(temp1/10.0)];
		a[2]=label[temp1%10+10];
	}
	else if(ff>=10.0 )
	{	f1=getint(ff*10.0);
		temp1=f1%100;
		a[0]=label[floor(f1/100.0)];
		a[1]=label[floor(temp1/10.0)+10];
		a[2]=label[temp1%10];
	}
	else if(ff>=1.0 )
	{       f1=getint(ff*100.0);
		temp1=f1%100;
		a[0]=label[floor(f1/100.0)+10];
		a[1]=label[floor(temp1/10.0)];
		a[2]=label[temp1%10];
	}
	else
	{       f1=getint(ff*100.0);
		a[0]=label[10];
		a[1]=label[floor(f1/10.0)];
		a[2]=label[f1%10];
	}
}
/***********把12个显示量变成待输出的数***********/
void convert(double data[12],unsigned int temp[36])
{
	unsigned a[3],i;
	for(i=0;i<12;i++)
	{
	change(data[i],a);
	temp[i*3]=a[0];
	temp[i*3+1]=a[1];
	temp[i*3+2]=a[2];
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -