?? canzj.c
字號(hào):
#include <P18F258.H>
#include "MCP2510.H"
#include <delays.h>
void MCP2510Rec(void);
//------------------------------------
struct JFSC //計(jì)時(shí)時(shí)長(zhǎng)、
{
unsigned char hour;
unsigned char min;
unsigned char sec;
unsigned char msec;
};
typedef union {
unsigned char word;
struct {
unsigned TMSEC_BIT:1; //100ms事件
unsigned TSEC_BIT:1; //1s事件
unsigned TMIN_BIT:1; //1min事件
unsigned THOUR_BIT:1; //1hour事件
unsigned CANRV_BIT:1;//CAN接收標(biāo)志
unsigned CAN2510RV_BIT:1;//CAN2510接收標(biāo)志
unsigned INT0_BIT:1;
unsigned RSV1_BIT:1;
}Bits;
}uProceSate;
struct CanRevType
{
unsigned char FrameID[4];
unsigned char FrameData[8];
};
typedef union {
unsigned char word;
struct {
unsigned RX0IF:1; //接收緩沖器0 滿中斷標(biāo)志
unsigned RX1IF:1; //接收緩沖器1 滿中斷標(biāo)志
unsigned TX0IF:1; //發(fā)送緩沖器0 空中斷標(biāo)志
unsigned TX1IF:1; //發(fā)送緩沖器1 空中斷標(biāo)志
unsigned TX2IF:1; //發(fā)送緩沖器2空中斷標(biāo)志
unsigned ERRIF:1; //出錯(cuò)中斷標(biāo)志
unsigned WAKIF:1; //喚醒中斷標(biāo)志
unsigned MERRF:1; //報(bào)文出錯(cuò)中斷標(biāo)志
}Bits;
}CAN2510IntStatus;
//------------變量--------------------
volatile struct JFSC CLOCK;
volatile uProceSate StateTemp;
struct CanRevType CanTxData;
struct CanRevType Can2510TxData;
volatile struct CanRevType CanRevData;
volatile struct CanRevType Can2510RevData;
unsigned char DebugErrorCode;//錯(cuò)誤代碼
unsigned char TestTryTime;
volatile CAN2510IntStatus MCP2510IntStatus;
unsigned char Thread;
//--------------------------------------
#define NO_THREAD 0x00
#define THREAD_IDLE 0x01
//#define Debug
//----------- 初始化程序---------------
void init_cpu(void)
{
//---------------------
INTCON = 0x00; //禁止所有中斷
INTCON2 = 0x00;//int0 下降沿中斷
INTCON3 = 0x00;
ADCON1 = 0x87; //設(shè)置所有與模擬輸入共用的管腿為I/O方式
//---初始化管腿------------
TRISA = 0xfc;//RA0 RA1為輸出
TRISB = 0xfb;//配置CAN
TRISC = 0xd0;//配置SPI SDO為輸出 SDI為輸入 SCK為輸出
//---初始化timer0------------
T0CON = 0x8F;//16位定時(shí)器,不使用分頻器
TMR0H = 0xD8;
TMR0L = 0xEF;//定時(shí)10ms
//------初始化CAN控制器--------
CANCON = 0x80;//進(jìn)入配置方式
//while((CANSTAT&0x80)==0x00);//等待進(jìn)入配置模式
DebugErrorCode=0x00;
TestTryTime=100;
while(TestTryTime--) //等待進(jìn)入配置模式
{
if((CANSTAT&0x80)==0x80) break;
}
if(TestTryTime==0x00) DebugErrorCode=CAN_ENTCONFG_ERR;
//設(shè)置CAN的波特率為5K,在Fosc=4M時(shí),Tbit=200us,假設(shè)BRP=39, 則
//TQ=[2*(1+BRP)]/Fosc=2*(1+39)/4=20us。
//NOMINAL BIT RATE=10TQ,SJW=1,Sync_Seg=1TQ,Prog _Seg=1TQ,Phase_Seg1=4TQ,Phase_Seg2=4TQ
BRGCON1 = 0x27; //設(shè)置SJW和BRP,SJW=1TQ,BRP=39H
BRGCON2 = 0x98; //設(shè)置Phase_Seg1=4TQ和Prog _Seg=1TQ
BRGCON3 = 0x43; //設(shè)置Phase_Seg2=4TQ
CIOCON = 0x00;//設(shè)置CAN輸入輸出控制寄存器
TXB0CON = 0x03;//設(shè)為最高優(yōu)先級(jí)
TXERRCNT= 0x00;//清除發(fā)送錯(cuò)誤計(jì)數(shù)器
RXB0CON = 0x00;//接收所有有效信息
RXB0DLC = 0x08;//接收數(shù)據(jù)長(zhǎng)度為8
RXERRCNT= 0x00;//清除接收錯(cuò)誤計(jì)數(shù)器
//初始化接收濾波器
RXF0SIDH= 0xff;
RXF0SIDL= 0xeb;
RXF0EIDH= 0xff;
RXF0EIDL= 0xff;
RXM0SIDH= 0x00;
RXM0SIDL= 0x00;
RXM0EIDH= 0x00;
RXM0EIDL= 0x00;
CANCON = 0x00;//進(jìn)入正常工作模式
//while((CANSTAT&0xE0)!=0x00);//等待進(jìn)入正常模式
TestTryTime=100;
while(TestTryTime--) //等待進(jìn)入正常模式
{
if((CANSTAT&0xE0)==0x00) break;
}
if(TestTryTime==0x00) DebugErrorCode=CAN_QUITCONFG_ERR;
PIR3 = 0x00; //清除所有中斷標(biāo)志
//PIE3 = 0x01; //使能接收0的中斷
//PIE3 = 0xe1; //使能接收0的中斷
PIE3 = 0x61; //使能接收0的中斷
IPR3 = 0x01; //接收0的中斷為最高優(yōu)先級(jí)
//------初始化SPI------------------
PIE1bits.SSPIE=0; //禁止中斷
SSPCON1 = 0x30; //SSPEN=1;CKP=1;主控方式Fosc/4(1M波特率)
SSPSTAT = 0xc0;
PIR1bits.SSPIF=0;//清除SSPIF標(biāo)志
//------設(shè)置中斷優(yōu)先級(jí)--------------
INTCON2bits.TMR0IP=0;//timer0 高優(yōu)先機(jī)
RCONbits.IPEN=1;//使能中斷優(yōu)先級(jí)
//------初始化管腿----------------
PORTAbits.RA0=0;
PORTAbits.RA1=0;
CAN2510Disable();
MCP2510REST=1;
Thread=NO_THREAD;
StateTemp.word=0x00;//清標(biāo)志位
}
//------timer0中斷程序------------------
void timer0int(void);
#pragma code Low_Vector=0x18
void InterruptVectorLow (void)
{
_asm
goto timer0int
_endasm
}
#pragma code
#pragma interrupt timer0int
void timer0int(void)
{
unsigned char temp;
if(INTCONbits.T0IF)//timer0中斷
{
TMR0H = 0xD9;
TMR0L = 0x7a;//定時(shí)10ms
INTCONbits.T0IF=0; //清中斷標(biāo)志
if((CLOCK.msec%10)==0) StateTemp.Bits.TMSEC_BIT=1; //100ms事件
if(++CLOCK.msec>=100)
{
CLOCK.msec=0;
StateTemp.Bits.TSEC_BIT=1;//秒事件
++CLOCK.sec;
temp=CLOCK.sec;
if((temp&0x0f)>9) CLOCK.sec=(temp&0xf0)+0x10;
if(CLOCK.sec>=0x60)
{
CLOCK.sec=0;
StateTemp.Bits.TMIN_BIT=1; //分事件
++CLOCK.min;
temp=CLOCK.min;
if((temp&0x0f)>9) CLOCK.min=(temp/16)*16+0x10;//(temp&0xf0)+0x10;
if(CLOCK.min>=0x60)
{
StateTemp.Bits.THOUR_BIT=1;//小時(shí)事件
CLOCK.min=0;
CLOCK.hour++;
temp=CLOCK.hour;
if((temp&0x0f)>9) CLOCK.hour=CLOCK.hour&0xf0+0x10;
if(CLOCK.hour==0x24) CLOCK.hour=0;
}
}
}
}
}
//------------------CAN程序-----------------------------
void send_data(unsigned char FrameType, unsigned char IDbuff[4],unsigned char DataBuff[8])
{
unsigned char temp;
unsigned char temp1;
unsigned char Flag;
Flag=0x00;
temp1=IDbuff[1]>>5;
temp=IDbuff[0]<<3;
TXB0SIDH=temp+temp1;
temp1=(IDbuff[1]&0x1f)<<3;//取后5位
temp=IDbuff[1]&0x03;//取后2位
temp1=temp1+temp;
if(FrameType==1) temp1=temp1|0x08;
if(FrameType==0) temp1=temp1&0xf7;
TXB0SIDL= temp1;
TXB0EIDH= IDbuff[2];
TXB0EIDL= IDbuff[3];
TXB0DLC = 0x08;//設(shè)置發(fā)送數(shù)據(jù)長(zhǎng)度為8
TXB0D0 = DataBuff[0];
TXB0D1 = DataBuff[1];
TXB0D2 = DataBuff[2];
TXB0D3 = DataBuff[3];
TXB0D4 = DataBuff[4];
TXB0D5 = DataBuff[5];
TXB0D6 = DataBuff[6];
TXB0D7 = DataBuff[7];
TXB0CONbits.TXREQ=1;//請(qǐng)求發(fā)送
while(PIR3bits.TXB0IF!=1) //ClrWdt(); //等待
{
ClrWdt(); //等待
if(TXB0CONbits.TXLARB)//丟失仲裁,(斷路)
{
TXB0CONbits.TXABT=1;//中止發(fā)送
TXB0CONbits.TXREQ=0;
TXERRCNT= 0x00;//清除發(fā)送錯(cuò)誤計(jì)數(shù)器
DebugErrorCode=CAN_SEND1_ERR;
Flag=0x01;
break;
}
if(TXB0CONbits.TXERR)//總線錯(cuò)誤(短路)
{
TXB0CONbits.TXABT=1;//中止發(fā)送
TXB0CONbits.TXREQ=0;
TXERRCNT= 0x00;//清除發(fā)送錯(cuò)誤計(jì)數(shù)器(可能不起作用)
DebugErrorCode=CAN_SEND2_ERR;
Flag=0x02;
break;
}
if(COMSTATbits.TXBO)//發(fā)送錯(cuò)誤計(jì)數(shù)大于255,總線關(guān)閉
{
TXB0CONbits.TXABT=1;//中止發(fā)送
TXB0CONbits.TXREQ=0;
TXERRCNT= 0x00;//清除發(fā)送錯(cuò)誤計(jì)數(shù)器(可能不起作用)
DebugErrorCode=CAN_SEND3_ERR;
Flag=0x03;
break;
}
}
if(Flag==0x00) DebugErrorCode=CAN_SENDOK;
}
void CanRecvInt(void);
#pragma code High_Vector=0x08
void InterruptVectorHigh (void)
{
_asm
goto CanRecvInt
_endasm
}
#pragma code
#pragma interrupt CanRecvInt
void CanRecvInt(void)
{
unsigned char temp,temp1,temp2;
//INTCONbits.GIE=0;//關(guān)總中斷
PORTAbits.RA1=0;
//----------PIC18F258 CAN中斷程序-------------
if(PIR3bits.RXB0IF==1) //接收緩沖區(qū)0接收中斷
{
temp=RXB0SIDH;
temp1=RXB0SIDL;
CanRevData.FrameID[0]=temp>>3;
temp2=temp1&0x03;//取后2位
temp2=temp2+((temp1&0xe0)>>3);
temp2=((temp&0x07)<<5)+temp2;
CanRevData.FrameID[1]=temp2;
CanRevData.FrameID[2]=RXB0EIDH;
CanRevData.FrameID[3]=RXB0EIDL;
CanRevData.FrameData[0]=RXB0D0;
CanRevData.FrameData[1]=RXB0D1;
CanRevData.FrameData[2]=RXB0D2;
CanRevData.FrameData[3]=RXB0D3;
CanRevData.FrameData[4]=RXB0D4;
CanRevData.FrameData[5]=RXB0D5;
CanRevData.FrameData[6]=RXB0D6;
CanRevData.FrameData[7]=RXB0D7;
StateTemp.Bits.CANRV_BIT=1; //置接收標(biāo)志
RXB0CONbits.RXFUL=0;//清除接收緩沖區(qū)
PIR3bits.RXB0IF=0; //清除接收中斷
}
if(PIR3bits.IRXIF==1) //錯(cuò)誤收信息中斷,與監(jiān)聽(tīng)模式聯(lián)合使用確定波特率
{
PIR3bits.IRXIF=0;
}
if(PIR3bits.WAKIF==1) //總線喚醒中斷,休眠模式下,退出休眠
{
PIR3bits.WAKIF=0;
}
if(PIR3bits.ERRIF==1) //總線錯(cuò)誤中斷
{
PORTAbits.RA1=0;
if(COMSTATbits.RXB0OVFL)//接收緩沖區(qū)0溢出
{
COMSTATbits.RXB0OVFL=0;//清除溢出
DebugErrorCode=CAN_REVBUFF0_ERR;
}
if(COMSTATbits.RXWARN)//接收器警告位
{
RXERRCNT= 0x00;//清除接收錯(cuò)誤計(jì)數(shù)器
DebugErrorCode=CAN_REVWAR_ERR;
}
if(COMSTATbits.TXBO)//發(fā)送錯(cuò)誤計(jì)數(shù)大于255,總線關(guān)閉
{
TXB0CONbits.TXABT=1;//中止發(fā)送
TXB0CONbits.TXREQ=0;
TXERRCNT= 0x00;//清除發(fā)送錯(cuò)誤計(jì)數(shù)器(可能不起作用)
DebugErrorCode=CAN_SEND3_ERR;
CANCON = 0x00;//進(jìn)入正常工作模式
TestTryTime=20;
while(TestTryTime--) //等待進(jìn)入正常模式
{
ClrWdt();
if((CANSTAT&0xE0)==0x00) break;
}
}
PIR3bits.ERRIF=0;
}
//---------MCP2510 Can中斷程序-------------------
if(INTCONbits.INT0F) //外部中斷,用于接收mcp2510
{
INTCONbits.INT0F=0;//清除中斷
//MCP2510Rec();
StateTemp.Bits.INT0_BIT=1;
}
//INTCONbits.GIE=1;//開(kāi)總中斷
}
//--------------SPI程序-------------------------
void WriteSPI(unsigned char OutData)
{
SSPBUF = OutData;//啟動(dòng)發(fā)送
do{
ClrWdt();
}while(PIR1bits.SSPIF==0);//等待發(fā)送結(jié)束
PIR1bits.SSPIF=0;//清除標(biāo)志位
}
//從一地址讀一個(gè)字節(jié)
unsigned char ReadSPI(void)
{
unsigned char spidata;
SSPBUF = 0x00; //清除SSPSTAT的BF位
TestTryTime=100;
while(TestTryTime--)
{
if(SSPSTATbits.BF==1)
{
spidata = SSPBUF;//讀出數(shù)據(jù)
PIR1bits.SSPIF=0;
}
}
return(spidata);
}
//--------------MCP2510程序--------------------
//復(fù)位程序,復(fù)位后,自動(dòng)進(jìn)入配置模式
void CAN2510Reset(void)
{
ClrWdt();
CAN2510Enable();
Nop();
MCP2510REST=0;
Delay100TCYx(2);
MCP2510REST=1;
Delay100TCYx(2);
CAN2510Disable();
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -