[资料分享] PIC16F87X在CAN通信中的应用

rain   2006-7-15 17:26 楼主

// ========CAN通信程序=======

#include    <pic.h>

#include    <pic16f87x.h>

#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();              // 初始化PIC16F877芯片

    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 脉冲宽度

        TMR1L=0x00;

        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;

}

回复评论 (1)

Re: PIC16F87X在CAN通信中的应用

// 向从地址"adress"开始的寄存器写入数据,共n个,数据存放数组b[n]中 void WR2510(adress,n) int adress; int n; { int j; a[0]=WRITE; a[1]=adress; for(j=0;j=c; 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=b; return 1; } return 0; }
点赞  2006-7-15 17:27
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复