/***************************************************************************
* FILE : AD_CAN.c *
* Version : V1.0 *
* Description : THis test program is call can841x.lib to implement CAN *
* controller send and recieve messages. *
****************************************************************************/
#include "can841.h" /* Library function declaration */
#include "stdlib.h"
#include "stdio.h"
#include <dos.h>
/*--------------------------------------------------------------------------
--------------------------------------------------------------------------*/
/* define can controller interrupt connect to PC irq number */
#define CAN1_IRQ 15 /* 0 mean polling */
#define CAN2_IRQ 3 /* 0 mean polling */
#define PORT1 0
#define PORT2 1
#define FAIL 0
#define SUCCESS 1
#define IRQ_POLLING 0
static BYTE gIrq0, gIrq1; /*中断号*/
static BYTE old_irq0=IRQ_POLLING; /*PORT1中断号暂时存储单元*/
static BYTE old_irq1=IRQ_POLLING; /*PORT2中断号暂时存储单元*/
static UI gSeg; /*段地址*/
UI MAXSLAVE_NUM =100 ; /* the max number of slave on the data-bus*/
UI ADResult[100][16]; /* 未加处理的A/D转化结果*/
float ADR[100][16]; /* 处理过的A/D转化结果*/
char Changchannal[100][3], ADslave[100][2];/*是否需要改变通道数标志及新通道数;该结点是否在线及是否出错标志*/
static int hw_ok=0; /*硬件配置结果标志*/
static int can_err_no; /*CAN卡配置出错类型标志*/
/*------------------------------------------------
0: no error
0x01 : hardware not release.
0x10: seg_addr set error
0x11: hardware not set successful
0x12: irq_no set error
0x20: bus off
------------------------------------------------*/
/*--------------------------------------------------------------------------*/
void interrupt (*old_isr0)();
void interrupt (*old_isr1)();
void interrupt can_isr0();/*配置PORT1的中断号*/
void interrupt can_isr1();/*配置PORT2的中断号*/
void can0w(BYTE addr, BYTE v);/*向指定地址(PORT1段地址+偏移量)写入一BYTE*/
void can1w(BYTE addr, BYTE v);/*向指定地址(PORT2段地址+偏移量)写入一BYTE*/
BYTE can0r( BYTE addr);/*从指定地址(PORT1段地址+偏移量)读入一BYTE*/
BYTE can1r( BYTE addr);/*从指定地址(PORT2段地址+偏移量)读入一BYTE*/
BYTE canExitHW( void );/*退出时取消硬件设置*/
/*--------------------------------------------------------------------------*/
static BYTE rBuf01[10],rBuf02[10],receiveflag4=0,receiveflag7=0,mainfreqflag=0;/*临时存储单元几接收标志*/
static BYTE rBuf0[10],rBuf1[10]; /*用于PORT1和PORT2的临时存储单元*/
static BYTE gSendFlag0, gSendFlag1;/*PORT1和PORT2的放松标志*/
static BYTE gRecFlag0, gRecFlag1; /*PORT1和PORT2的接收标志*/
/*--------------------------------------------------------------------------*/
void can_reset( BYTE port );/*使该口的SJA1000进入复位状态*/
/*--------------------------------------------------------------------------*/
BYTE CAN_INI(void);
void write_cc_MSG(BYTE,MSG_STRUCT*,BYTE);/*将更改通道数的命令写入发送包*/
void write_cmd_MSG(BYTE,MSG_STRUCT* );/*将88命令写入发送包*/
void mov_ADR(MSG_STRUCT,BYTE,BYTE);/*将接收到的信息从临时存储单元转移到接口数组ADResult[][]中并屏蔽通道号*/
char com[6];
void main(void)
{
char cha;
int ERR_slave,ADRi,Li,MOVi;/*临时变量及算子*/
double waitcounter; /*用于延时用的记数变量*/
/* declare the can card segment address */
CAN_STRUCT can1, can2; /*存储两口配置数据的结构体*/
MSG_STRUCT smsg1, smsg2; /*用于两口中接收数据的接收包*/
MSG_STRUCT rmsg1, rmsg2,ADMRG[4];/*用于两口中发送信息的发送包,及主函数中临时存储接收信息的结构体数组*/
UI i,j; /*临时变量*/
if( CAN_INI()==0)
{printf(" the can card initial is error!");
return;
}
/*-----------------------use in test----------------------*/
clrscr();
cprintf("\r\n TESTING BEGIN \r\n");
cprintf("\r\nThe target ID:");
while(1)
{
for(;;)
{ scanf("%s",&com);
if(atoi(com)<=255)
{ smsg1.id=atoi(com);
break;
}
else
cprintf("\r\nError ID,Please input the ID <=255\r\n");
}
cprintf("\r\nThe data length:(<=8)");
for(;;)
{ scanf("%s",&com);
if(atoi(com)<=8)
{ smsg1.dlen=atoi(com);
cprintf(" %d\n",smsg1.dlen);
break;
}
else
cprintf("\r\nError length,Please input the length <=8\r\n");
}
for(i=0;i<smsg1.dlen;i++)
{cprintf("\r\ndata[%d]=",i);
scanf("%s",&com);
smsg1.data[i]=atoi(com);
/* cprintf(" %d\r\n",smsg1.data[i]);*/
}
if( canSendMsg( PORT1,smsg1)==1 )
printf("the msg transmission is ok!\n");
else
printf("the msg transmission is error!\n");
/*----------------------------use in test------------------*/
/* printf("DO you want to go on? Y (yes) or N (no):\n");
cha=getch();
if( (cha=='y') ||(cha=='Y') )
;
else
if( (cha=='n') || (cha=='N') )
break;
else
{printf("you have input wrong key,the program is stop!\n");
break;
} */
/*---------------------------use in test----------------*/
/*--------------------------------------III---------------------------------------------*/
}
/*退出之前复位*/
/*---- reset can controller */
canReset(PORT1);
canReset(PORT2);
canExitHW();
}
/******************************** the following are son functions***************************/
BYTE CAN_INI(void)
{ /* declare the can card segment address */
UI gSegment=0xDA00;
CAN_STRUCT can1, can2; /*存储两口配置数据的结构体*/
MSG_STRUCT smsg1, smsg2; /*用于两口中接收数据的接收包*/
MSG_STRUCT rmsg1, rmsg2,ADMRG[4];/*用于两口中发送信息的发送包,及主函数中临时存储接收信息的结构体数组*/
BYTE FAIL_FLAG=0;
clrscr();
/*对CAN卡进行初始化*/
if( canInitHW(gSegment,CAN1_IRQ,CAN2_IRQ)== FAIL )
{
clrscr();
cprintf("\n\n hardware initial is error ");
FAIL_FLAG=1;
/* return;*/
}
/*---- reset can controller */
canReset(PORT1);
canReset(PORT2);
/*填写配置代码*/
can1.acc_code=0x00; /*接收码 */
can1.acc_mask=0xff; /* 屏蔽码 */
can1.bt0=0x0f; /*波特率20K*/
can1.bt1=0x7f;
printf("\nthe baud rate=20kbps\n");
/*配置PORT1*/
if( canConfig(PORT1,can1)== FAIL)
{
cprintf("\n\n can controller port %d configure is error ", 1);
FAIL_FLAG=1;
/* return;*/
}
memcpy(&can2, &can1 ,sizeof(CAN_STRUCT));
/*以同样的代码配置PORT2*/
if( canConfig(PORT2,can2)== FAIL)
{
clrscr();
cprintf("\n\n can controller port %d configure is error ", 2);
FAIL_FLAG=1;
/* return;*/
}
/*让两PORT恢复正常运行状态*/
canNormalRun( PORT1); /* Put CAN1,2 to normal mode */
canNormalRun( PORT2);
if( FAIL_FLAG==1)
return (0);
else
return(1);
}
/*将更改通道数的命令写入发送包*/
void write_cc_MSG(BYTE ID,MSG_STRUCT* msg,BYTE chanum)
{ msg->id=ID+0x10;
msg->id=(msg->id<<3);
msg->rtr=0;
msg->dlen=2;
msg->data[0]=0x77;
msg->data[1]=chanum;
}
/*将88命令写入发送包*/
void write_cmd_MSG(BYTE ID,MSG_STRUCT* msg)
{ msg->id=ID+0X10;
msg->id=(msg->id<<3);
msg->rtr=0;
msg->dlen=