?? main.lst
字號(hào):
1: // ========CAN通信程序=======
2: #include <pic.h>
3: #include <pic1687x.h>
4: #include <mcp2510.h> // MCP2510寄存器定義
5: // =========常數(shù)和變量定義=========
6: #define READ 0x03 // 讀MCP2510指令代碼
7: #define WRITE 0x02 // 寫MCP2510指令代碼
8: #define RESET 0xC0 // 復(fù)位MCP2510指令代碼
9: #define RTS 0x80 // MCP2510請(qǐng)求發(fā)送指令代碼
10: #define STA2510 0xA0 // 讀MCP2510狀態(tài)指令代碼
11: #define BITMOD 0x05 // MCP2510位修改指令代碼
12: int a[12]; // SPI發(fā)送或接收數(shù)據(jù)寄存器
13: int b[8]; // 發(fā)送或接收的數(shù)據(jù)
14: int c[8]; // 發(fā)送或接收的數(shù)據(jù)
15: int i; // 臨時(shí)變量
16: int count; // 發(fā)送接收計(jì)數(shù)器
17: int count1=0; // for test
18: int RecID_H=0;
19: int RecID_L=0;
20: int DLC=8;
21: void SPIINT();
22: void TMR1INT();
23: void CCP1INT();
24: void SPIEXCHANGE(int count);
25: void WAIT_SPI();
26: void RESET2510();
27: int RD2510(int adress,int n);
28: void WR2510(int adress,int n);
29: void RTS2510(int RTSn);
30: int GETS2510();
31: void BM2510(int adress,int mask,int data);
32: void SETNORMAL();
33: void TXCOMPLETE(int adress);
34: void TXMSG(int DLC);
35: int RXMSG();
36: void INIT2510();
37: void INIT877();
38: void INITSPI();
39: void ACK();
40: void wait();
41: // ========主程序=======
42: main(void)
43: {
44: int l,detect=0;
45: SSPIE=1;
46: TMR1IE=1;
47: CCP1IE=1;
48: CCP2IE=1;
49: PEIE=1;
50: ei(); // 開中斷
51: INIT877(); // 初始化PIC16F877芯片
52: INITSPI(); // 初始化SPI接口
53: INIT2510(); // 初始化MCP2510芯片
54: flag1=0;
55: flag2=0;
56: CCP1CON=0x05;
57: CCP2CON=0x04;
58: while(1) {
59: RXMSG();
60: TXMSG(8);
61: }
62: }
63: // ========中斷服務(wù)程序=======
64: // SPI中斷服務(wù)子程序
65: void SPIINT()
66: {
67: SSPIF=0;
68: a[i++]=SSPBUF; // 數(shù)據(jù)暫存a[]中
69: count-=1;
70: if(count>0) SSPBUF=a[i];// 未發(fā)送完,繼續(xù)
71: else RE2=1; // 否則,片選信號(hào)置高電平
72: return;
73: }
74: // TMR1中斷服務(wù)子程序
75: void TMR1INT()
76: {
77: TMR1IF=0;
78: T1CON=0;
79: if(!flag1){
80: TMR1H=0xfe; // 512 μs 脈沖寬度
81: TMR1L=0x00;
82: T1CON=0x01;
83: PORTD=0xff; // 輸出所有通道
84: flag1=1;
85: }
86: else {
87: flag1=0;
88: PORTD=0;
89: T1CON=0;
90: }
91: return;
92: }
93: // CCP1中斷服務(wù)子程序
94: void CCP1INT()
95: {
96: CCP1IF=0;
97: T1CON=0x01;
98: return;
99: }
100: // CCP2中斷服務(wù)子程序
101: void CCP2INT()
102: {
103: CCP2IF=0;
104: T1CON=0x01;
105: return;
106: }
107: // 中斷入口,保護(hù)現(xiàn)場(chǎng),判中斷類型
108: void interrupt INTS()
109: {
110: di();
111: if(TMR1IF) TMR1INT(); // 定時(shí)器TMR1中斷
112: else if(CCP1IF) CCP1INT(); // 電壓過零捕捉中斷1
113: else if(CCP2IF) CCP2INT(); // 電壓過零捕捉中斷2
114: else if(SSPIF) SPIINT(); // SPI接口中斷
115: ei();
116: }
117: // ========子程序=======
118: // 啟動(dòng)SPI傳送
119: void SPIEXCHANGE(count)
120: int count;
121: {
122: if(count>0) { // 有數(shù)據(jù)可送?
123: i=0;
124: RE2=0; // 片選位置低電平
125: SSPBUF=a[i]; // 送數(shù)
126: }
127: else
128: ; // 否則,空操作,并返回
129: return;
130: }
131: // 等待SPI傳送完成
132: void WAIT_SPI()
133: {
134: do{
135: ;
136: }while(count>0); // 當(dāng)count!=0時(shí),等待 to add "CLRWDT"
137: return;
138: }
139: // 對(duì)MCP2510芯片進(jìn)行復(fù)位
140: void RESET2510()
141: {
142: a[0]=RESET;
143: count=1;
144: SPIEXCHANGE(count); // 送復(fù)位指令
145: WAIT_SPI();
146: return;
147: }
148: // 讀取從地址"adress"開始的寄存器中的數(shù)據(jù),共n個(gè),存放在數(shù)組b[n]中
149: int RD2510(adress,n)
150: int adress;
151: int n;
152: {
153: int j;
154: a[0]=READ;
155: a[1]=adress;
156: for(j=0;j<n;j++) a[j+2]=0;
157: count=n+2; // 指令、地址和要得到的數(shù)據(jù)量n
158: SPIEXCHANGE(count);
159: WAIT_SPI();
160: for(j=0;j<n;j++) b[j]=a[j+2];// 數(shù)據(jù)存到數(shù)組b[]中
161: return;
162: }
163: // 向從地址"adress"開始的寄存器寫入數(shù)據(jù),共n個(gè),數(shù)據(jù)存放數(shù)組b[n]中
164: void WR2510(adress,n)
165: int adress;
166: int n;
167: {
168: int j;
169: a[0]=WRITE;
170: a[1]=adress;
171: for(j=0;j<n;j++) a[j+2]=b[j];
172: count=n+2; // 指令、地址和要寫入的數(shù)據(jù)量n
173: SPIEXCHANGE(count);
174: WAIT_SPI();
175: return;
176: }
177: // MCP2510芯片請(qǐng)求發(fā)送程序
178: void RTS2510(RTSn)
179: int RTSn;
180: {
181: a[0]=RTS^RTSn;
182: count=1;
183: SPIEXCHANGE(count); // 發(fā)送MCP2510芯片,請(qǐng)求發(fā)送指令
184: WAIT_SPI();
185: return;
186: }
187: // 讀取MCP2510芯片的狀態(tài)
188: int GETS2510()
189: {
190: a[0]=STA2510;
191: a[1]=0;
192: count=2;
193: SPIEXCHANGE(count); // 讀取MCP2510芯片狀態(tài)
194: WAIT_SPI();
195: b[0]=a[1]; // 狀態(tài)存到數(shù)組b[]中
196: return;
197: }
198: // 對(duì)MCP2510芯片進(jìn)行位修改子程序
199: void BM2510(adress,mask,data)
200: int adress;
201: int mask;
202: int data;
203: {
204: a[0]=BITMOD; // 位修改指令
205: a[1]=adress; // 位修改寄存器地址
206: a[2]=mask; // 位修改屏蔽位
207: a[3]=data; // 位修改數(shù)據(jù)
208: count=4;
209: SPIEXCHANGE(count);
210: WAIT_SPI();
211: return;
212: }
213: // 設(shè)置MCP2510芯片為正常操作模式
214: void SETNORMAL()
215: {
216: int k=1;
217: BM2510(CANCTRL,0xe0,0x00); // 設(shè)置為正常操作模式
218: do {
219: RD2510(CANSTAT,1);
220: k=b[0]&0xe0;
221: }while(k); // 確認(rèn)已進(jìn)入正常操作模式
222: return;
223: }
224: // 對(duì)MCP2510進(jìn)行初始化
225: void INIT2510()
226: {
227: RESET2510(); // 使芯片復(fù)位
228: b[0]=0x02;
229: b[1]=0x90;
230: b[2]=0x07;
231: WR2510(CNF3,3); // 波特率為 125 kbps
232: b[0]=0x00;
233: b[1]=0x00;
234: WR2510(RXM0SIDH,2);
235: b[0]=0x00;
236: b[1]=0x00;
237: WR2510(RXF0SIDH,2); // RX0接收,屏蔽位為0,過濾器為0
238: b[0]=0x00;
239: WR2510(CANINTE,1); // CAN中斷不使能
240: SETNORMAL(); // 設(shè)置為正常操作模式
241: return;
242: }
243: // MCP2510芯片發(fā)送完成與否判斷,郵箱號(hào)為adress
244: void TXCOMPLETE(adress)
245: int adress;
246: {
247: int k=1;
248: do {
249: RD2510(adress,1);
250: k=b[0]&0x08;
251: }while(k); // 確認(rèn)是否已發(fā)送完畢 to add CLRWDT
252: return;
253: }
254: // 初始化PIC16F877芯片
255: void INIT877()
256: {
257: PORTA=0;
258: PORTB=0;
259: PORTC=0;
260: PORTD=0;
261: PORTE=0;
262: TRISA=0xff;
263: TRISB=0xfd;
264: TRISC=0xd7; // SCK, SDO:輸出,SDI:輸入
265: TRISD=0;
266: TRISE=0x03; // 片選CS信號(hào)輸出
267: PORTA=0xff;
268: PORTB=0x03; // RST=1
269: PORTC=0;
270: PORTD=0xff;
271: PORTE=0x04;
272: return;
273: }
274: // 初始化SPI接口
275: void INITSPI()
276: {
277: SSPCON=0x11;
278: SSPEN=1; // SSP使能
279: SSPSTAT=0;
280: return;
281: }
282: // 發(fā)送數(shù)據(jù)子程序
283: void TXMSG(int DLC)
284: {
285: for(i=0;i<DLC;i++) b[i]=c[i];
286: WR2510(TXB0D0,DLC);
287: b[0]=DLC;
288: WR2510(TXB0DLC,1);
289: b[0]=0x03;
290: b[1]=RecID_H;
291: b[2]=RecID_L;
292: WR2510(TXB0CTRL,3);
293: RTS2510(0x01); // 請(qǐng)求發(fā)送
294: TXCOMPLETE(TXB0CTRL); //等待發(fā)送完畢
295: return;
296: }
297: // 接收數(shù)據(jù)子程序
298: int RXMSG()
299: {
300: int k;
301: RD2510(CANINTF,1);
302: k=b[0]&0x01;
303: if(k==1) {
304: BM2510(CANINTF,0x01,0x00);
305: RD2510(RXB0SIDH,2);
306: RecID_H=b[0];
307: RecID_L=b[1]&0xe0;
308: RD2510(RXB0DLC,1);
309: DLC=b[0]&0x0f;
310: RD2510(RXB0D0,DLC);
311: for(i=0;i<DLC;i++) c[i]=b[i];
312: return 1;
313: }
314: return 0;
315: }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -