eclipsekeil 发表于 2014-2-8 20:37:09

stm32控制mcp2515总线总是处于总线关闭状态

我用stm32像单片机一样,控制mcp2515,mcp2515上有spi接口,将stm32的io与mcp2515的sck,cs,si,so,rst,连接,spi读写命令都没问题,但是mcp2515就是发送不出去,检测EFLG,说总线关闭,我才发一帧就总线关闭。。。,然后总线另一端是与can总线分析仪连接。而且我的环回测试没问题可以自发自收。但是我向分析仪发送时就出错了。
附带吗:

void GPIO_CONF()
{
      GPIO_InitTypeDef GPIO_InitStructure;
      RCC_DeInit();
      RCC_HSEConfig(RCC_HSE_ON);
      RCC_HCLKConfig(RCC_SYSCLK_Div1);
      RCC_HCLKConfig(RCC_SYSCLK_Div2);
      RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_8);
      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
      RCC->APB2ENR=0x0;
      RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
      
      GPIOA->CRL=0x01401310;
      RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC , ENABLE);
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
         GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void MCP2515Reset()
{
      PAout(nRST) = 0;
      __nop();
      __nop();
      PAout(nRST) = 1;
      __nop();
      __nop();
      PAout(nCS) = 0;
//      __nop();
      WriteSPIByte(CAN_RESET);
//      __nop();
      PAout(nCS) = 1;
}

void MCP2515ByteWrite(unsigned char addr,unsigned char value)
{
      PAout(nCS) = 0;
      WriteSPIByte( CAN_WRITE);
      WriteSPIByte( addr );
      WriteSPIByte( value );
      PAout(nCS) = 1;
}

unsigned char MCP2515ByteRead(unsigned char addr)
{
      unsigned char tempdata;
      PAout(nCS) = 0;
      WriteSPIByte(CAN_READ);
      WriteSPIByte(addr);
      tempdata = ReadSPIByte();
      PAout(nCS) = 1;
      return tempdata;
}

void MCP2515BitModify( unsigned char addr,unsigned char mask,unsigned char udata)
{
      unsigned char i;
      PAout(nCS) = 0;
      for(i = 10;i > 0;i--) ;
      //__nop();
      WriteSPIByte(CAN_BIT_MODIFY);
      WriteSPIByte(addr);
      WriteSPIByte(mask);
      WriteSPIByte(udata);
      PAout(nCS)= 1;
}

void delay_ms(u16 nms)
{
      u32 temp;
      SysTick->LOAD=9000*nms;
      SysTick->VAL=0x00;
      SysTick->CTRL|=0x01;
      do
      {
                temp=SysTick->CTRL;
      }while(!(temp&(1<<16)));//(temp&0x01)&&(!(temp&(1<<16))));
      SysTick->CTRL=0x00;
      SysTick->VAL=0x00;
}

void WriteSPIByte( unsigned char DataOut )
{
                unsigned char n;
                for(n=0;n<8;n++)
                {

                        PAout(mSCK) = 0;
                        if((DataOut&0x80)==0x80)
                        {
                              PAout(mSI) = 1;
                        }
                        else
                        {
                              PAout(mSI) = 0;
                        }
                        PAout(mSCK) = 1;
                        DataOut<<=1;
                }
}

unsigned char ReadSPIByte( void )
{
                unsigned char DataIn = 0x0;
                unsigned char n;
                for(n=0;n<8;n++)
                {
               
                        PAout(mSCK)=0;
                        //__nop();
                        DataIn<<=1;

                        if(PAin(mSO)==1)
                              DataIn++;
                        
                        PAout(mSCK)=1;
                }
                return DataIn;
}


