C51模拟SPI对MCP2515没成功,总线上波形有时候有,有时候没有,CAN调试器没发现数据,CAN调试肯定耗用<br />#include "reg51.h"<br />#include "MCP2515.H"<br />#include "intrins.h"<br /><br />sbit CS=P1^2; /*单片机P1.2为片选 可以改为你的实际引脚 */<br />sbit SO=P1^3;/*数据输出 */<br />sbit SK=P1^5; /* 时钟 */<br />sbit SI=P1^4; /* 数据输入*/ <br /><br /><br /><br />#define uint unsigned int<br />#define uchar unsigned char<br /><br />uchar can_boud=0x01;//修改8M下500K拨特率//MCP2515在16M晶振情况,<br /> //can_boud=0x00总线波特率为1M,0x01=500K,0x03=250K,0x07=125K;公式:16M/(16*(1+X))<br /><br />uchar TID[2]={0,0}; //存放标准祯的ID号<br />uchar Tdate[10]={0}; //发送标准祯的数据, 2字节ID,8字节数据<br />uchar Rdate[8]={0}; //存放接收数据<br />uchar RESID[4]; //存放接收到的数据帧的ID号,标准帧只用到RESID[0],RESID[1],扩展帧全部用到<br /><br />void Uart_init(void) //串口初始化,11。0592M-------------9600<br />{<br /> TMOD=0X22;<br /> SCON=0X40;<br /> TH1=0XFA;<br /> PCON=0X80;<br /> TR1=1;<br /> REN=1;<br /> }<br />void putchar(uchar dat) //串口输出一字节函数<br />{<br /> SBUF=dat;<br /> while(!TI);<br /> TI=0;<br /> }<br />void delay_ms(uint del) //延时<br />{<br /><br /> unsigned char j,k;<br /><br /> for(k=del;k>0;k--)<br /><br /> for(j=24;j>0;j--);<br />}<br /><br />void Exint0(void) //外部中断初始化<br />{<br /> EA=1;<br /> EX0=1;<br /> IT0=1; //下降沿触发<br />}<br /><br />void WriteSPI(uchar cData) //模拟SPI发送数据<br />{<br />uchar cLoop;<br /><br />for(cLoop=0;cLoop<8;cLoop++)<br />{<br />SK=0;<br /> <br />if((cData&0x80)==0)<br />{<br />SI=0;<br />}<br />else<br />{<br />SI=1;<br />}<br />SK=1;<br />cData<<=1;<br />}<br />}<br />unsigned char Read8(void) //模拟SPI 读1个字节 <br />{<br />bit bData;<br />unsigned char cLoop;<br />unsigned char cData;<br />for(cLoop=0;cLoop<8;cLoop++)<br />{<br />SK=1;<br />SK=0;<br />bData=SO;<br />cData<<=1;<br />if(bData)<br />{<br />cData|=0x01;<br />}<br />}<br />return cData;<br />}<br /><br />uchar Read_state(uchar order) //读命令状态<br />{<br /> uchar clear;<br /> CS=0;<br /> WriteSPI(order);<br /> clear=Read8();<br /> CS=1;<br /> return clear;<br /> }<br /><br />//**从2515指定地址Address读取一个字节数据Data**//<br />uchar Read_Byte(uchar Address)<br />{//uchar clear;<br /> uchar date;<br /> CS=0; //使能SPI器件<br /> <br /> //SPDR=0x03; //送2515读指令为0x03<br /> WriteSPI(0X03);<br /> <br />// SPDR=Address; //送地址<br /> WriteSPI(Address);<br /> <br /> date=Read8();<br /> CS=1; //关SPI器件<br /> return date;<br />}<br /><br />//**向2515指定地址Address写一个字节数据Data**//<br />void Write_Byte(uchar Address,uchar Data)<br />{<br /> CS=0; //使能SPI器件2515<br /> WriteSPI(0X02); <br /> WriteSPI(Address);<br /> WriteSPI(Data);<br /> CS=1; //关SPI器件<br />}<br /><br />void load_Standard_ID_dates(uchar num) //给标准祯装载ID号和数据<br />{<br /> uchar i,j,T0=0x36;<br /> uchar TIDH,TIDL;<br /> i=TID[1]>>3;j=TID[0]<<5;j=j+i;i=TID[1]<<5;<br /> TIDL=i;TIDH=j;//将数组TID中的值转化为TIDH,TIDL以便给TXB0SIDH,TXB0SIDL附值<br /> Write_Byte(CANCTRL,0x80);//CAN工作在配置模式<br /> Write_Byte(CNF1,can_boud);<br /> Write_Byte(TXB0SIDH,TIDH);<br /> Write_Byte(TXB0SIDL,TIDL);<br /> Write_Byte(TXB0DLC,num);// <br /> for(i=2;i<num+2;i++,T0++)Write_Byte(T0,Tdate);<br /> }<br /><br />void CAN_Initialize(void)<br />{<br /> WriteSPI(CAN_RESET);<br /> delay_ms(20);<br /> Write_Byte(CANCTRL,0x80);//CAN工作在配置模式<br /> Write_Byte(CNF1,can_boud);<br /> Write_Byte(CNF2,0x80 | PHSEG1_3TQ | PRSEG_1TQ);//Set CNF2<br /> Write_Byte(CNF3,PHSEG2_3TQ);<br /> //0x80+0x10+0x00,相位缓冲段2由CNF3确定,相位缓冲段1为3TQ,传播段为1TQ<br /> Write_Byte(RXB0CTRL,0xf0);//接收类型选择,接收所有报文<br /> Write_Byte(CANINTF,0x00);//接收完一次必须对中断标志位清0<br /> Write_Byte(CANINTE,0x01);//接收缓冲器0满中断使能<br /> Write_Byte(CANCTRL,0x00);//选定正常工作模式<br />}<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />void int0() interrupt 0 //外部中断处理程序<br />{ <br /> putchar(0x55);<br />}<br /><br /><br />void main(void)<br />{<br /> uchar i;<br /> Uart_init();<br /> Exint0();<br /> CAN_Initialize(); CAN_Initialize(); CAN_Initialize();<br /> TID[0]=0X00;TID[1]=0X01; //ID号<br /> for(i=0;i<8;i++)<br /> {<br /> Tdate=i; //要发送的数据<br /> }<br /> SK=1;<br /> SK=1; SK=1;<br /> CS=1;<br /> while(1)<br /><br /> {<br /> load_Standard_ID_dates(8);<br /> Write_Byte(CANCTRL,0x00);//选定工作模式<br /> WriteSPI(CAN_RTS_TXB0);//发送缓冲器0请求发送<br />delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000); <br /> delay_ms(60000);<br /> delay_ms(60000); <br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000);<br /> delay_ms(60000); <br /> delay_ms(60000);<br /> delay_ms(60000); <br /><br /> for(i=0;i<8;i++)<br /> {<br /> putchar(Tdate);<br /> } <br /> }<br /> <br /> <br /> } |
|