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

📄 cantest.c

📁 pc104 规格can卡测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:

//*************************************************************************************
//* All rights reserved (c) 2008                                                      *
//* CNRERD (Dalian, China)                                                            *
//* This computer program may not be used, copied, distributed, corrected,            *
//* modified, translated, transmitted or assigned without CNRERD's prior              *
//* written authorization :                                   *
//*                                                                                   *
//*************************************************************************************
//*                                                                                   *
//* Document         :  cantest.c                                                        *
//*                                                                                   *
//*************************************************************************************
//*                                                                                   *
//* Description      :  can测试程序
//*						can1发送;can2接收,中断号11(硬件板卡需要跳线到IRQ11)       *
//*************************************************************************************
/*******************************************************************************************************************/
//*头文件
/*******************************************************************************************************************/
#include <STDLIB.H>
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include <bios.h>
#include <math.h>
//*************************************************************************************


#define CAN1_IRQ 0 // CAN1中断号设置
#define CAN2_IRQ 11	 // CAN2中断号设置(默认11)
#define PORT1 0		// CAN1
#define PORT2 1		// CAN2

#define FAIL 0
#define SUCCESS 1

#define OK 1
#define ERROR 0

#define CAN1 0      			/*can1 controller base address			*/
#define CAN2 0x200              	/*can2 controller base address			*/
#define RESET_ADDR 0x101        	/*reset address					*/


/*can controller register addr*/
#define  MOD 0
#define  CMR 1
#define  SR 2
#define  IR 3
#define  ACR 4
#define  AMR 5
#define  BTR0  6
#define  BTR1  7
#define  OCR  8
#define  TXB 10
#define  RXB 20
#define  CDR     31

typedef unsigned int UI;
typedef unsigned char BYTE;
#define OK 1
#define ERROR 0

#define CAN1_BPS  125 // CAN1的波特率设置,可选100,125,250,500,1000
#define CAN2_BPS  125 // CAN2的波特率设置,可选100,125,250,500,1000
#define CAN1_ID  0x00 // CAN1的发送ID号
#define CAN2_ID  0x00 // CAN2的发送ID号
#define CAN1_MSK  0xff// CAN1的屏蔽场
#define CAN2_MSK  0xff// CAN2的屏蔽场

static UI SEG;                  /*segment addr*/
static BYTE P_IRQ1,P_IRQ2;      /*interrupt code*/
static BYTE M_main,M_slave;     /*interrupt mask code*/

struct can  			/*2.0A configuration parameter*/
{
	BYTE acc_code;		/*acceptance code*/
	BYTE acc_mask;		/*acceptance mask*/
	BYTE bt0;
	BYTE bt1;
};
struct msg                      /*2.0A data struct of receive or transmite*/
{
	UI id;			/*id[0]-id[10]~ID.0-ID.10*/
	BYTE rtr;
	BYTE dlen;
	char data[8];
};
/*flag whether data is remote transmission request(RTR)*/
struct flag			/*rtr should be set when received data's rtr is 1, and 	*/
{				/*be clear after dealing with RTR			*/
	UI id;
	BYTE rtr;
	BYTE dlen;
};
typedef struct can CAN_STRUCT;
typedef struct msg MSG_STRUCT;

/*define parameters in interrupt routine*/
#define IBUFLEN 1024 			/*length of receive buffer;                     	*/
MSG_STRUCT InBuffer1[IBUFLEN];	/*can1 receive buffer					*/
MSG_STRUCT InBuffer2[IBUFLEN];	/*can2 receive buffer					*/

struct flag flagRtr1,flagRtr2;	/*can1 rtr flag,can2 rtr flag 				*/
int inhead1=0,intail1=0;		/*can1 receive buffer's head and tail			*/
int inhead2=0,intail2=0;		/*can2 receive buffer's head and tail			*/
								/*if inhead is equal to intail,receive buffer is empty	*/

/*basic functions*/
int canInitHW(UI segment, BYTE IRQ1, BYTE IRQ2);  /*install interrupt vect		*/
int canExitHW();                                  /*uninstall interrupt vect		*/
int canReset(BYTE port);                          /*reset can contraller		*/
int canConfig(BYTE port,UI,UI,UI );          	  /*set can controller parameters	*/
int canNormalRun(BYTE port);                      /*enable can run normally		*/
int canSendMsg(BYTE port,MSG_STRUCT send_msg);    /*transmit message			*/
int canReceiveMsg(BYTE port,MSG_STRUCT *msg_ptr); /*receive message			*/
int intCanReceiveMsg(BYTE port,MSG_STRUCT *msg_ptr);/*receive one frame from buffer	*/


/*additional funticons*/
int ErrorHandle(UI base);
int vect(BYTE IRQ);
void install(BYTE v1, BYTE v2);
void uninstall();
void init_8259(BYTE v1,BYTE v2);
void old_8259();                                 /*recovery 8259*/
void interrupt port1();      					 /*can1 interrupt serve function*/
void interrupt port2();                          /*can2 interrupt serve function*/
void interrupt (*oldport1)();
void interrupt (*oldport2)();
void init8259();
main()
{
	UI gSegment=0xC800;	 //段基地址使用默认设置0xC800
	UI temp;
	MSG_STRUCT smsg1,smsg2;
	MSG_STRUCT rmsg1,rmsg2;
	UI i;

	if(canInitHW(gSegment,CAN1_IRQ,CAN2_IRQ)==FAIL)//设置CAN卡在PC 机中的中断号
	{
		printf("\n\n Hardware Initialization Error");
		getch();
		return;

	}
	else
	{
		clrscr();	//清屏
		printf("\n\n Hardware Initialization OK");
	}
	canReset(PORT1); //复位CAN 板,设置CAN 控制器1、2 为复位模式,TX/RX 缓冲区清零
	canReset(PORT2); //复位CAN 板,设置CAN 控制器1、2 为复位模式,TX/RX 缓冲区清零

	if(canConfig(PORT1,CAN1_BPS,CAN1_ID,CAN1_MSK)==FAIL)//设置接收码、屏蔽码和总线时序寄存器
	{

		printf("\n\n CAN Port %d Configuration Error",PORT1);
		getch();
		return;
	}
	else
	{
		printf("\n\n CAN Port %d Configuration OK",PORT1);

	}
	if(canConfig(PORT2,CAN2_BPS,CAN2_ID,CAN2_MSK)==FAIL) //设置接收码、屏蔽码和总线时序寄存器
	{

		printf("\n\n CAN Port %d Configuration Error",PORT2);
		return;
	}
	else
	{
		printf("\n\n CAN Port %d Configuration OK",PORT2);
	}
	canNormalRun(PORT1);//设置CAN 控制器为工作模式
	canNormalRun(PORT2);//设置CAN 控制器为工作模式

//	clrscr();		//清屏
	smsg1.id=0xffff;//id号
	smsg1.rtr=0;
	smsg1.dlen=8;	//数据的长度
	for(i=0;i<smsg1.dlen;i++)
		smsg1.data[i]=i;

	while(1)
	{
		canSendMsg(PORT1,smsg1);  //CAN1发送
//		canSendMsg(PORT2,smsg1);  //CAN2发送


//		printf("\n CAN RUN");
//		if(canReceiveMsg(PORT2,&rmsg2)==1)
		if(intCanReceiveMsg(PORT2,&rmsg2)==1)
		{
			printf("PORT2 receive : ID=%3x RTR=%1d Length=%1d",rmsg2.id,rmsg2.rtr,rmsg2.dlen);
			for(i=0;i<rmsg2.dlen;i++)
				printf(" %2x",rmsg2.data[i]);
			printf("\n");
		}
		if(kbhit())	//如果有键盘输入则跳出程序
		{
			getch();
			break;
		}
	}
	canReset(PORT1);//复位CAN 板,设置CAN 控制器1、2 为复位模式,TX/RX 缓冲区清零
	canReset(PORT2);//复位CAN 板,设置CAN 控制器1、2 为复位模式,TX/RX 缓冲区清零
	canExitHW();	//清除canInitHW()中对中断的设置
	clrscr();		//清屏
}



