[CAN-bus/DeviceNet] 共享-我做过的总线调试,请多支持

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

支持

支持,好同志啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

74

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部