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);
}
} 一般都是时序,还有就是控制引脚的控制顺序。建议把datasheet读烂,多读几遍,自然会有收获。
在控制命令之间多加一定的延时,看看效果。
页:
[1]