main.c

来自「DSP56F807的CAN通讯程序,可用于多子板互连、也可作为开发的原型程序」· C语言 代码 · 共 474 行

C
474
字号
/*
 * MSCAN demo code:
 * Author: William Jiang
 *
 * NOTE: 
 *	1. HyperTerminal baudrate = 9600bps
 *	2. For 56F805:
 *		change the linker command file so that
 *		: pflash orgin from  0x04 and length = 0x7E00-4 
 *		comment two vectors for COP and h/w resets at the first two lines
 *		in IV_Table.
 */

#include "dsp56f805_io.h"
#include "can.h"
#include "rs232.h"
#include "stdio.h"

#define TEST_ECHO	0

#define TEST_29BITS_ID_RX_MASK	0
#define RX_CAN_ID				0x435	//0x1000885DL //0x18f1f160


#define FILTER_16BITS	0
#define FILTER_32BITS	1

#define BAUDRATE_1000KBPS	1	// change can.c to: io.can.ctl1=0x0081
#define BAUDRATE_500KBPS	0	// change can.c to: io.can.ctl1=0x0080
#define BAUDRATE_250KBPS	0
#define BAUDRATE_125KBPS	0

#define CANID_STAND(n,ID,RTR)		CANID##n##_STAND(ID,RTR)
#define CANID_EXT(n,ID,RTR)		CANID##n##_EXT(ID,RTR)

#define	CANID0_STAND(ID,RTR)		((ID & 0x07F8)>>3)
#define	CANID1_STAND(ID,RTR)	(((ID & 0x0007)<<5) | (RTR<<4))

#define	CANID0_EXT(ID,RTR)		((ID & 0x1FFFFFFFL)>>21)
#define	CANID1_EXT(ID,RTR)		((((((ID & 0x1FFFFFFFL)>>15) & 0x0000003FL) & 0x38)<<2) | 0x18 |   \
							((((ID & 0x1FFFFFFFL)>>15) & 0x0000003FL) & 0x7))

#define	CANID2_EXT(ID,RTR)		(((ID & 0x1FFFFFFFL)>>7) & 0xFF)
#define	CANID3_EXT(ID,RTR)		((((ID & 0x1FFFFFFFL) & 0x7F) <<1) | RTR)


#define ID_BITS_MASK_EXT(bitNo)		\
			((bitNo >=21 && bitNo <=28)? (1L << (bitNo-21)) :	\
			(bitNo >=15 && bitNo <=17)? (1L << (bitNo-15+8)) : \
			(bitNo >=18 && bitNo <=20)? (1L << (bitNo-15+8+2)) : \
			(bitNo >=7 && bitNo <=14)? (1L << (bitNo-7+16)) : \
			(1L << (bitNo+1+24)))

/* CAN <-> SCI0 gateway example */
/* after connecting two EVMs via CAN bus, run this code on both of them */
/* and connect SCI0 to 9600 baud terminal with local echo disabled */
/* Any character received through SCI is sent to CAN, any character received */
/* over CAN is sent to SCI and echoed back to provide remote echo */

/* for debugging purposes to see contents of Peripheral registers and Core registers as global variables */
s_io 	*iop=(s_io *)0x0C00;
s_cr	*crp=(s_cr *)0xFF80;

char	*ErrMsg[] =
{
	"Overrun!",
	"Bus-off!",
	"Transmit Error Passive!",
	"Receiver Error Passive!",
	"Transmitter Warning!",
	"Receiver Warning!",
	"Wake up!"	
};
void print_rx_errors(void);
void testCanTx();

void loop (void) {
	struct can_frame frame;
	char c;
	while(1) {
	
		if (can_rxstat()) {
			can_rx(&frame);					/* receive CAN frame */
#if FILTER_16BITS
		#if 0
			if ((frame.id[0]==0xc8)&&(frame.id[1]==0xc0)) {
				frame.id[0]=0x0002;			/* change ID (echo) */
				can_tx(-1,&frame);			/* provide echo on remote terminal using first empty tx buffer */
				sci_putchar(frame.data[0]);		/* treat first data byte as character and display it on local terminal */
			}
		#else
			// ID = 0x435
			if ((frame.id[0]==0x86)&&(frame.id[1]==0xa0)) {
				frame.id[0]=0x0002;			/* change ID (echo) */
				can_tx(-1,&frame);			/* provide echo on remote terminal using first empty tx buffer */
				sci_putchar(frame.data[0]);		/* treat first data byte as character and display it on local terminal */
			}		
		#endif
			else
			if(frame.id[0]==0x00 &&  frame.id[1]==0x00 )
			{
				// Check the Receiver Flag Register to see what kind of errors occured
				sci_send_string("\x0dError: ID = 0x0000 is received!\x0d");
				print_rx_errors();
			}
			else
			{
				print_rx_errors();
			}
		}
		if ((c=sci_getchar())!=-1) {		/* receive character from SCI */
			frame.id[0]=0xc8;				/* ID = 0x646 */
			frame.id[1]=0xc0;				/* standard frame */
#elif FILTER_32BITS
			// test 29 bits ID = 0x646L 
			if ((frame.id[0]==0x00)&&(frame.id[1]==0x08)&&(frame.id[2]==0x06)&&(frame.id[3]==0x8c)) {
				frame.id[0]=0x0002;			/* change ID (echo) */
				can_tx(-1,&frame);			/* provide echo on remote terminal using first empty tx buffer */
				sci_putchar(frame.data[0]);		/* treat first data byte as character and display it on local terminal */
			}
			else
			if((frame.id[0]==0x00 && frame.id[1]==0x00) ||	/* standard frame */
			   (frame.id[0]==0x00 && frame.id[1]==0x08 && frame.id[2]==0x00 && frame.id[3]==0x00) ) /* extended frame */
			{
				sci_send_string("\x0dError: ID = 0x0000 is received!\x0d");
				print_rx_errors();
			}
			else
			{
				print_rx_errors();			
			}
		}
		if ((c=sci_getchar())!=-1) {		/* receive character from SCI */
			frame.id[0]=0x00;				/* ID = 0x646 */
			frame.id[1]=0x08;				/* extended frame */
			frame.id[2]=0x06;
			frame.id[3]=0x8c;
#else
#endif			
			frame.length=1;					/* 1 byte */
			frame.priority=0;
			frame.data[0]=c;				/* put character from SCI into frame */
			can_tx(-1,&frame);				/* transmit the frame over CAN */
		}
	}
}

void main (void) {
	struct can_config config;
	sci_init(260);		/* 9600 baud */

#if BAUDRATE_250KBPS	
	config.timing=0x58c9;   /* 250kbps: 40MHz clk divided by 10, SJW= 4Tq, */
							/* TSEG1 = PROP_SEG+PHASE_SEG1 = 4+5=9, TSEG2 = 6 */
#elif BAUDRATE_125KBPS	
	config.timing=0x23A7;	/* 125kbps: 40Mhz clk divided by 40, */
							/* TSEG1= PROP_SEG+PHASE_SEG1=1+3,TSEG2=3; synchro jump: 3 */
#elif BAUDRATE_400KBPS
	config.timing=0x7A04;	/* 400 kbit: 40Mhz clk divided by 5, TSEG1=11,TSEG2=8; synchro jump: 1 */
#elif BAUDRATE_500KBPS
	// change can.c to: io.can.ctl1=0x0080
	config.timing=0x1401;	/* 0.5 Mbit: 8Mhz external clk divided by 2, segments: 1+4+1+2; synchro jump: 1 */
#elif BAUDRATE_1000KBPS
	// change can.c to: io.can.ctl1=0x0081
	config.timing=0x1404;	/* 1 M bps: 40Mhz internal clk divided by 5 = 8M CAN clock, segments: 1+4+1+2; synchro jump: 1 */
#else
	/// 0.5MHz CAN bit rate using internal PLL clock source
	// change can.c to: io.can.ctl1=0x0081
	//config.timing=0x1409;	/* 0.5 Mbit: 40Mhz internal clk divided by 10=4M CAN clock, segments: 1+4+1+2; synchro jump: 1 */
#endif

#if FILTER_16BITS
	config.filters=0x01;	/* Four 16-bit acceptance filters */

	#if 1
		#if 0
			// Set receiver ID to any, standard frame
			config.acceptance0.f16b.filter0=0xffff;
			config.acceptance0.f16b.filter1=0xffff;
			config.acceptance1.f16b.filter0=0xffff;
			config.acceptance1.f16b.filter1=0xffff;	
			
			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f16b.filter0=0xffff;
			config.mask0.f16b.filter1=0xffff;	
			config.mask1.f16b.filter0=0xffff;
			config.mask1.f16b.filter1=0xffff;
		#else
		
		#if 0
			// Set receiver ID to 0x646, standard frame
			config.acceptance0.f16b.filter0=0xc0c8;
			config.acceptance0.f16b.filter1=0xc0c8;
			config.acceptance1.f16b.filter0=0xc0c8;
			config.acceptance1.f16b.filter1=0xc0c8;	
			
			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f16b.filter0=0x1700;
			config.mask0.f16b.filter1=0x1700;	
			config.mask1.f16b.filter0=0x1700;
			config.mask1.f16b.filter1=0x1700;
		#else
			// Set receiver ID to 0x435, standard frame
			config.acceptance0.f16b.filter0=0xa086;
			config.acceptance0.f16b.filter1=0xa086;
			config.acceptance1.f16b.filter0=0xa086;
			config.acceptance1.f16b.filter1=0xa086;	
			
			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f16b.filter0=0x1700;
			config.mask0.f16b.filter1=0x1700;	
			config.mask1.f16b.filter0=0x1700;
			config.mask1.f16b.filter1=0x1700;
		#endif
		#endif
	#else
			// Set receiver ID to 0x7e8, standard frame
			config.acceptance0.f16b.filter0=0x00FD;
			config.acceptance0.f16b.filter1=0x00FD;
			config.acceptance1.f16b.filter0=0x00FD;
			config.acceptance1.f16b.filter1=0x00FD;	
			
			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f16b.filter0=0x1700;
			config.mask0.f16b.filter1=0x1700;	
			config.mask1.f16b.filter0=0x1700;
			config.mask1.f16b.filter1=0x1700;
	#endif

#elif FILTER_32BITS		/* use extended frame format: 29-bit ID */
	config.filters=0;	/* two 32-bit acceptance filters */

	#if 1
	#if 1
		// Set receiver ID to 0x646, extended frame
		config.acceptance0.f32b.filter0=0xffffffffL;
		config.acceptance1.f32b.filter0=0xffffffffL;
		
		// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
		// AM[2:0]= 111 for 16-bit filters.
		config.mask0.f32b.filter0=0xffffffffL;
		config.mask1.f32b.filter0=0xffffffffL;
	#else
	// Set receiver ID to 0x646, extended frame
	config.acceptance0.f32b.filter0=0x8c060800L;
	config.acceptance1.f32b.filter0=0x8c060800L;
	
	// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 0 for standard frame,
	// AM[2:0]= 111 for 16-bit filters.
	config.mask0.f32b.filter0=0x01001000L;
	config.mask1.f32b.filter0=0x01001000L;
	#endif
	#else
		#if TEST_29BITS_ID_RX_MASK
			// Not to receive messages from ID14 = 0, but 
			// to receive messages from ID14=1,
			// Set receiver ID , extended frame
			config.acceptance0.f32b.filter0= ((CANID_EXT(3,RX_CAN_ID,0) << 8 
							| CANID_EXT(2,RX_CAN_ID,0)) << 8 
							| CANID_EXT(1,RX_CAN_ID,0)) << 8 					
							| CANID_EXT(0,RX_CAN_ID,0);
							
			config.acceptance0.f32b.filter0 |= ID_BITS_MASK_EXT(14);//(1L<<23);//
			
			config.acceptance1.f32b.filter0=config.acceptance0.f32b.filter0;
	

			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 1 for extended frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f32b.filter0=0xFF7FFFFFL;
			config.mask1.f32b.filter0=0xFF7FFFFFL;
		#else
	
			// To Receive messages from RX_CAN_ID,
			// Set receiver ID , extended frame
			config.acceptance0.f32b.filter0= ((CANID_EXT(3,RX_CAN_ID,0) << 8 
							| CANID_EXT(2,RX_CAN_ID,0)) << 8 
							| CANID_EXT(1,RX_CAN_ID,0)) << 8 					
							| CANID_EXT(0,RX_CAN_ID,0);
			config.acceptance1.f32b.filter0=config.acceptance0.f32b.filter0;
			// To Receive messages from RX_CAN_ID,
			// Set mask register IDMR1,3,5,7 bits RTR - don't care, IDE - 1 for extended frame,
			// AM[2:0]= 111 for 16-bit filters.
			config.mask0.f32b.filter0=0x01001000L;
			config.mask1.f32b.filter0=0x01001000L;
		#endif	//TEST_29BITS_ID_RX_MASK
	#endif
#else
#endif
	can_init(&config);

#if TEST_ECHO
	printf("CAN <-> SCI gateway\r\n");
	loop();
#else
	testCanTx();
#endif
}


void print_rx_errors(void)
{
	int	i;
	UWord16 flag;
	
	i=0;
	flag = can_rxflag();
	can_clr_rxflag(flag);	/* clear flags */
	
	if(flag & ~RX_FLAG_BUF_FULL)
	{
		sci_send_string("Error:");
		while( (flag>>=1) & 0x01 )
		{
			sci_send_string(ErrMsg[i++]);
		}
		sci_putchar(0x0d);
	}
}


void testCanTx()
{
	short i;
	struct can_frame frame,frameRx;
	
	for(;;)
	{
			
		#if FILTER_16BITS
			frame.id[0]=CANID_STAND(0,0x7E0,0);				
			frame.id[1]=CANID_STAND(1,0x7E0,0);;				/* standard frame */
			frame.id[2]=0;
			frame.id[3]=0;
		#else
			frame.id[0]=CANID_EXT(0,0x1000885dL,0);				
			frame.id[1]=CANID_EXT(1,0x1000885dL,0);;	/* extended frame */
			frame.id[2]=CANID_EXT(2,0x1000885dL,0);
			frame.id[3]=CANID_EXT(3,0x1000885dL,0);			
		#endif

			// Transmit first frame
			frame.length=8;					
			frame.priority=0;
			frame.data[0]=0x1;						
			frame.data[1]=0x2;						
			frame.data[2]=0x3;						
			frame.data[3]=0x4;						
			frame.data[4]=0x5;						
			frame.data[5]=0x6;						
			frame.data[6]=0x7;						
			frame.data[7]=0x8;						
			can_tx(-1,&frame);
			
	#if TEST_29BITS_ID_RX_MASK			
			// Receive first frame
			while (!can_rxstat()) {};
			can_rx(&frameRx);					/* receive CAN frame */
	#endif	//TEST_29BITS_ID_RX_MASK
				
		#if 0			
			// Transmit second frame			
			frame.data[0]=0x03;						
			frame.data[1]=0x21;						
			frame.data[2]=0x83;						
			frame.data[3]=0x80;						
			frame.data[4]=0x80;						
			frame.data[5]=0x80;						
			frame.data[6]=0x80;						
			frame.data[7]=0x80;						
			can_tx(-1,&frame);

			// Receive second frame
			while (!can_rxstat()) {};
			can_rx(&frameRx);					/* receive CAN frame */

			// Receive third frame
			while (!can_rxstat()) {};
			can_rx(&frameRx);					/* receive CAN frame */
			
			asm(nop);
		#endif
			
#if 0
#if 1
			frame.id[0]=0x86;				
			frame.id[1]=0xa0;				/* standard frame */
			frame.id[2]=0;
			frame.id[3]=0;

			frame.length=4;					
			frame.priority=0;
			frame.data[0]='B';						
			frame.data[1]='y';						
			frame.data[2]='e';						
			frame.data[3]='!';						
			can_tx(-1,&frame);
			
			// wait for a few seconds
			for(i=0;i<2000;i++)
			{
				asm(nop);
				asm(nop);		
			}
#else
	
		// Send first CAN frame: ID = 0x03ce1e41
/*
   bit28  bits 27-24  bits 23-20  bits 19-16  bits 15-12  bits 11-8  bits 7-4  bits 3-0
       0        0011        1100        1110        0001       1110      0100      0001

Data Length: 4 bytes
Data: 0x45030400
     Byte 0  Byte 1  Byte 2  Byte 3
       0x45    0x03   0x04     0x00
*/
		
			frame.id[0]=0x1E;				
			frame.id[1]=0x7C;				/* extended frame */
			frame.id[2]=0x3C;
			frame.id[3]=0x82;

			frame.length=4;					
			frame.priority=0;
			frame.data[0]=0x45;						
			frame.data[1]=0x03;						
			frame.data[2]=0x04;						
			frame.data[3]=0x00;						
			can_tx(-1,&frame);
			
			// wait for a few seconds
			for(i=0;i<2000;i++)
			{
				asm(nop);
				asm(nop);		
			}
		// Send second CAN frame: ID = 0x03ce1e42
/*
   bit28  bits 27-24  bits 23-20  bits 19-16  bits 15-12  bits 11-8  bits 7-4  bits 3-0
       0        0011        1100        1110        0001       1110      0100      0010

Data Length: 4 bytes
Data: 0x45030400
     Byte 0  Byte 1  Byte 2  Byte 3
       0x45    0x03   0x04     0x00
*/
			frame.id[0]=0x1E;				
			frame.id[1]=0x7C;				/* extended frame */
			frame.id[2]=0x3C;
			frame.id[3]=0x84;

			frame.length=4;					
			frame.priority=0;
			frame.data[0]=0x45;						
			frame.data[1]=0x03;						
			frame.data[2]=0x04;						
			frame.data[3]=0x00;						
			can_tx(-1,&frame);
			
			// wait for a few seconds
			for(i=0;i<2000;i++)
			{
				asm(nop);
				asm(nop);		
			}
#endif	
#endif		
			
	}
}

⌨️ 快捷键说明

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