?? can_example.c
字號:
// ========CAN通信程序=======
#include <pic.h>
#include <pic16f87x.h>
#include <mcp2510.h>
// =========常數和變量定義=========
#define READ 0x03
#define WRITE 0x02
#define RESET 0xC0
#define RTS 0x80
#define STA2510 0xA0
#define BITMOD 0x05
int a[12];
int b[8];
int c[8];
int i;
int count;
int count1=0;
int RecID_H=0;
int RecID_L=0;
int DLC=8;
void SPIINT();
void TMR1INT();
void CCP1INT();
void SPIEXCHANGE(int count);
void WAIT_SPI();
void RESET2510();
int RD2510(int adress,int n);
void WR2510(int adress,int n);
void RTS2510(int RTSn);
int GETS2510();
void BM2510(int adress,int mask,int data);
void SETNORMAL();
void TXCOMPLETE(int adress);
void TXMSG(int DLC);
int RXMSG();
void INIT2510();
void INIT877();
void INITSPI();
void ACK();
void wait();
// ========主程序=======
main(void)
{
int l,detect=0;
SSPIE=1;
TMR1IE=1;
CCP1IE=1;
CCP2IE=1;
PEIE=1;
ei();
INIT877();
INITSPI();
INIT2510();
flag1=0;
flag2=0;
CCP1CON=0x05;
CCP2CON=0x04;
while(1)
{
RXMSG();
TXMSG(8);
}
}
// ========中斷服務程序=======
void SPIINT()
{
SSPIF=0;
a[i++]=SSPBUF;
count-=1;
if(count>0) SSPBUF=a[i];
else RE2=1;
return;
}
//--------------------------
void TMR1INT()
{
TMR1IF=0;
T1CON=0;
if(!flag1)
{
TMR1H=0xfe;
TMR1L=0x00;
T1CON=0x01;
PORTD=0xff;
flag1=1;
}
else
{
flag1=0;
PORTD=0;
T1CON=0;
}
return;
}
//-----------------------------
void CCP1INT()
{
CCP1IF=0;
T1CON=0x01;
return;
}
//-----------------------------
void CCP2INT()
{
CCP2IF=0;
T1CON=0x01;
return;
}
//-----------------------------
void interrupt INTS()
{
di();
if(TMR1IF) TMR1INT();
else if(CCP1IF) CCP1INT();
else if(CCP2IF) CCP2INT();
else if(SSPIF) SPIINT();
ei();
}
// ========子程序=======
void SPIEXCHANGE(count)
int count;
{
if(count>0)
{
i=0;
RE2=0;
SSPBUF=a[i];
}
else
;
return;
}
//-----------------------
void WAIT_SPI()
{
do{
;
}while(count>0);
return;
}
//-------------------------
void RESET2510()
{
a[0]=RESET;
count=1;
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
//-------------------------
int RD2510(adress,n)
int adress;
int n;
{
int j;
a[0]=READ;
a[1]=adress;
for(j=0;j<n;j++) a[j+2]=0;
count=n+2;
SPIEXCHANGE(count);
WAIT_SPI();
for(j=0;j<n;j++) b[j]=a[j+2];
return;
}
//------------------------
void WR2510(adress,n)
int adress;
int n;
{
int j;
a[0]=WRITE;
a[1]=adress;
for(j=0;j<n;j++) a[j+2]=b[j];
count=n+2;
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
//--------------------------
void RTS2510(RTSn)
int RTSn;
{
a[0]=RTS^RTSn;
count=1;
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
//-----------------------------
int GETS2510()
{
a[0]=STA2510;
a[1]=0;
count=2;
SPIEXCHANGE(count);
WAIT_SPI();
b[0]=a[1];
return;
}
//-----------------------------
void BM2510(adress,mask,data)
int adress;
int mask;
int data;
{
a[0]=BITMOD;
a[1]=adress;
a[2]=mask;
a[3]=data;
count=4;
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
//-----------------------------
void SETNORMAL()
{
int k=1;
BM2510(CANCTRL,0xe0,0x00);
do {
RD2510(CANSTAT,1);
k=b[0]&0xe0;
}while(k);
return;
}
//-----------------------------
void INIT2510()
{
RESET2510();
b[0]=0x02;
b[1]=0x90;
b[2]=0x07;
WR2510(CNF3,3);
b[0]=0x00;
b[1]=0x00;
WR2510(RXM0SIDH,2);
b[0]=0x00;
b[1]=0x00;
WR2510(RXF0SIDH,2);
b[0]=0x00;
WR2510(CANINTE,1);
SETNORMAL();
return;
}
//-----------------------------
void TXCOMPLETE(adress)
int adress;
{
int k=1;
do {
RD2510(adress,1);
k=b[0]&0x08;
}while(k);
return;
}
//-----------------------------
void INIT877()
{
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
PORTE=0;
TRISA=0xff;
TRISB=0xfd;
TRISC=0xd7;
TRISD=0;
TRISE=0x03;
PORTA=0xff;
PORTB=0x03;
PORTC=0;
PORTD=0xff;
PORTE=0x04;
return;
}
//-----------------------------
void INITSPI()
{
SSPCON=0x11;
SSPEN=1;
SSPSTAT=0;
return;
}
//-----------------------------
void TXMSG(int DLC)
{
for(i=0;i<DLC;i++) b[i]=c[i];
WR2510(TXB0D0,DLC);
b[0]=DLC;
WR2510(TXB0DLC,1);
b[0]=0x03;
b[1]=RecID_H;
b[2]=RecID_L;
WR2510(TXB0CTRL,3);
RTS2510(0x01);
TXCOMPLETE(TXB0CTRL);
return;
}
//-----------------------------
int RXMSG()
{
int k;
RD2510(CANINTF,1);
k=b[0]&0x01;
if(k==1) {
BM2510(CANINTF,0x01,0x00);
RD2510(RXB0SIDH,2);
RecID_H=b[0];
RecID_L=b[1]&0xe0;
RD2510(RXB0DLC,1);
DLC=b[0]&0x0f;
RD2510(RXB0D0,DLC);
for(i=0;i<DLC;i++) c[i]=b[i];
return 1;
}
return 0;
}
//-============又一個===============================
#INCLUDE <P18F248.INC>
;發送數據是08H
;*************LOCAL MACROS***************
CONFIGURE_MODE MACRO
BSF CANCON,REQOP2
ENDM
NORMAL_MODE MACRO
BCF CANCON,REQOP2
BCF CANCON,REQOP1
BCF CANCON,REQOP0
BCF CANCON,ABAT
ENDM
;******************復位矢量中斷向量*************
ORG 000h
NOP
GOTO MAIN
;*****************主程序*************************
MAIN
CALL CLR_BANK ;CLEAR ALL BANK 0,1,2,15
;**********開始進入傳輸初始化的設定***************
SETUP
MOVLB 0FH ;BANK 15
MOVLW B'11000000' ;ENABLE ALL
MOVWF INTCON ;enable gie
MOVLW B'00000000' ; MOVWF PIE3
CALL SET_PORT ;set port
CALL TXB0_IDENTIFIER ;TXB0 FILTER
CALL RXB0_FILTER0 ;RXB0 FILTER0
CALL BAUD_RATE ;50KB/S
NORMAL_MODE ;NORMAL MODE
MOVLW 08h ;發數據,現在是08H
MOVWF TXB0D0
BSF TXB0CON,TXREQ
BTFSS PIR3,TXB0IF ;判斷是否發出去
GOTO $-2
BCF PIR3,TXB0IF
STOP
NOP
GOTO STOP
;******************RXB0 FILTER0****************
;RXB0_FILTER0
; STANDARD FRAME
;PORTA 低五位作為ID的高五位
;*********************************************
RXB0_FILTER0
CONFIGURE_MODE
BCF RXB0CON,RXM1
BCF RXB0CON,RXM0
;0,0 FILTER 有效
;0,1 ONLY STANDARD FRAME
;1,1 RECEIVE ALL
;1,0 ONLY EXTERN FRAME
MOVLW B'10101111'
MOVWF RXF0SIDH
MOVLW b'11100000'
MOVWF RXF0SIDL
MOVLW B'11111111' ;識別位XXXXX000111
MOVWF RXM0SIDH
MOVLW B'11111111' ;全部起作用
MOVWF RXM0SIDL ;進行屏蔽位設定,全部為11
RETURN
;*********設置TXB0 IDENTIFIER***********************
;TXB0_IDENTIFIER
;***************************************************
TXB0_IDENTIFIER
BCF TXB0CON,TXPRI1
BCF TXB0CON,TXPRI0 ;high interrupt
MOVLW B'10101111'
MOVWF TXB0SIDH
MOVLW B'11100000' ;標志位是XXXXX000111
MOVWF TXB0SIDL
MOVLW B'00000001'
MOVWF TXB0DLC ;數據幀 6,txrtr是零
RETURN
;***********SET_PORT******************************
SET_PORT
;********PORTB********
;RB0 OUT
;RB1 OUT
;RB2 OUT TXCAN
;RB3 IN RXCAN
;RB4 IN
;RB5 IN
;RB6 ICD2
;RB7 ICD2
CLRF LATB
MOVLW B'00001000'
MOVWF TRISB
;*******PORTC*********
;RC0 OUT RC0-RC7 ALL OUT
;RC1 OUT
;RC7 OUT
CLRF LATC
MOVLW B'00000000'
MOVWF TRISC
RETURN
;**************BAUD RATE SET******************
; FOSC =4MHZ
; NOMINAL BIT TIME = 8 TQ
; TQ=2*(BAUD RATE +1)/FOSC
; SYN =1 TQ,PRO=1TQ,PHE1=3TQ,PHE2=3TQ
; BAUD RATE= 50KB/S
; BAUD RATE PRESCALER=00100
; fosc =4mhz MAX_baud rate=250kb/s
; If fosc=16Mhz ,the max_band=1Mkb/s
;************************************************
BAUD_RATE ;50KB/S
CONFIGURE_MODE
MOVLW B'00000100' ;BAUD RATE SET
MOVWF BRGCON1
MOVLW B'10010000'
MOVWF BRGCON2
MOVLW B'00000010'
MOVWF BRGCON3
RETURN
;**********CLEAR BANK************************
CLR_BANK
LFSR FSR0,00H ;BANK 0
NEXT CLRF POSTINC0
BTFSS FSR0H,0
GOTO NEXT
LFSR FSR0,100H
NEXT1 CLRF POSTINC0 ;BANK1
BTFSS FSR0H,1
GOTO NEXT1
LFSR FSR0,200H
NEXT2 CLRF POSTINC0 ;BANK 2
BTFSS FSR0H,0
GOTO NEXT2
LFSR FSR0,0F00H
NEXT3 CLRF POSTINC0 ;BANK 15
BTFSS FSR0L,7
GOTO NEXT3
RETURN
END
#INCLUDE <P18F248.INC>
; 接收數據
;*************LOCAL MACROS***************
CONFIGURE_MODE MACRO
BSF CANCON,REQOP2
ENDM
NORMAL_MODE MACRO
BCF CANCON,REQOP2
BCF CANCON,REQOP1
BCF CANCON,REQOP0
BCF CANCON,ABAT
ENDM
;******************復位矢量中斷向量*************
ORG 000h
NOP
GOTO MAIN
ORG 0008h
RXB0_INTERRUPT
BCF RXB0CON,RXFUL ;必須清零,否則會溢出到RXB1D0
BCF PIR3,RXB0IF
MOVFF RXB0D0,PORTC ;接收到放到PORTC顯示
RETFIE
;*****************主程序*************************
MAIN
CALL CLR_BANK ;CLEAR ALL BANK 0,1,2,15
;**********開始進入傳輸初始化的設定***************
SETUP
MOVLB 0FH ;BANK 15
MOVLW B'11000000' ;ENABLE ALL
MOVWF INTCON ;enable gie
MOVLW B'00000001' ;ONLY ENABLE RXB0IE
MOVWF PIE3
CALL SET_PORT ;set port
CALL RXB0_FILTER0 ;RXB0 FILTER0
CALL BAUD_RATE ;250KB/S
NORMAL_MODE ;NORMAL MODE
STOP
NOP
GOTO STOP
;******************RXB0 FILTER0****************
;RXB0_FILTER0
; STANDARD FRAME
;*********************************************
RXB0_FILTER0
CONFIGURE_MODE
BCF RXB0CON,RXM1
BCF RXB0CON,RXM0
;0,0 FILTER 有效
;0,1 ONLY STANDARD FRAME
;1,1 RECEIVE ALL
;1,0 ONLY EXTERN FRAME
MOVLW B'10101111'
MOVWF RXF0SIDH;
MOVLW b'11100000'
MOVWF RXF0SIDL
MOVLW B'11111111' ;識別位XXXXX000111
MOVWF RXM0SIDH
MOVLW B'11111111' ;全部起作用
MOVWF RXM0SIDL ;進行屏蔽位設定,全部為11
RETURN
;***********SET_PORT******************************
SET_PORT
;********PORTB********
;RB0 OUT
;RB1 OUT
;RB2 OUT TXCAN
;RB3 IN RXCAN
;RB4 IN
;RB5 IN
;RB6 ICD2
;RB7 ICD2
CLRF LATB
MOVLW B'00001000'
MOVWF TRISB
;*******PORTC*********
;RC0 OUT RC0-RC7 ALL OUT
;RC1 OUT
;RC7 OUT
CLRF LATC
MOVLW B'00000000'
MOVWF TRISC
RETURN
;**************BAUD RATE SET******************
; FOSC =4MHZ
; NOMINAL BIT TIME = 8 TQ
; TQ=2*(BAUD RATE +1)/FOSC
; SYN =1 TQ,PRO=1TQ,PHE1=3TQ,PHE2=3TQ
; BAUD RATE= 50KB/S
; BAUD RATE PRESCALER=00100
; fosc =4mhz MAX_baud rate=250kb/s
; If fosc=16Mhz ,the max_band=1Mkb/s
;************************************************
BAUD_RATE ;50KB/S
CONFIGURE_MODE
MOVLW B'00000100' ;BAUD RATE SET
MOVWF BRGCON1
MOVLW B'10010000'
MOVWF BRGCON2
MOVLW B'00000010'
MOVWF BRGCON3
RETURN
;**********CLEAR BANK************************
CLR_BANK
LFSR FSR0,00H ;BANK 0
NEXT CLRF POSTINC0
BTFSS FSR0H,0
GOTO NEXT
LFSR FSR0,100H
NEXT1 CLRF POSTINC0 ;BANK1
BTFSS FSR0H,1
GOTO NEXT1
LFSR FSR0,200H
NEXT2 CLRF POSTINC0 ;BANK 2
BTFSS FSR0H,0
GOTO NEXT2
LFSR FSR0,0F00H
NEXT3 CLRF POSTINC0 ;BANK 15
BTFSS FSR0L,7
GOTO NEXT3
RETURN
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -