MSP430与mcp2515的can通讯程序2(续前贴)

2019-07-20 16:14发布

续前贴

用msp430afe253制作了电路板,程序已经在电路板上运行正常

/////////////////////////////////////////////////////////////////////

void RecvDataProc()  //处理从can来的数据或者命令

{

  if(RecvBuff[1]<0x40)

  {

    switch(RecvBuff[1])

    {

      case 0x01:   //读地址 ,单机命令

          SendBuff[0]=0x00;

          SendBuff[1]=0x01;

          SendBuff[2]=Address;

          SendBuff[3]=0X21;

          SendIndex=4;

          datapro_write_flag=1;

          break;

      case 0x02:   //读压力

          SendBuff[0]=Address;

          SendBuff[1]=0x02;

          SendBuff[2]= Ch0Adc /256;

          SendBuff[3]= Ch0Adc %256;

          SendBuff[4]= 0X21;

          SendIndex=5;

          datapro_write_flag=1;

          break;        

      default  :

        datapro_write_flag=0;

        break;

    }//end switch

  }//end

}

/************************************************************************************

** 函数名称: Pro_CAN_ERROR()

** 功能描述: CAN总线错误处理

** 输  入  : 数据类型       形参名      功能

** 输  出  : 数据类型       形参名      功能

** 全局变量: 无

** 调用模块: 无

*************************************************************************************/

void Pro_CAN_ERROR( void )

{

         unsigned char num;

         num=mcp2515_read_register( E** );            // 读错误标志寄存器,判断错误类型

         if( num & EWARN )                              // 错误警告寄存器,当TEC或REC大于或等于96时置1

         {

                   mcp2515_write_register( TEC, 0 );

                   mcp2515_write_register( REC, 0 );

         }

         if( num & RXWAR )                               // 当REC大于或等于96时置1

         { ;      }

         if( num & TXWAR )                               // 当TEC大于或等于96时置1

         { ;      }

         if( num & RXEP )                                   // 当REC大于或等于128时置1

         { ;      }

         if( num & TXEP )                                   // 当TEC大于或等于128时置1

         { ;      }

         if( num & TXBO )                    // 当TEC大于或等于255时置1

         { delay_s(10);   }               //延时10s,等待单片机看门狗复位

         if( num & RX0OVR )                    // 接收缓冲区0溢出

         {

           mcp2515_write_register( E**, num & ~RX0OVR );             // 清中断标志;      // 根据实际情况处理,一种处理办法是发送远程桢,请求数据重新发送

         }

         if( num & RX1OVR )                    // 接收缓冲区1溢出

         {

            mcp2515_write_register( E**, num & ~RX1OVR );             // 清中断标志;

         }

}

/************************************************************************************

** 函数名称: CAN_ISR()

** 功能描述: CAN中断处理函数

*************************************************************************************/

void CAN_ISR(void)

{

  uchar num1,num2,num3,num,i;

  num1 = mcp2515_read_register(CANINTF);

                        // 读中断标志寄存器,根据中断类型,分别处理

   //---------------------------  报文错误中断

   if( num1 & MERRF )                                 

   {

      mcp2515_write_register( CANINTF, num1 & ~MERRF );             // 清中断标志

   }

   //---------------------------  唤醒中断

   if( num1 & WAKIF )

   {

      mcp2515_write_register( CANINTF, num1 & ~WAKIF );             // 清中断标志

      mcp2515_write_register( CANCTRL, CAN_NORMAL_MODE );           // 唤醒后,在仅监听模式,须设置进入正常工作模式

          //---------------------------  判断是否进入正常工作模式

      do

      {

          num = mcp2515_read_register( CANSTAT )& CAN_NORMAL_MODE;

      }

      while( num != CAN_NORMAL_MODE );

   }

   //---------------------------  Error interrupt!

   if(num1 & ERRIF)                                    // 错误中断

   {

      mcp2515_write_register(CANINTF, num1 & ~ERRIF);               // 清中断标志

      Pro_CAN_ERROR( );                                // 分别处理各个错误

   }

   //---------------------------  TX2 success!

   if( num1 & TX2IF )                                  // 发送2成功中断

   {

      mcp2515_write_register( CANINTF, num1 & ~TX2IF );             // 清中断标志

   }

   //---------------------------  TX1 success!

   if( num1 & TX1IF )                                  // 发送1成功中断

   {

      mcp2515_write_register( CANINTF, num1 & ~TX1IF );             // 清中断标志

   }

   //---------------------------  TX0 success!

   if(num1 & TX0IF)                                    // 发送0成功中断

   {

      mcp2515_write_register(CANINTF, num1 & ~TX0IF);               // 清中断标志

   }

   //---------------------------  RX1 interrupt!

   if( num1 & RX1IF )                                  // 接收1成功中断

   {

      mcp2515_write_register( CANINTF, num1 & ~RX1IF );             // 清中断标志

   }

  if(num1 & RX0IF)

  {

    mcp2515_write_register(CANINTF, num1 & ~RX0IF);  // 清中断标志

    num2 = mcp2515_read_register( RXB0SIDL );

    num3 = mcp2515_read_register( RXB0DLC );

    num = num3 & 0x0f;                               // 求数据长度

    if( num2 & IDE )                                 // 收到扩展帧

      {

         //---------------------------  Buffer 0 received extended remote frame!

         if( num3 & RTR )                              // 远程桢,则读取标识符,按照此标识符发送要求的数据

           { ; }

         else                                          // 数据桢,接收处理数据

            {  //---------------------------  Buffer 0 received extended data frame,data length is num

               for( i = 0; i < num; i++ )

               {

                  RecvBuff[ i ] = mcp2515_read_register( RXB0D0 + i );

               }

            }

        }

    RecvDataProc();        //处理接收到的数据命令,诸如:读地址、读压力、设置地址。。。。

  }



}

