// ========CAN通信程序=======
#include <pic.h>
#include <pic
#include <mcp2510.h> // MCP2510寄存器定义
// =========常数和变量定义=========
#define READ 0x03 // 读MCP2510指令代码
#define WRITE 0x02 // 写MCP2510指令代码
#define RESET 0xC0 // 复位MCP2510指令代码
#define RTS 0x80 // MCP2510请求发送指令代码
#define STA2510 0xA0 // 读MCP2510状态指令代码
#define BITMOD 0x05 // MCP2510位修改指令代码
int a[12]; // SPI发送或接收数据寄存器
int b[8]; // 发送或接收的数据
int c[8]; // 发送或接收的数据
int i; // 临时变量
int count; // 发送接收计数器
int count1=0; // for test
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(); // 初始化PIC
INITSPI(); // 初始化SPI接口
INIT2510(); // 初始化MCP2510芯片
flag1=0;
flag2=0;
CCP1CON=0x05;
CCP2CON=0x04;
while(1) {
RXMSG();
TXMSG(8);
}
}
// ========中断服务程序=======
// SPI中断服务子程序
void SPIINT()
{
SSPIF=0;
a[i++]=SSPBUF; // 数据暂存a[]中
count-=1;
if(count>0) SSPBUF=a;// 未发送完,继续
else RE2=1; // 否则,片选信号置高电平
return;
}
// TMR1中断服务子程序
void TMR1INT()
{
TMR1IF=0;
T1CON=0;
if(!flag1){
TMR1H=0xfe; // 512 μs 脉冲宽度
TMR
T1CON=0x01;
PORTD=0xff; // 输出所有通道
flag1=1;
}
else {
flag1=0;
PORTD=0;
T1CON=0;
}
return;
}
// CCP1中断服务子程序
void CCP1INT()
{
CCP1IF=0;
T1CON=0x01;
return;
}
// CCP2中断服务子程序
void CCP2INT()
{
CCP2IF=0;
T1CON=0x01;
return;
}
// 中断入口,保护现场,判中断类型
void interrupt INTS()
{
di();
if(TMR1IF) TMR1INT(); // 定时器TMR1中断
else if(CCP1IF) CCP1INT(); // 电压过零捕捉中断1
else if(CCP2IF) CCP2INT(); // 电压过零捕捉中断2
else if(SSPIF) SPIINT(); // SPI接口中断
ei();
}
// ========子程序=======
// 启动SPI传送
void SPIEXCHANGE(count)
int count;
{
if(count>0) { // 有数据可送?
i=0;
RE2=0; // 片选位置低电平
SSPBUF=a; // 送数
}
else
; // 否则,空操作,并返回
return;
}
// 等待SPI传送完成
void WAIT_SPI()
{
do{
;
}while(count>0); // 当count!=0时,等待 to add "CLRWDT"
return;
}
// 对MCP2510芯片进行复位
void RESET2510()
{
a[0]=RESET;
count=1;
SPIEXCHANGE(count); // 送复位指令
WAIT_SPI();
return;
}
// 读取从地址"adress"开始的寄存器中的数据,共n个,存放在数组b[n]中
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; // 指令、地址和要得到的数据量n
SPIEXCHANGE(count);
WAIT_SPI();
for(j=0;j<n;j++) b[j]=a[j+2];// 数据存到数组b[]中
return;
}