这是我第一次设计调试的总线程序和硬件,其间犯了些小错误,但还好,最终还是成功了,已应用到实际项目中。在此将所设计的程序与硬件接口与大家共享,希望能为与我同样初作总线的朋友多一份参考,当然还请总线设计方面的大侠多提建议啦。<br /> 我有的是PIC18F4580控制芯片,晶振是12MHz。设计要求是,利用总线接收指令信号,同时发送当前系统状态信息。总线采用接收中断方式,为低优先级中断。<br />一、软件的设计<br />基于PIC18F4580总线的波特率的计算,如波特率为250Kbit/s,则每位的时间是T bit=4us,如果晶振为12MHz,Fosc=12MHz,由于为保证正常工作,Tbit>=8TQ。因此取TQ=0.5us,则TQ=[2×(BRP+1)]/Fosc=0.5us则2×(BRP+1)=0.5×12=6。可求得,BRP=2,即BRP54321 =0 1 ; <br />取T bit=8 TQ。同时要求:Prog_Seg+ Phase_Seg1≥Phase_Seg2;Phase_Seg2≥SJW。因此取<br />SJW1 =0 ,则Sync_Seg=1 TQ;<br />因此SJW1 BRP54321 =BRGCON1=0x02; <br />SEG2PHTS=1,SAM=0, <br />phasic time one=SEG1:21 =01 =3TQ,<br />transmission time=PRSEG:21 =0 =1TQ<br />则1001 0000=BRGCON2=0x90;<br />SEG2:21 =01 ,则Phase_Seg2=3TQ。<br />因此BRGCON3=0x02;<br />注意,T bit可编程的数值是4-25 TQ,但是为了正常工作Tbit>=8TQ。<br />设计的总线初始化函数如下:<br />void CANinitial(void) <br />{ <br /> TRISB=(TRISB|0x08)&0xFB; //定义 CANRX/RB3输入口, CANTX/RB2为输出口CANCON=0x80; //申请进入总线配置模式,并选报接收缓冲器0 <br /> while(CANSTAT&0x80==0){;} //等待进入总线配置模式<br />BRGCON1=0x02; <br /> BRGCON2=0x90;<br /> BRGCON3=0x02;<br /> TXB0CON=0x03; /*set the priority*/ <br /> //the ID is 0x582,101 1000 0010, 1011 0000 010 <br /> TXB0SIDH=0xb0; /*the standard frame id id3-10,the frame ID is 0x582= 101 1000 0010,id10-id3=1011 0000*/<br /> TXB0SIDL=0x40; /*the standard frame id (id0-2:bit5-0)=0100 0000,and define standard frame(bit3=EXIDE=0) or extend frame*/<br /> TXB0DLC=0x08; /*the register defines remote frame request or no,and defines the length of the date*/ <br /> TXB0D0=0x00; <br /> TXB0D1=0x00;<br /> TXB0D2=0x00;<br /> TXB0D3=0x00;<br /> TXB0D4=0x00;<br /> TXB0D5=0x00;<br /> TXB0D6=0x00;<br /> TXB0D7=0x00;<br />RXB0CON=0x20; <br />/*receive buffer 0 control register ,0010 1000,define receive standard frame(0010) and remote frame*/<br /> /*and select acceptance filter 0(RXF0)*/<br /> //the fiter id is 0x10a=001 0000 1010<br /> RXF0SIDH=0x21; /*define the filter register 11-3bits 0010 0001 */<br /> RXF0SIDL=0x40; /*define the filter register 2-0bits 010*/<br /> RXM0SIDH=0xff;<br /> RXM0SIDL=0xe0; <br /> RXB0SIDH=0x21; /*the standard frame id id3-10,the frame ID is 0x10A= 001 0000 1010, id10-id3=0010 0001*/<br /> RXB0SIDL=0x40; <br /> RXB0DLC=0x08; /*define the lengh of the received data bytes*/ <br /> RXB0D0=0x00; <br /> RXB0D1=0x00;<br /> RXB0D2=0x00;<br /> RXB0D3=0x00;<br /> RXB0D4=0x00;<br /> RXB0D5=0x00;<br /> RXB0D6=0x00;<br /> RXB0D7=0x00;<br /><br /> CIOCON=0x20;<br /> CANCON=0x00; <br /> while(CANSTAT&0xe0!=0){;} <br /> PIR3=0x00; /*external interupt mark register,clear all interupt marks*/<br /> PIE3=0x01; /*external interupt enable register,1000 0001,enable receive interupt,enable receive buffer 0 interupt*/ <br /> IPR3=0x00; //为低优先级<br />}<br />#pragma interrupt can_isr <br />#pragma code low_ISR=0x18<br />void low_ISR()<br />{<br /> _asm<br /> goto can_isr <br /> _endasm<br />}<br />#pragma code<br />int CAN_FLAG;<br />void can_isr(void)<br />//void interrupt HI_ISR(void)<br />{<br /> if(PIR3bits.RXB0IF==1) //jude if the receive buffer 0 has received a new data <br /> {<br /> CAN_FLAG=1;<br /> CANData=RXB0D6;<br /> PIR3bits.RXB0IF=0; //crear the reveive mark <br /> RXB0CONbits.RXFUL=0; <br /> switch (CANData&0xff)<br /> {<br /> case 0x40: <br /> { <br /> _asm<br /> RESET <br /> _endasm<br /> }<br /> break;<br /> case 0x9c: <br /> { <br /> _asm<br /> RESET <br /> _endasm<br /> }<br /> default:<br /> break;<br /> }<br /> }<br />}<br />说明:CANData为全局变量,当有总线接收中断发生时,取CANData=RXB0D6。在主程序中即调用CANFunction()函数,此函数中对CANData 值进行判断,当为一定值时即执行相关子程序,详细程序与此贴无关,略。同时在执行任何程序过程中,当总线中断发生时,如果总线数据为RXB0D6=0x40或0x9c均会使系统复位。<br />二、CAN接口硬件设计<br /> <br />CAN接口电路图<br /> CAN接口硬件电路如上图所示,在此CAN总线接口电路中,应用高速光耦ADUM1201对总线收发器82C250与主控制器PIC18F4580进行隔离。因为当总线速率高于62.5kbps以上均为高速模式,斜率电阻不应大于1.8k,因此本设计选用的斜率电阻R1为1k。应用隔离电源U3为IB0505LS进行隔离供电。82C250 的CANH 和CANL 引脚各自通过一个5Ω 的电阻与CAN 总线相连,电阻可起到一定的限流作用,保护82C250 免受过流的冲击。CANH 和CANL 与地之间并联了两个30P 的小电容,可以起到滤除总线上的高频干扰和一定的防电磁辐射的能力,另外在两根CAN 总线接入端与地之间分别反接了一个保护二极管,当CAN 总线有较高的负电压时,通过二极管的短路可起到一定的过压保护作用。其中82C250T 是CAN 控制器与物理总线之间的接口,它最初是为汽车高速通信(1Mbps)应用而设计的,可以提供对总线的差动发送和接收功能,支持多达110 个节点,并能以1Mbps 的速率工作于恶劣电气环境下。<br /> |
|