/////////////////////////////////////////////////////////



void can_service()

{

if(can_isr_flag==1)            //如果有CAN中断

   {  

    can_isr_flag=0;

    CAN_ISR();                  //can中断处理 :接收数据,以及错误、溢出等中断处理

    if(datapro_write_flag==1)

          {

            datapro_write_flag=0;

            CAN_TX_D_Frame( 0, SendIndex, &SendBuff[0] ); // 通过CAN发送缓冲区0,发送数据长度为SendIndex的扩展帧数据,数据在 SendBuff[]中

          }

   }

}



////////////////////////////////////////////////////////////////////////

void main(void)

{



/******************************************************************/

  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  Init_Clk();



  CAN_RST_1;        //mcp2515退出复位

  set_p12_to_int();

   init_SD24();

/****************************************************************/

  UCB0_SPI_Init(0X40);          //USCI SPI模式初始化

  UCB0_SPI_WriteByte(0X00);

/*******************************************************************/

  CanBusConfig();               //MCP2515初始化模块

  delay_s(1);

  Init_TimeA();

__enable_interrupt();         //Enable the Global Interrupt



  while(1)

  {      

      if(SYSTime>=10)   //TIME:100ms*10=1 S

        {

          SYSTime=0;

          ConvToPreVal();  

        }

      can_service();   //CAN服务程序,接收数据并按照协议处理数据,然后将处理的结果通过CAN总线上传

   }

}

/******************************************************************

函数名称:

函数功能:CAN接收中断处理函数

入口参数:

返回参数:

函数说明:

******************************************************************/

#pragma vector = PORT1_VECTOR

__interrupt void CanRxISR_Handler(void)

{

if((P1IFG&BIT2) == BIT2) //处理P1IN.2中断

    {

     P1IFG &= ~BIT2; //清除中断标志

     can_isr_flag=1;

    }

}

/////////////////////////////////////////////////////////////

#pragma vector=TIMERA0_VECTOR      

__interrupt void Timer_A (void)

{

  __disable_interrupt();

  times++;  

  if(times>=100)  //IME:1ms*100=100MS           

  {

   SYSTime++;

   SD24CCTL0 |= SD24SC;//AD开始转换

   times=0;

   }

__enable_interrupt();

}



/////////////////////////////////////////////////////////////////

uchar FilterIndex=0;

uint FilterBuf[4]={0};



#pragma vector=SD24_VECTOR            //SD24 interrupt

__interrupt void SDA24(void)

{               

  //滑动平均滤波算法(递推平均滤波法)

  uchar i;

  long  uint sum=0;

  FilterBuf[FilterIndex++]=SD24MEM0;// Save CH0 results (clears IFG)

  if(FilterIndex==4) FilterIndex=0; //先进先出,再求平均值

  for(i=0;i<4;i++)sum+=FilterBuf[i];

  Ch0Adc=(sum/4);

  SD24INCTL0 = SD24INCH_0;

  SD24CCTL0 |= SD24SNGL  + SD24IE+SD24OSR_256;    // Single conv,enable interrupt  采样率为512  数据格式(当增益为1时0-32768表示0~-600mv  65535~32768表示0~600mv

}

技术交流:qq:531706356,13106551527
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。