void MCP2515Init()
{
      unsigned char rs;
      MCP2515Reset();
      delay_ms(1);
//      delay_ms(10);
      MCP2515BitModify(CANCTRL,0x0e0,REQOP_CONFIG);
      while((rs=(MCP2515ByteRead(CANSTAT)&0xe0))!=REQOP_CONFIG)
      {
                MCP2515BitModify(CANCTRL,0xe0,REQOP_CONFIG);
                delay_ms(10);
      }
      
      MCP2515ByteWrite(CNF1,CAN_125kbps);
      MCP2515ByteWrite(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
      MCP2515ByteWrite(CNF3,PHSEG2_3TQ);
      
      MCP2515ByteWrite(RXB0CTRL,0x60);
      MCP2515ByteWrite(RXB0CTRL,0x60);
      
      MCP2515ByteWrite(CANINTF,0x00);
      MCP2515ByteWrite(CANINTE,0x01);
      
      MCP2515BitModify(CANCTRL,0xe0,REQOP_NORMAL);
      
         while( (rs=(MCP2515ByteRead(CANSTAT)&0xe0)) != REQOP_NORMAL )         
      {
                MCP2515BitModify( CANCTRL, 0xe0, REQOP_NORMAL );
                delay_ms( 10 );
      }
//                MCP2515BitModify(CANCTRL,0xe0,REQOP_LOOPBACK);
//                while((rs=(MCP2515ByteRead(CANSTAT)&0xe0))!=REQOP_LOOPBACK)
//                {
//                        MCP2515BitModify(CANCTRL,0xe0,REQOP_LOOPBACK);
//                        delay_ms(10);
//                }
//      
}

int main()
{
      unsigned char ret;                //返回调试信息
      GPIO_CONF();
      MCP2515Init();
      delay_ms(100);
      while(1)
      {
                PCout(13)=1;      //stm32指示灯
                Delay(0x1ffff);
                PCout(13)=0;
                  Delay(0x1ffff);
                  do
                {      
                        WriteSPIByte(CAN_RD_STATUS);//检测个寄存器的状态
                        ret=ReadSPIByte();
                        ret=MCP2515ByteRead(TEC);
                        ret=MCP2515ByteRead(REC);
                        ret=MCP2515ByteRead(EFLG);                              //外循环第一次为0x00,第二次就是0x20了再也出不去do while了
                        ret = MCP2515ByteRead(0x30);
                  } while (ret&0x10);      
                MCP2515ByteWrite( TXB0CTRL, 0x03 );
                ret=MCP2515ByteRead(TXB0CTRL);
      
      MCP2515ByteWrite( TXB0SIDH,CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0SIDH);

      MCP2515ByteWrite( TXB0SIDL,CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0SIDL);
               
      MCP2515ByteWrite( TXB0EID8,CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0EID8);
               
      MCP2515ByteWrite( TXB0EID0,CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0EID0);
      
      MCP2515ByteWrite( TXB0DLC, CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0DLC);
               
      MCP2515ByteWrite( TXB0D0, CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0D0);
      
      MCP2515ByteWrite( TXB0D1, CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0D1);
               
      MCP2515ByteWrite( TXB0D2, CAN_TX_Buf );
                ret=MCP2515ByteRead(TXB0D2);
      
      MCP2515ByteWrite( TXB0D3, CAN_TX_Buf );
      MCP2515ByteWrite( TXB0D4, CAN_TX_Buf );
      MCP2515ByteWrite( TXB0D5, CAN_TX_Buf );
      MCP2515ByteWrite( TXB0D6, CAN_TX_Buf );
      MCP2515ByteWrite( TXB0D7, CAN_TX_Buf );
      PAout(nCS)=0;
      WriteSPIByte(0x81);                //发送tx请求
      PAout(nCS)=1;
      delay_ms(100);
      }               
}

jzkn 发表于 2014-3-10 16:37:03

一般都是时序,还有就是控制引脚的控制顺序。建议把datasheet读烂,多读几遍,自然会有收获。
在控制命令之间多加一定的延时,看看效果。
页: [1]
查看完整版本: stm32控制mcp2515总线总是处于总线关闭状态