天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術熱線: 4007-888-234

技術支持

PIC16F87X單片機在CAN通信中的應用軟件清單

更新時間: 2019-03-22

十年單片機開發方案公司深圳英銳恩分享PIC16F87X單片機在CAN通信中的應用軟件清單。

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

#include

#include <pic16f87x.h>

#include    // 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[i];// 未發送完,繼續 

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 {

T1CON=0;

if(!flag1){

TMR1H=0xfe;    // 512 μs 脈沖寬度

TMR1L=0x00;

T1CON=0x01;

PORTD=0xff;    // 輸出所有通道

flag1=1;

}

else {

{

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[i];    // 送數 

}

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;

}

// 向從地址"adress"開始的寄存器寫入數據,共n個,數據存放數組b[n]中 

 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;     // 指令、地址和要寫入的數據量n

SPIEXCHANGE(count);

WAIT_SPI();

return;

}

// MCP2510芯片請求發送程序 

 void RTS2510(RTSn)

 int RTSn;

{

a[0]=RTS^RTSn;

count=1;

SPIEXCHANGE(count);   // 發送MCP2510芯片,請求發送指令 

WAIT_SPI();

return;

}

// 讀取MCP2510芯片的狀態 

int GETS2510()

{

a[0]=STA2510;

a[1]=0;

count=2;

SPIEXCHANGE(count);   // 讀取MCP2510芯片狀態 

WAIT_SPI();

b[0]=a[1];     // 狀態存到數組b[]中 

return;

}

// 對MCP2510芯片進行位修改子程序 

 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;

}

// 設置MCP2510芯片為正常操作模式 

void  SETNORMAL()

{

int  k=1;

BM2510(CANCTRL,0xe0,0x00); // 設置為正常操作模式 

do {

  RD2510(CANSTAT,1);

  k=b[0]&0xe0;

}while(k);     // 確認已進入正常操作模式 

return;

}

// 對MCP2510進行初始化 

void INIT2510()

{

RESET2510();     // 使芯片復位 

b[0]=0x02;

b[1]=0x90;

b[2]=0x07;

WR2510(CNF3,3);    // 波特率為 125 kbps

b[0]=0x00;

b[1]=0x00;

WR2510(RXM0SIDH,2);

b[0]=0x00;

b[1]=0x00;

WR2510(RXF0SIDH,2);   // RX0接收,屏蔽位為0,過濾器為0

b[0]=0x00;

WR2510(CANINTE,1);   // CAN中斷不使能 

SETNORMAL();     // 設置為正常操作模式 

return;

}

// MCP2510芯片發送完成與否判斷,郵箱號為adress 

void TXCOMPLETE(adress)

int adress;

{

int k=1;

do {

  RD2510(adress,1);

  k=b[0]&0x08;

}while(k);     // 確認是否已發送完畢 to add CLRWDT

return;

}

// 初始化PIC16F877芯片 

void INIT877()

{

PORTA=0;

PORTB=0;

PORTC=0;

PORTD=0;

PORTE=0;

TRISA=0xff;

TRISB=0xfd;

TRISC=0xd7;     // SCK, SDO:輸出,SDI:輸入  

TRISD=0;

TRISE=0x03;     // 片選CS信號輸出

PORTA=0xff;

PORTB=0x03;     // RST=1

PORTC=0;

PORTD=0xff;

PORTE=0x04;

return;

}

// 初始化SPI接口 

 void INITSPI()

{

SSPCON=0x11;

SSPEN=1;       // SSP使能 

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;

}

(文源網絡,侵刪)

404
返回首頁 |  返回上一頁
联系我们: 常熟市| 汨罗市| 乐亭县| 威远县| 洪洞县| 庄河市| 庄河市| 莱芜市| 望江县| 班玛县| 逊克县| 固原市| 全州县| 平和县| 昌图县| 来凤县| 兴山县| 湖口县| 正定县| 涞水县| 犍为县| 布尔津县| 津市市| 镇康县| 龙南县| 邯郸县| 福泉市| 舟山市| 海原县| 翁牛特旗| 临夏市| 康马县| 天等县| 荣昌县| 鹤岗市| 香河县| 鄂托克旗| 泸水县| 太和县| 建宁县| 丽江市|