int canInitHW(UI segment,BYTE IRQ1,BYTE IRQ2)
{
	BYTE v1,v2;

	SEG=segment;                            /*save segment addr*/
	P_IRQ1=IRQ1;                            /*save IRQ	code*/
	P_IRQ2=IRQ2;

	v1=vect(IRQ1);				/*from IRQ code to interrupt vector*/
	v2=vect(IRQ2);
       //	if((v1<0) ||( v2<0)) return ERROR;
	disable();
	install(v1,v2);               	       /*install interrupt vects*/
	init_8259(IRQ1,IRQ2);                  /*init 8259*/
	enable();

	return OK;
}

int canExitHW()
{
	disable();

	uninstall();                          /*uninstall interrupt vects*/
	old_8259();                           /*recovery 8259*/

	enable();

	return OK;
}

int canReset(BYTE port)
{
	int i;
	UI base;
	base=port*0x200;
	pokeb(SEG,base+MOD,0x21);
	i=peekb(SEG,base+RESET_ADDR);
	delay(100);
	if((peekb(SEG,base+MOD)&0x00ff)!=0x21) return ERROR;
	return OK;
}

/*set  can controller config(initial can controller) */
int canConfig(BYTE port,UI can_bps,UI can_id,UI can_mask )
{
	UI base;
	CAN_STRUCT can;
	int i,j,temp;
	can.acc_code=can_id;
	can.acc_mask=can_mask;
	if(can_bps==100){
		can.bt0=0x43 ;
		can.bt1=0x2f;
		}
	else if(can_bps==125) {
		can.bt0=0x03  ;
		can.bt1=0x1c;
		}
	else if (can_bps==250){
		can.bt0=0x01;
		can.bt1=0x1c;
		}
	else if (can_bps==500){
		can.bt0=0x0;
		can.bt1=0x1c;
		}
	else if (can_bps==1000){
		can.bt0=0x00;
		can.bt1=0x14;
		}
	else {
		can.bt0=0x03;
		can.bt1=0x1c;
		}

	base=port*0x200;
	pokeb(SEG,base+MOD,0x09);
	for(i=0;i<5000;i++);
	pokeb(SEG,base+CDR,0x07);

	pokeb(SEG,base+ACR,can.acc_code); /*write receive acceptance code*/
	pokeb(SEG,base+AMR,can.acc_mask); /* write receive acceptance mask code*/
	pokeb(SEG,base+BTR0,can.bt0);	  /*write baudrate*/
	pokeb(SEG,base+BTR1,can.bt1);
	pokeb(SEG,base+OCR,0xfa);	  /*write outcontrol regsiter*/
	for(i=0;i<2;i++);
	temp=peekb(SEG,base+ACR)&0x00ff;
	if((peekb(SEG,base+ACR)&0x00ff)!=can.acc_code ||
	   (peekb(SEG,base+AMR)&0x00ff)!=can.acc_mask)
	   return ERROR;
	else
		return OK;
}

int canNormalRun(BYTE port)                      /*set operating mode*/
{                                                /*soft reset*/
	UI base;
	int i;
	base=port*0x200;

	pokeb(SEG,base+MOD,0x1a);		 /*set operating mode*/
	for(i=0;i<2;i++);
	if((peekb(SEG,base+MOD)&0x1f)!=0x1a) return ERROR;

	return OK;
}

int canSendMsg(BYTE port,MSG_STRUCT send_msg)    /*transmit message*/
{
	BYTE s,frame[2];
	UI base;
	int i;

	base=port*0x200;

⌨️ 快捷键说明

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