⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.lst

📁 微芯公司PIC16F87X单片机在CAN通信中的应用.
💻 LST
字号:
     1: // ========CAN通信程序======= 

     2: #include        <pic.h>

     3: #include        <pic1687x.h>

     4: #include        <mcp2510.h>                     // MCP2510寄存器定义 

     5: // =========常数和变量定义=========  

     6: #define READ    0x03                            // 读MCP2510指令代码 

     7: #define WRITE   0x02                    // 写MCP2510指令代码 

     8: #define RESET   0xC0                    // 复位MCP2510指令代码 

     9: #define RTS     0x80                            // MCP2510请求发送指令代码 

    10: #define STA2510 0xA0                    // 读MCP2510状态指令代码 

    11: #define BITMOD  0x05                    // MCP2510位修改指令代码 

    12: int     a[12];                                  // SPI发送或接收数据寄存器

    13: int     b[8];                                   // 发送或接收的数据

    14: int     c[8];                                   // 发送或接收的数据

    15: int     i;                                              // 临时变量

    16: int     count;                                  // 发送接收计数器

    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: // ========中断服务程序======= 

    64: // SPI中断服务子程序 

    65: void SPIINT()

    66: {

    67:         SSPIF=0;

    68:         a[i++]=SSPBUF;                  // 数据暂存a[]中 

    69:         count-=1;

    70:         if(count>0)  SSPBUF=a[i];// 未发送完,继续 

    71:         else  RE2=1;                            // 否则,片选信号置高电平 

    72:         return;

    73: }

    74: // TMR1中断服务子程序 

    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中断服务子程序 

    94: void CCP1INT()

    95: {

    96:         CCP1IF=0;

    97:         T1CON=0x01;

    98:         return;

    99: }

   100: // CCP2中断服务子程序 

   101:  void CCP2INT()

   102: {

   103:         CCP2IF=0;

   104:         T1CON=0x01;

   105:         return;

   106: }

   107: // 中断入口,保护现场,判中断类型 

   108: void interrupt INTS()

   109: {

   110:         di();

   111:         if(TMR1IF)  TMR1INT();          // 定时器TMR1中断 

   112:         else if(CCP1IF)  CCP1INT();     // 电压过零捕捉中断1 

   113:         else if(CCP2IF)  CCP2INT();     // 电压过零捕捉中断2 

   114:         else if(SSPIF)  SPIINT();               // SPI接口中断 

   115:         ei();

   116: }

   117: // ========子程序======= 

   118: // 启动SPI传送 

   119:  void SPIEXCHANGE(count)

   120:  int count;

   121: {

   122:         if(count>0) {                           // 有数据可送? 

   123:           i=0;

   124:           RE2=0;                                                // 片选位置低电平 

   125:           SSPBUF=a[i];                          // 送数 

   126:         }

   127:         else

   128:           ;                                                     // 否则,空操作,并返回 

   129:         return;

   130: }

   131: // 等待SPI传送完成 

   132:  void WAIT_SPI()

   133: {

   134:         do{

   135:           ;

   136:         }while(count>0);                                // 当count!=0时,等待 to add "CLRWDT" 

   137:         return;

   138: }

   139: // 对MCP2510芯片进行复位 

   140: void RESET2510()

   141: {

   142:         a[0]=RESET;

   143:         count=1;

   144:         SPIEXCHANGE(count);                     // 送复位指令 

   145:         WAIT_SPI();

   146:         return;

   147: }

   148: // 读取从地址"adress"开始的寄存器中的数据,共n个,存放在数组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;                                      // 指令、地址和要得到的数据量n 

   158:         SPIEXCHANGE(count);

   159:         WAIT_SPI();

   160:         for(j=0;j<n;j++)  b[j]=a[j+2];// 数据存到数组b[]中 

   161:         return;

   162: }

   163: // 向从地址"adress"开始的寄存器写入数据,共n个,数据存放数组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;                                      // 指令、地址和要写入的数据量n 

   173:         SPIEXCHANGE(count);

   174:         WAIT_SPI();

   175:         return;

   176: }

   177: // MCP2510芯片请求发送程序 

   178:  void RTS2510(RTSn)

   179:  int RTSn;

   180: {

   181:         a[0]=RTS^RTSn;

   182:         count=1;

   183:         SPIEXCHANGE(count);                     // 发送MCP2510芯片,请求发送指令 

   184:         WAIT_SPI();

   185:         return;

   186: }

   187: // 读取MCP2510芯片的状态 

   188:  int GETS2510()

   189: {

   190:         a[0]=STA2510;

   191:         a[1]=0;

   192:         count=2;

   193:         SPIEXCHANGE(count);                     // 读取MCP2510芯片状态 

   194:         WAIT_SPI();

   195:         b[0]=a[1];                                      // 状态存到数组b[]中 

   196:         return;

   197: }

   198: // 对MCP2510芯片进行位修改子程序 

   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;                                      // 位修改数据 

   208:         count=4;

   209:         SPIEXCHANGE(count);

   210:         WAIT_SPI();

   211:         return;

   212: }

   213: // 设置MCP2510芯片为正常操作模式 

   214: void  SETNORMAL()

   215: {

   216:         int  k=1;

   217:         BM2510(CANCTRL,0xe0,0x00);      // 设置为正常操作模式 

   218:         do      {

   219:           RD2510(CANSTAT,1);

   220:           k=b[0]&0xe0;

   221:         }while(k);                                      // 确认已进入正常操作模式 

   222:         return;

   223: }

   224: // 对MCP2510进行初始化 

   225: void INIT2510()

   226: {

   227:         RESET2510();                                    // 使芯片复位 

   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();                                    // 设置为正常操作模式 

   241:         return;

   242: }

   243: // MCP2510芯片发送完成与否判断,邮箱号为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);                                      // 确认是否已发送完毕 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信号输出

   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: // 发送数据子程序 

   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);                                  // 请求发送 

   294:         TXCOMPLETE(TXB0CTRL);                           //等待发送完毕 

   295:         return;

   296: }

   297: // 接收数据子程序 

   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: }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -