📄 cantest.c
字号:
//*************************************************************************************
//* 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 + -