解析CAN總線與PC機(jī)串口通信適配器設(shè)計(jì)與實(shí)現(xiàn)
來源:龍人計(jì)算機(jī)研究所 作者:站長 時(shí)間:2009-09-17 10:42:44
CAN總線(Controller AreaNetwork,控制器局域網(wǎng)) 已成為比較流行的一種現(xiàn)場總線,廣泛應(yīng)用于控制系統(tǒng)中的各檢測和執(zhí)行機(jī)構(gòu)之間的數(shù)據(jù)通信,因其具有高性能、高可靠性、高性價(jià)比、連接方便、實(shí)時(shí)性好及其獨(dú)特的設(shè)計(jì)等突出優(yōu)點(diǎn)應(yīng)用于許多工業(yè)部門。而實(shí)際應(yīng)用中PC機(jī)與CAN總線的人機(jī)交互設(shè)計(jì)尤為重要,它直接影響系統(tǒng)的運(yùn)行和結(jié)果,其連接方法也成為系統(tǒng)設(shè)計(jì)的重點(diǎn),通常采取3種連接方式:RS-232串行口通信、PCI卡、USB口通信,由于串行通信端口在系統(tǒng)控制領(lǐng)域中一直扮演著極為重要的角色,以其開發(fā)簡單,資源豐富,成本低,無需驅(qū)動(dòng)程序等諸多優(yōu)點(diǎn),不僅沒有被淘汰,反而在規(guī)格上更先進(jìn),故應(yīng)用廣泛。結(jié)合設(shè)計(jì)中AT89C51單片機(jī)有串行通信口且接口簡單的特點(diǎn),選用RS-232作為CAN總線與PC機(jī)之間的連接方式。將就這一基于CAN控制器SJA1000與AT89C51的具有通用性的工業(yè)測控系統(tǒng)設(shè)計(jì)的軟硬件設(shè)計(jì)方案作詳細(xì)介紹。
CAN總線及CAN控制器SJA1000簡介
CAN總線最初是德國Bosch公司在1986 年為解決現(xiàn)代汽車中眾多的控制與測試儀器之間的數(shù)據(jù)交換而開發(fā)的一種支持分布式實(shí)時(shí)控制系統(tǒng)的串行數(shù)據(jù)通訊總線。CAN總線與其它通信網(wǎng)的顯著不同之處在于:
(1)報(bào)文傳送中不包含目標(biāo)地址,它是以全網(wǎng)廣播為基礎(chǔ),各接收站根據(jù)報(bào)文中反映數(shù)據(jù)性質(zhì)的標(biāo)識符過濾報(bào)文,該收的收下,不收的棄用。其好處是可線上網(wǎng)下網(wǎng)、即插即用和多站接收。
(2)特別強(qiáng)化了對數(shù)據(jù)安全性的關(guān)注,滿足控制系統(tǒng)及其它較高數(shù)據(jù)要求的系統(tǒng)需求。另外CAN總線采用短幀結(jié)構(gòu),借助接收濾波的多地址幀傳送,受干擾概率低,每幀信息都有CRC校驗(yàn)及其它檢錯(cuò)措施。響應(yīng)遠(yuǎn)程數(shù)據(jù)請求,配置靈活,具有全系統(tǒng)的數(shù)據(jù)相容性。節(jié)點(diǎn)數(shù)主要取決于總線驅(qū)動(dòng)電路,目前最多可達(dá)110個(gè)節(jié)點(diǎn)。CAN總線符合ISO11898標(biāo)準(zhǔn),通信速率高,最大傳輸速率可達(dá)1Mbit/S,最大傳輸距離為10km,傳輸介質(zhì)可為雙絞線;贑AN總線以上的特點(diǎn),把它應(yīng)用于系統(tǒng)分布比較分散且需要在同一總線上掛接多個(gè)節(jié)點(diǎn)的場合是非常適合的。
目前廣泛流行的CAN總線器件有兩大類:一類是獨(dú)立的CAN控制器,如PhilipS公司的PCA82C200,SJA1000及Intel82256/82257等;另一類是帶有在片CAN的微控制器,如P8XC582等。其中Philips公司的PCA82C200是符合CAN2. 0A協(xié)議的總線控制器,SJA1000是它的替代產(chǎn)品,它是應(yīng)用于汽車和一般工業(yè)環(huán)境的獨(dú)立CAN總線控制器。具有完成CAN通信協(xié)議所要求的全部特性。經(jīng)過簡單總線連接的SJA1000可完成CAN總線的物理層和數(shù)據(jù)鏈路層的所有功能。其硬件與軟件設(shè)計(jì)和PCA82C200的基本CAN模式(BasicCAN)兼容。同時(shí),新增加的增強(qiáng)CAN模式( PeliCAN)還可支持CAN2. 0B協(xié)議。根據(jù)當(dāng)前市場開發(fā)工具和課題的實(shí)際需要,選用SJA1000作為CAN控制器,同時(shí)使用了CAN控制器接口芯片PCA82C250。
SJA1000有兩種工作模式:基本模式和增強(qiáng)模式。在基本模式下,SJA1000只可收發(fā)標(biāo)準(zhǔn)數(shù)據(jù)幀(標(biāo)準(zhǔn)數(shù)據(jù)幀的標(biāo)識符為11位),且錯(cuò)誤報(bào)警的極限值不能修改;在增強(qiáng)模式下,SJA1000既可接收標(biāo)準(zhǔn)數(shù)據(jù)幀,也可接收擴(kuò)展數(shù)據(jù)幀(擴(kuò)展數(shù)據(jù)幀的標(biāo)識符為29位),可修改錯(cuò)誤報(bào)警的極限值,并且SJA1000具有更加靈活的濾波方式,能夠根據(jù)數(shù)據(jù)幀的標(biāo)識符有選擇地接收一些數(shù)據(jù)幀。另外,增強(qiáng)模式下的SJA1000能夠進(jìn)行自檢,即可通過自發(fā)自收一組報(bào)文來判斷該控制節(jié)點(diǎn)是否正常地掛在CAN總線上。使用者所要做的主要工作是SJA1000的初始化,收發(fā)報(bào)文的處理以及對節(jié)點(diǎn)脫離總線的檢測量與處理。
RS-232標(biāo)準(zhǔn)
串行通信由于接線少、成本低,在數(shù)據(jù)采集和控制系統(tǒng)中得到了廣泛的應(yīng)用,1969年,美國電子工業(yè)協(xié)會(huì)( EIA)公布了RS-232C作為串行通信接口的電氣標(biāo)準(zhǔn),該標(biāo)準(zhǔn)定義了數(shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通信設(shè)備(DCE)間按位串行傳輸?shù)慕涌谛畔,合理安排了接口的電氣信號和機(jī)械要求,在世界范圍內(nèi)得到了廣泛的應(yīng)用。
系統(tǒng)總體結(jié)構(gòu)原理及設(shè)計(jì)
該適配器利用RS-232串行通信口及CAN總線進(jìn)行數(shù)據(jù)通信,實(shí)現(xiàn)上位機(jī)與各智能節(jié)點(diǎn)間的通信任務(wù),包括控制臺(上位機(jī))向下傳輸命令和下位機(jī)數(shù)據(jù)的返回,以完成對下層設(shè)備的監(jiān)控。圖1為系統(tǒng)結(jié)構(gòu)框圖。PC機(jī)通過RS-232與CAN控制器SJA1000通信,實(shí)現(xiàn)信息在CAN總線上的發(fā)送與接收。底層各智能節(jié)點(diǎn)根據(jù)應(yīng)用的不同具有不同功能,但都具有與CAN總線通信能力可以上傳數(shù)據(jù)和接收數(shù)據(jù)。
CAN總線接口硬件設(shè)計(jì)
圖2為CAN總線通信接口適配器硬件設(shè)計(jì)簡圖。
PCA82C250提供對總線的差動(dòng)發(fā)送和對CAN控制器的差動(dòng)接收功能,也增大了通信距離,提高了系統(tǒng)的瞬間抗干擾能力,保護(hù)總線,降低射頻干擾(RFI),實(shí)現(xiàn)了熱防護(hù)等功能。
系統(tǒng)軟件設(shè)計(jì)
軟件設(shè)計(jì)分PC機(jī)Visual BasiC編程和AT89C51單片機(jī)C語言編程2部分。
PC機(jī)部分
采用VB6. 0編程,這樣界面非常直觀,人機(jī)交互效果好。VB提供了具有通訊功能的MSComm. OCX控件,該控件可設(shè)置串行通信的數(shù)據(jù)發(fā)送和接收,對串口狀態(tài)及串口通信的信息格式和協(xié)議進(jìn)行設(shè)置。MSComm控件提供2種處理通訊的方式:(1)事件驅(qū)動(dòng)通訊,即發(fā)送或接收數(shù)據(jù)過程中觸發(fā)ONCOMM事件,通過編程訪問CommEvent屬性了解通信事件的類型,分別進(jìn)行各自的處理;(2)查詢方式,通過檢查CommEvent屬性的值來查詢事件和錯(cuò)誤。采取查詢方式。控件MSComm是將RS-232的初級操作予以封裝,用戶以高級的BasiC語法即可利用RS-232與外界通信并不需要了解其他有關(guān)的初級操作,因此使用方便。
MSComm控件初始化:
MSComm1. CommPort= 2 設(shè)置串口2
MSComm1. SettingS=“9600,N,8,1” 設(shè)定工作方式
MSComm1. InBufferSize = 10 根據(jù)1次傳1個(gè)CAN幀,設(shè)置輸入緩沖區(qū)大小
MSComm1. InputMode = 1 二進(jìn)制形式接收
MSComm1. InputLeN= 0 一次讀出輸入緩沖區(qū)中的所有數(shù)據(jù)
MSComm1. OutBufferSize = 10 輸出緩沖區(qū)大小的設(shè)置
MSComm1. OutBufferCount= 0 清空輸出緩沖區(qū)
MSComm1. PortOpeN= True 打開串口
PC機(jī)與單片機(jī)MSC51之間的通信約定如下:一般情況下PC與多個(gè)MSC51單片機(jī)系統(tǒng)進(jìn)行主從式通信,其方案是MSC51采用串口工作方式3,即11位異步接收/發(fā)送方式,有效數(shù)據(jù)為9位,其中第9位為地址/數(shù)據(jù)信息的標(biāo)志位,以此區(qū)分各從機(jī)。但現(xiàn)在PC機(jī)采用VB編程,其MSComm控件為標(biāo)準(zhǔn)的10位串口通信,包括8位標(biāo)準(zhǔn)數(shù)據(jù)和數(shù)據(jù)的起始位和停止位。將單片機(jī)串口設(shè)為工作方式1,即改為10位異步接收/發(fā)送方式,通訊流程如下:
通訊時(shí)首先發(fā)通信開始標(biāo)志,接著發(fā)送各下位機(jī)單片機(jī)的地址信號和芯片的片選信號,然后發(fā)送單片機(jī)的工作命令字。再往下即進(jìn)行數(shù)據(jù)處理,轉(zhuǎn)入相應(yīng)的處理功能模塊,最后對數(shù)據(jù)進(jìn)行效驗(yàn)。這個(gè)通訊流程非常簡便,實(shí)現(xiàn)了PC機(jī)與單片機(jī)之間的主從式通訊。
以下為VB的發(fā)送接收程序:
Private SuBcmdSendàClick() 使用按鈕控件
MSComm1. Output= txtSend. Text 將傳送區(qū)內(nèi)的字符串以O(shè)utput屬性送出
End Sub
Private SuBFormàLoad() 窗體的加載事件
MSComm1. PortOpeN= True 將通訊斷口開啟,通訊參數(shù)也可以在開啟前先設(shè)定
MSComm1. RThreshold = Val (txtThreshold. Text) 設(shè)定引發(fā)接收事件的接收閾值,使程序一執(zhí)行便開啟通訊端口,將接收的閾值設(shè)定為閾值,設(shè)定文本框內(nèi)的值。
End Sub
Private SuBMSComm1. OnComm() 通訊控件的OnComm事件。引發(fā)接收事件后,將字符收進(jìn)來并放在接收的文本框中
SelectCase MSComm1. CommEvent 根據(jù)下面每一個(gè)case 語句處理每個(gè)事件和錯(cuò)誤事件
Case comEvCD CD 線的狀態(tài)發(fā)生變化
Case commEvReceive 收到Rthreshold # of
txtReceive. Text= txtReceive. Text+ Trim(MSComm1. Input)&vbCrLf
Case comEvSend 傳輸緩沖區(qū)有Sthreshold 個(gè)字符
End Select
End Sub
Private SuBtxtThreshold Change ( ) p閾值設(shè)定文本框的Change事件
MSComm1. Rthreshold = Val (txtThreshold. Text) p當(dāng)設(shè)定的閾值變化時(shí),實(shí)時(shí)改變通訊對象的屬性
End Sub
AT89C51單片機(jī)部分
單片機(jī)部分采用C語言編程。C語言編程具有快捷、模塊功能強(qiáng)大、可靠性好、效率高等優(yōu)點(diǎn)。其中程序初始化包括設(shè)定串口工作方式,定時(shí)器、中斷寄存器初始化,各變量的初始化。
TMOD = 0x20; //定時(shí)器1為發(fā)生器
SCON= 0x50; //串口工作方式1
TH1= 0xfd ; //設(shè)定波特率= 9600bit/s
TL1= 0xfd ;
EA= 1; //開中斷
ES= 1; //允許串口中斷
TR1= 1; //啟動(dòng)定時(shí)器T1
SPECHAR = 0xff ; //設(shè)定通訊開始標(biāo)志
程序采用中斷接收,查詢發(fā)送的方式。串口中斷服務(wù)程序流程圖如圖3所示。
SJA1000控制器部分
初始化子程序CANINIT()
選用CAN2. 0協(xié)議構(gòu)建CAN總線控制網(wǎng)絡(luò),對SJA1000的初始化主要包括工作方式的設(shè)置、驗(yàn)收代碼寄存器ACR、驗(yàn)收屏蔽寄存器AMR、波特率的參數(shù)設(shè)置等。
void canàinit(void) /*SJA1000的初始化子函數(shù)*/
{control = 1; /*禁止超載、出錯(cuò)及接收中斷,并置復(fù)位請求位使其進(jìn)入復(fù)位狀態(tài)*/
while (control&0x01== 0);
acceptanceàcode = 0x01; /*驗(yàn)收碼寄存器(存機(jī)號1號)*/
acceptanceàmask= 0xfe ; /*驗(yàn)收屏蔽碼寄存器*/
busàtimingà0= 0x03; /*總線定時(shí)寄存器0,同步跳轉(zhuǎn)寬度
T0= T,BPS= 125 k*/
busàtimingà1= 0x18; /*總線定時(shí)寄存器1,T1= 9T,T2=2T,波特率為500kbit/S*/
outputàcontrol = 0x1A; /*正常輸出方式,TX1引腳懸浮*/
clockàdivider = 0x40; /*BASICCAN模式,RX1接固定電平*/
control = 0x1A; /*清復(fù)位請求,使其進(jìn)入工作狀態(tài)*/
}
發(fā)送canàsend()
發(fā)送子程序負(fù)責(zé)節(jié)點(diǎn)報(bào)文的發(fā)送,由CAN控制器SJA1000獨(dú)立完成,將命令寄存器里的發(fā)送請求標(biāo)志置位,即可發(fā)送SJA1000發(fā)送緩沖區(qū)中的報(bào)文。
void canàsend(unsigned char ID ,char*xdata) /*該子函數(shù)完成一幀數(shù)據(jù)的發(fā)送*/
{while ( (status&0x10)>> 4 == 1)àNOPà; /*檢查上次請求發(fā)送是否完成*/
while ( (status&0x04)>> 2== 0)àNOPà;
Transmitbuffer1= ID;
Transmitbuffer2= 0x08;
Transmitbuffer3= txdata[0] ;
Transmitbuffer10= txdata[7] ;
Command = 0x05 ; /*發(fā)送請求*/
while ( (status&0x08)>> 3== 0);
}
接收子程序canàreceive ()
接收子程序負(fù)責(zé)節(jié)點(diǎn)報(bào)文的接收。SJA1000自動(dòng)接收發(fā)往該節(jié)點(diǎn)的數(shù)據(jù)并將收到的數(shù)據(jù)放到它的接收緩沖器中。
SJA1000的報(bào)文接收主要有2種方式:中斷接收方式和查詢接收方式。系統(tǒng)采用的是中斷接收方式。
{unsigned char ir ;
ir = interrupt; /*獲得SJA1000的中斷狀態(tài)*/
EA= 0;
If ( (ir&0x04)>> 2== 1)error ( ); /*如果是出錯(cuò)中斷,則調(diào)出錯(cuò)處理函數(shù)*/
If ( (ir&0x08)>> 3== 1)overruN( ); /*如果是超載中斷,則調(diào)超載處理函數(shù)*/
While ( ( (ir&0x04)>> 2== 1)‖( ( (ir&0x08)>> 3)== 1){àNOPà;}
RxID[0] = Receivebuffer1;
RxID[0] = Receivebuffer2;
If ( ( (Receivebuffer2&0x10)>> 4)== 0) /*如果是數(shù)據(jù)幀,則接收數(shù)據(jù)*/
{Rxdata[0] = Receivebuffer3;
.
Rxdata[7] = Receivebuffer10;
Command = 0x04 ; /*SJA1000的接收緩存器被釋放*/
}
else if ( ( (Receivebuffer2&0x10)>> 4)== 1) /*如果是遠(yuǎn)程幀,則作相應(yīng)處理*/
{ /*相應(yīng)處理程序*/
EA= 1;
}
}
CAN總線及CAN控制器SJA1000簡介
CAN總線最初是德國Bosch公司在1986 年為解決現(xiàn)代汽車中眾多的控制與測試儀器之間的數(shù)據(jù)交換而開發(fā)的一種支持分布式實(shí)時(shí)控制系統(tǒng)的串行數(shù)據(jù)通訊總線。CAN總線與其它通信網(wǎng)的顯著不同之處在于:
(1)報(bào)文傳送中不包含目標(biāo)地址,它是以全網(wǎng)廣播為基礎(chǔ),各接收站根據(jù)報(bào)文中反映數(shù)據(jù)性質(zhì)的標(biāo)識符過濾報(bào)文,該收的收下,不收的棄用。其好處是可線上網(wǎng)下網(wǎng)、即插即用和多站接收。
(2)特別強(qiáng)化了對數(shù)據(jù)安全性的關(guān)注,滿足控制系統(tǒng)及其它較高數(shù)據(jù)要求的系統(tǒng)需求。另外CAN總線采用短幀結(jié)構(gòu),借助接收濾波的多地址幀傳送,受干擾概率低,每幀信息都有CRC校驗(yàn)及其它檢錯(cuò)措施。響應(yīng)遠(yuǎn)程數(shù)據(jù)請求,配置靈活,具有全系統(tǒng)的數(shù)據(jù)相容性。節(jié)點(diǎn)數(shù)主要取決于總線驅(qū)動(dòng)電路,目前最多可達(dá)110個(gè)節(jié)點(diǎn)。CAN總線符合ISO11898標(biāo)準(zhǔn),通信速率高,最大傳輸速率可達(dá)1Mbit/S,最大傳輸距離為10km,傳輸介質(zhì)可為雙絞線;贑AN總線以上的特點(diǎn),把它應(yīng)用于系統(tǒng)分布比較分散且需要在同一總線上掛接多個(gè)節(jié)點(diǎn)的場合是非常適合的。
目前廣泛流行的CAN總線器件有兩大類:一類是獨(dú)立的CAN控制器,如PhilipS公司的PCA82C200,SJA1000及Intel82256/82257等;另一類是帶有在片CAN的微控制器,如P8XC582等。其中Philips公司的PCA82C200是符合CAN2. 0A協(xié)議的總線控制器,SJA1000是它的替代產(chǎn)品,它是應(yīng)用于汽車和一般工業(yè)環(huán)境的獨(dú)立CAN總線控制器。具有完成CAN通信協(xié)議所要求的全部特性。經(jīng)過簡單總線連接的SJA1000可完成CAN總線的物理層和數(shù)據(jù)鏈路層的所有功能。其硬件與軟件設(shè)計(jì)和PCA82C200的基本CAN模式(BasicCAN)兼容。同時(shí),新增加的增強(qiáng)CAN模式( PeliCAN)還可支持CAN2. 0B協(xié)議。根據(jù)當(dāng)前市場開發(fā)工具和課題的實(shí)際需要,選用SJA1000作為CAN控制器,同時(shí)使用了CAN控制器接口芯片PCA82C250。
SJA1000有兩種工作模式:基本模式和增強(qiáng)模式。在基本模式下,SJA1000只可收發(fā)標(biāo)準(zhǔn)數(shù)據(jù)幀(標(biāo)準(zhǔn)數(shù)據(jù)幀的標(biāo)識符為11位),且錯(cuò)誤報(bào)警的極限值不能修改;在增強(qiáng)模式下,SJA1000既可接收標(biāo)準(zhǔn)數(shù)據(jù)幀,也可接收擴(kuò)展數(shù)據(jù)幀(擴(kuò)展數(shù)據(jù)幀的標(biāo)識符為29位),可修改錯(cuò)誤報(bào)警的極限值,并且SJA1000具有更加靈活的濾波方式,能夠根據(jù)數(shù)據(jù)幀的標(biāo)識符有選擇地接收一些數(shù)據(jù)幀。另外,增強(qiáng)模式下的SJA1000能夠進(jìn)行自檢,即可通過自發(fā)自收一組報(bào)文來判斷該控制節(jié)點(diǎn)是否正常地掛在CAN總線上。使用者所要做的主要工作是SJA1000的初始化,收發(fā)報(bào)文的處理以及對節(jié)點(diǎn)脫離總線的檢測量與處理。
RS-232標(biāo)準(zhǔn)
串行通信由于接線少、成本低,在數(shù)據(jù)采集和控制系統(tǒng)中得到了廣泛的應(yīng)用,1969年,美國電子工業(yè)協(xié)會(huì)( EIA)公布了RS-232C作為串行通信接口的電氣標(biāo)準(zhǔn),該標(biāo)準(zhǔn)定義了數(shù)據(jù)終端設(shè)備(DTE)和數(shù)據(jù)通信設(shè)備(DCE)間按位串行傳輸?shù)慕涌谛畔,合理安排了接口的電氣信號和機(jī)械要求,在世界范圍內(nèi)得到了廣泛的應(yīng)用。
系統(tǒng)總體結(jié)構(gòu)原理及設(shè)計(jì)
該適配器利用RS-232串行通信口及CAN總線進(jìn)行數(shù)據(jù)通信,實(shí)現(xiàn)上位機(jī)與各智能節(jié)點(diǎn)間的通信任務(wù),包括控制臺(上位機(jī))向下傳輸命令和下位機(jī)數(shù)據(jù)的返回,以完成對下層設(shè)備的監(jiān)控。圖1為系統(tǒng)結(jié)構(gòu)框圖。PC機(jī)通過RS-232與CAN控制器SJA1000通信,實(shí)現(xiàn)信息在CAN總線上的發(fā)送與接收。底層各智能節(jié)點(diǎn)根據(jù)應(yīng)用的不同具有不同功能,但都具有與CAN總線通信能力可以上傳數(shù)據(jù)和接收數(shù)據(jù)。
CAN總線接口硬件設(shè)計(jì)
圖2為CAN總線通信接口適配器硬件設(shè)計(jì)簡圖。
PCA82C250提供對總線的差動(dòng)發(fā)送和對CAN控制器的差動(dòng)接收功能,也增大了通信距離,提高了系統(tǒng)的瞬間抗干擾能力,保護(hù)總線,降低射頻干擾(RFI),實(shí)現(xiàn)了熱防護(hù)等功能。
系統(tǒng)軟件設(shè)計(jì)
軟件設(shè)計(jì)分PC機(jī)Visual BasiC編程和AT89C51單片機(jī)C語言編程2部分。
PC機(jī)部分
采用VB6. 0編程,這樣界面非常直觀,人機(jī)交互效果好。VB提供了具有通訊功能的MSComm. OCX控件,該控件可設(shè)置串行通信的數(shù)據(jù)發(fā)送和接收,對串口狀態(tài)及串口通信的信息格式和協(xié)議進(jìn)行設(shè)置。MSComm控件提供2種處理通訊的方式:(1)事件驅(qū)動(dòng)通訊,即發(fā)送或接收數(shù)據(jù)過程中觸發(fā)ONCOMM事件,通過編程訪問CommEvent屬性了解通信事件的類型,分別進(jìn)行各自的處理;(2)查詢方式,通過檢查CommEvent屬性的值來查詢事件和錯(cuò)誤。采取查詢方式。控件MSComm是將RS-232的初級操作予以封裝,用戶以高級的BasiC語法即可利用RS-232與外界通信并不需要了解其他有關(guān)的初級操作,因此使用方便。
MSComm控件初始化:
MSComm1. CommPort= 2 設(shè)置串口2
MSComm1. SettingS=“9600,N,8,1” 設(shè)定工作方式
MSComm1. InBufferSize = 10 根據(jù)1次傳1個(gè)CAN幀,設(shè)置輸入緩沖區(qū)大小
MSComm1. InputMode = 1 二進(jìn)制形式接收
MSComm1. InputLeN= 0 一次讀出輸入緩沖區(qū)中的所有數(shù)據(jù)
MSComm1. OutBufferSize = 10 輸出緩沖區(qū)大小的設(shè)置
MSComm1. OutBufferCount= 0 清空輸出緩沖區(qū)
MSComm1. PortOpeN= True 打開串口
PC機(jī)與單片機(jī)MSC51之間的通信約定如下:一般情況下PC與多個(gè)MSC51單片機(jī)系統(tǒng)進(jìn)行主從式通信,其方案是MSC51采用串口工作方式3,即11位異步接收/發(fā)送方式,有效數(shù)據(jù)為9位,其中第9位為地址/數(shù)據(jù)信息的標(biāo)志位,以此區(qū)分各從機(jī)。但現(xiàn)在PC機(jī)采用VB編程,其MSComm控件為標(biāo)準(zhǔn)的10位串口通信,包括8位標(biāo)準(zhǔn)數(shù)據(jù)和數(shù)據(jù)的起始位和停止位。將單片機(jī)串口設(shè)為工作方式1,即改為10位異步接收/發(fā)送方式,通訊流程如下:
通訊時(shí)首先發(fā)通信開始標(biāo)志,接著發(fā)送各下位機(jī)單片機(jī)的地址信號和芯片的片選信號,然后發(fā)送單片機(jī)的工作命令字。再往下即進(jìn)行數(shù)據(jù)處理,轉(zhuǎn)入相應(yīng)的處理功能模塊,最后對數(shù)據(jù)進(jìn)行效驗(yàn)。這個(gè)通訊流程非常簡便,實(shí)現(xiàn)了PC機(jī)與單片機(jī)之間的主從式通訊。
以下為VB的發(fā)送接收程序:
Private SuBcmdSendàClick() 使用按鈕控件
MSComm1. Output= txtSend. Text 將傳送區(qū)內(nèi)的字符串以O(shè)utput屬性送出
End Sub
Private SuBFormàLoad() 窗體的加載事件
MSComm1. PortOpeN= True 將通訊斷口開啟,通訊參數(shù)也可以在開啟前先設(shè)定
MSComm1. RThreshold = Val (txtThreshold. Text) 設(shè)定引發(fā)接收事件的接收閾值,使程序一執(zhí)行便開啟通訊端口,將接收的閾值設(shè)定為閾值,設(shè)定文本框內(nèi)的值。
End Sub
Private SuBMSComm1. OnComm() 通訊控件的OnComm事件。引發(fā)接收事件后,將字符收進(jìn)來并放在接收的文本框中
SelectCase MSComm1. CommEvent 根據(jù)下面每一個(gè)case 語句處理每個(gè)事件和錯(cuò)誤事件
Case comEvCD CD 線的狀態(tài)發(fā)生變化
Case commEvReceive 收到Rthreshold # of
txtReceive. Text= txtReceive. Text+ Trim(MSComm1. Input)&vbCrLf
Case comEvSend 傳輸緩沖區(qū)有Sthreshold 個(gè)字符
End Select
End Sub
Private SuBtxtThreshold Change ( ) p閾值設(shè)定文本框的Change事件
MSComm1. Rthreshold = Val (txtThreshold. Text) p當(dāng)設(shè)定的閾值變化時(shí),實(shí)時(shí)改變通訊對象的屬性
End Sub
AT89C51單片機(jī)部分
單片機(jī)部分采用C語言編程。C語言編程具有快捷、模塊功能強(qiáng)大、可靠性好、效率高等優(yōu)點(diǎn)。其中程序初始化包括設(shè)定串口工作方式,定時(shí)器、中斷寄存器初始化,各變量的初始化。
TMOD = 0x20; //定時(shí)器1為發(fā)生器
SCON= 0x50; //串口工作方式1
TH1= 0xfd ; //設(shè)定波特率= 9600bit/s
TL1= 0xfd ;
EA= 1; //開中斷
ES= 1; //允許串口中斷
TR1= 1; //啟動(dòng)定時(shí)器T1
SPECHAR = 0xff ; //設(shè)定通訊開始標(biāo)志
程序采用中斷接收,查詢發(fā)送的方式。串口中斷服務(wù)程序流程圖如圖3所示。
SJA1000控制器部分
初始化子程序CANINIT()
選用CAN2. 0協(xié)議構(gòu)建CAN總線控制網(wǎng)絡(luò),對SJA1000的初始化主要包括工作方式的設(shè)置、驗(yàn)收代碼寄存器ACR、驗(yàn)收屏蔽寄存器AMR、波特率的參數(shù)設(shè)置等。
void canàinit(void) /*SJA1000的初始化子函數(shù)*/
{control = 1; /*禁止超載、出錯(cuò)及接收中斷,并置復(fù)位請求位使其進(jìn)入復(fù)位狀態(tài)*/
while (control&0x01== 0);
acceptanceàcode = 0x01; /*驗(yàn)收碼寄存器(存機(jī)號1號)*/
acceptanceàmask= 0xfe ; /*驗(yàn)收屏蔽碼寄存器*/
busàtimingà0= 0x03; /*總線定時(shí)寄存器0,同步跳轉(zhuǎn)寬度
T0= T,BPS= 125 k*/
busàtimingà1= 0x18; /*總線定時(shí)寄存器1,T1= 9T,T2=2T,波特率為500kbit/S*/
outputàcontrol = 0x1A; /*正常輸出方式,TX1引腳懸浮*/
clockàdivider = 0x40; /*BASICCAN模式,RX1接固定電平*/
control = 0x1A; /*清復(fù)位請求,使其進(jìn)入工作狀態(tài)*/
}
發(fā)送canàsend()
發(fā)送子程序負(fù)責(zé)節(jié)點(diǎn)報(bào)文的發(fā)送,由CAN控制器SJA1000獨(dú)立完成,將命令寄存器里的發(fā)送請求標(biāo)志置位,即可發(fā)送SJA1000發(fā)送緩沖區(qū)中的報(bào)文。
void canàsend(unsigned char ID ,char*xdata) /*該子函數(shù)完成一幀數(shù)據(jù)的發(fā)送*/
{while ( (status&0x10)>> 4 == 1)àNOPà; /*檢查上次請求發(fā)送是否完成*/
while ( (status&0x04)>> 2== 0)àNOPà;
Transmitbuffer1= ID;
Transmitbuffer2= 0x08;
Transmitbuffer3= txdata[0] ;
Transmitbuffer10= txdata[7] ;
Command = 0x05 ; /*發(fā)送請求*/
while ( (status&0x08)>> 3== 0);
}
接收子程序canàreceive ()
接收子程序負(fù)責(zé)節(jié)點(diǎn)報(bào)文的接收。SJA1000自動(dòng)接收發(fā)往該節(jié)點(diǎn)的數(shù)據(jù)并將收到的數(shù)據(jù)放到它的接收緩沖器中。
SJA1000的報(bào)文接收主要有2種方式:中斷接收方式和查詢接收方式。系統(tǒng)采用的是中斷接收方式。
{unsigned char ir ;
ir = interrupt; /*獲得SJA1000的中斷狀態(tài)*/
EA= 0;
If ( (ir&0x04)>> 2== 1)error ( ); /*如果是出錯(cuò)中斷,則調(diào)出錯(cuò)處理函數(shù)*/
If ( (ir&0x08)>> 3== 1)overruN( ); /*如果是超載中斷,則調(diào)超載處理函數(shù)*/
While ( ( (ir&0x04)>> 2== 1)‖( ( (ir&0x08)>> 3)== 1){àNOPà;}
RxID[0] = Receivebuffer1;
RxID[0] = Receivebuffer2;
If ( ( (Receivebuffer2&0x10)>> 4)== 0) /*如果是數(shù)據(jù)幀,則接收數(shù)據(jù)*/
{Rxdata[0] = Receivebuffer3;
.
Rxdata[7] = Receivebuffer10;
Command = 0x04 ; /*SJA1000的接收緩存器被釋放*/
}
else if ( ( (Receivebuffer2&0x10)>> 4)== 1) /*如果是遠(yuǎn)程幀,則作相應(yīng)處理*/
{ /*相應(yīng)處理程序*/
EA= 1;
}
}