s1.inc
来自「Dos 串口通信例程实现了FiFO ,中断发送中断接受!」· INC 代码 · 共 639 行 · 第 1/2 页
INC
639 行
/**************************************************************************************
/ SBS Science & Technology CO.,LTD of shanghai.
/ http://www.sbs.com.cn
/
/ Compiler: Turboc C++ (r) version 3.0
/
/ Last update: December 26, 2005
/
/ This file contains procedure and functions used by the sample programs
/ provided with your serial port The procedures are well documented and should
/ be helpful in learning how to program your serial port
/**************************************************************************************/
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#include <process.h>
#include <conio.h>
#include <bios.h>
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
#include "s1.h"
unsigned char Inchar,ch; //取得键盘参数 设置中间变量
int Raddr,Saddr,Rirq,Sirq,Bit,Stop,Parity; //定义变量 基地址 中断号 数据位 停止位 校验位
long int Sbps,Rbps; // 波特率
int ff; //循环变量
int x1,y1,x2,y2,x3,y3; //三个显示区的光标位置
void interrupt far new_int(...); //定义新的中断接受函数
void interrupt (*old_vect)(...); //定义中断向量 保存原中断向量
void interrupt far asyncint(...); // 用于FIFO
unsigned char flag=0,sendflag=0; // 引起中断标志位
unsigned char Buffer[BUFFLEN],Out_Buffer[BUFFLEN]; // 接受和发送数据缓冲区
int buffin=0,out_buffin=0,k=0; //存数据指针 字符串指针
int buffout=0,out_buffout=0; //显示数据指针
void interrupt far receiveint(...); //中断发送下的中断向量设置
void interrupt (*receivevect)(...);
void interrupt far sendint(...);
void interrupt (*sendvect)(...);
/**************************************************************************************
/该函数的主要功能是接受发送端口和接受端口的 基地址 中断号 和波特率
/以及双方设定的通信格式 数据位 停止位和奇偶校验位
/其中默认设置为:接受基地址Raddr:0x3f8 发送基地址Saddr:0x2f8
/ 接受中断号Rirq : 4 发送中断号Sirq : 3
/ 接受波特率Rbps : 9600 发送波特率Sbps : 9600
/ 双方通信的数据位 Bit :8
/ 双方通信的停止位 Stop:2
/ 双方通信的校验位 Parity: EVEN (偶校验)
/**************************************************************************************/
void test2in(void){ //设置通信参数
char update;
Raddr=0x3f8;Saddr=0x2f8; //默认通信设置
Rirq=4;Sirq=3;
Rbps=Sbps=9600;
Bit=8;
Stop=2;
Parity=EVEN;
printf("\nInit COM1, (default) address 0x3f8,IRQ 4,9600 bps,Receive(Y/N)?Y\b");
do{
update=getch();
}while(!(update=='Y'||update=='y'||update=='N'||update=='n'));//询问是否接受默认设置
printf("%c\n",update);
if(update=='N'||update=='n')
{
printf("Please setup address(Hex),IRQ,bps:\n");
scanf("%x %d %ld",&Raddr,&Rirq,&Rbps);
if(!(Raddr<=0x3ff&&(Raddr%8==0))) //判断输入是否规范
Raddr=0x3f8;
if(!(Rirq>=0&&Rirq<=15))
Rirq=4;
if(!(1843200L%(16*Rbps)==0))
Rbps=9600;
}
printf("Address is %x,IRQ is %d, bps is %ld,Receive data.\n",Raddr,Rirq,Rbps);
printf("Init COM2, (default) address 0x2f8,IRQ 3,9600 bps(Y/N)?Y\b");
do{
update=getch();
}while(!(update=='Y'||update=='y'||update=='N'||update=='n'));
printf("%c\n",update);
if(update=='N'||update=='n')
{
printf("Please setup address(Hex),IRQ,bps:\n");
scanf("%x %d %ld",&Saddr,&Sirq,&Sbps);
if(!(Saddr<=0x3ff&&(Saddr%8==0)))
Saddr=0x2f8;
if(!(Sirq>=0&&Sirq<=15))
Sirq=3;
if(!(1843200%(16*Sbps)==0))
Sbps=9600;
}
printf("Address is %x,IRQ is %d, bps is %ld, Send data.\n",Saddr,Sirq,Sbps);
printf("The format is (default) Bit 8 Stop 2 Parity Even(2 for Even 1 for Odd 0 for None )(Y/N)?Y\b");
do{
update=getch();
}while(!(update=='Y'||update=='y'||update=='N'||update=='n'));
printf("%c\n",update);
if(update=='N'||update=='n')
{
printf("Please setup Bit,Stop,Parity:\n");
scanf("%d %d %d",&Bit,&Stop,&Parity);
if(!(Bit==8||Bit==7||Bit==6||Bit==5))
Bit=8;
if(!(Stop==1||Stop==2))
Stop=2;
if(!(Parity==0||Parity==1||Parity==2))
Parity=2;
}
printf("Bit is %d,Stop is %d, Parity is %d \n",Bit,Stop,Parity);
// textcolor(223); //红色并闪烁
printf("Press any Key Countiune!\n");
getch();
}
/***************************************************************************************
/该函数的主要功能是绘制用于显示发送和接收的数据的窗口及用于显示双方的基本信息的窗口
/其中window()为窗口绘制函数 参数的意义为 left top right bottom 零坐标为左上角(0,0)
/ 右下角为最大值(80,25)
/ 其中颜色值对应为:0 黑 1 蓝 2 绿 3 青 4 红 5 洋红 6 棕 7 淡灰 8 深灰 9 淡蓝 10 淡绿
/ 11 淡青 12 淡红 13 淡洋红 14 黄 15 白 128 闪烁
/**************************************************************************************/
void pesck(void){ //设置图形界面
window(1,25,80,25); // 绘制帮助界面
textbackground(7); //设置背景色
clrscr(); //清屏
textcolor(0); //设置字符的颜色
cprintf(" Press ");
textcolor(4);
cprintf("ESC ");
textcolor(0);
cprintf("Key Exit! Press ");
textcolor(4);
cprintf("F2");
textcolor(0);
cprintf(" change!");
window(1,1,80,24);
textbackground(1);
clrscr();
window(49,2,79,23);
textbackground(7);
textcolor(15);
clrscr();
printf("\xc9" //绘制左上转角图形
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" //双水平线
" Information "
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xbb"); //右上转角
x3=1;
for(y3=2;y3<22;y3++){
gotoxy(x3,y3);
printf("\xba");} //双垂直线
x3=31;
for(y3=2;y3<22;y3++){
gotoxy(x3,y3);
printf("\xba");}
gotoxy(1,22);
printf("\xc8" //左下转角
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xbc"); //右下转角
window(50,3,78,22);
textbackground(7);
textcolor(0);
cprintf("Serial port test:\n\r");
cprintf(" 8 Bit,2 Stop,even\n\r"
" Receive data address ");
textcolor(4);
cprintf("%x\n\r",Raddr);
textcolor(0);
cprintf(" Receive IRQ is ");
textcolor(4);
cprintf("%d\n\r",Rirq);
textcolor(0);
cprintf(" Receive data bps ");
textcolor(4);
cprintf("%ld\n\r",Rbps);
textcolor(0);
cprintf(" Send data address ");
textcolor(4);
cprintf("%x\n\r",Saddr);
textcolor(0);
cprintf(" Send IRQ is ");
textcolor(4);
cprintf("%d\n\r",Sirq);
textcolor(0);
cprintf(" Send data bps ");
textcolor(4);
cprintf("%ld\n\r",Sbps);
x3=wherex();y3=wherey(); //记录信息窗口当前光标的位置
window(2,2,47,11);
textbackground(3);
textcolor(15);
clrscr();
printf("\xc9"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
" Receive Data %3x,%2d,%6ld "
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xbb",Raddr,Rirq,Rbps);
x1=1;
for(y1=2;y1<10;y1++){
gotoxy(x1,y1);
printf("\xba");}
x1=46;
for(y1=2;y1<10;y1++){
gotoxy(x1,y1);
printf("\xba");}
gotoxy(1,10);
printf("\xc8"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd"
"\xbc");
window(3,3,46,10);
textcolor(14);
x1=wherex();y1=wherey(); //记录接受窗口当前光标的位置
window(2,13,47,23);
textbackground(3);
textcolor(15);
clrscr();
printf("\xc9"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
" Send Data %3x,%2d,%6ld "
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xbb",Saddr,Sirq,Sbps);
x2=1;
for(y2=2;y2<11;y2++)
{gotoxy(x2,y2);
printf("\xba");}
x2=46;
for(y2=2;y2<11;y2++){
gotoxy(x2,y2);
printf("\xba");}
gotoxy(1,11);
printf("\xc8"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd"
"\xbc");
window(3,14,46,22);
textcolor(15);
x2=wherex();y2=wherey();//记录发送窗口当前光标的位置
}
/*********************************************************************************************
/该函数的主要功能是 对通信的串口相关寄存器进行初始化: 设置波特率 数据位 停止位 奇偶校验位
/开关FIFO 设置门限值 及初始化Moden控制寄存器
/其中各参数的意义为: addrn : 串口基地址 bpsn : 波特率 rsier : 发送口或接受口的标志位
/ fcr :FIFO使能位 0x00 : 禁止 0xcf :开FIFO 门限值为 14
/********************************************************************************************/
void Init(int addrn,int rsier,long int bpsn,int fcr){
int vailable;
inportb(addrn);
outportb(addrn+LCR,0x80); //设置波特率
outport(addrn,1843200/(16*bpsn));
vailable=Bit-5; //设置数据位 停止位 校验位
if(Stop==2)
vailable=vailable+4;
if(Parity==1)
vailable=vailable+8;
else if (Parity==2)
vailable=vailable+24;
outportb(addrn+LCR,vailable);
outportb(addrn+FCR,fcr); //开FIFO 复位发送 接受FIFO 门限值
if((rsier&0x01)==1) //receive 支持485方式
outportb(addrn+MCR,0x08&0x0b&0xFD);
else
outportb(addrn+MCR,2); //send
}
/*********************************************************************************************
/该函数的主要功能是 使能接受中断 设置相关的中断向量
/其中各参数的意义为: addrn : 串口基地址 bpsn : 波特率 rsier : 发送口或接受口的标志位
/ fcr : 使能FIFO接受中断向量
/********************************************************************************************/
void enableports(int addrn, int irqn,int rsier,int fcr){
int irqnx;
outportb(addrn+IER,rsier); // 开接受中断
if(irqn<8){ // 取得中断向量
outportb(0x21,inportb(0x21)&((0x01<<irqn))); // 开相应的中断号
irqnx=irqn+8;}
else{
outportb(0xA1,inportb(0xA1)&((0x01<<(irqn-8))));
irqnx=irqn+0x70-8;}
old_vect=getvect(irqnx); // 保存原中断向量
disable(); // 屏蔽所有中断
if(fcr==0x00) // 判断是否使用FIFO
setvect(irqnx,new_int); // 设置新的中断向量
else
setvect(irqnx,asyncint);
enable(); // 引起中断
}
/********************************************************************************************
/该函数的主要功能是不使用FIFO方式下中断接受端口数据 并保存的接受数据缓冲区内
/********************************************************************************************/
void interrupt far new_int(...){ //中断函数
unsigned char rchar;
rchar=inportb(Raddr); //读端口数据
flag=1; //设置标志位 说明接受中断已经产生
if(++buffin==BUFFLEN) buffin=0;
if(buffin!=buffout)
Buffer[buffin]=rchar; //保存接受的数据到缓冲区
outportb(0x20,0x20); //写中断结束命令
if(Rirq>=8)
outportb(0xA0,0x20);
}
/********************************************************************************************
/该函数的主要功能是使用FIFO方式下中断接受端口数据 并保存的接受数据缓冲区内
/********************************************************************************************/
void interrupt far asyncint(...){ //支持fifo的中断函数
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?