PIC 8位單片機內已經包含運算器、存儲器、A/D、PWM、輸入和輸出I/O(灌電流可達25 mA)、通信等常用接口,自由靈活的定義功能可以適應不同的控製要求,而不必增加額外的IC芯片。這樣電路結構很簡單,開發周期將大為縮短。
PIC16係列單片機屬於PIC 8位單片機的中級型產品,采用14位的RISC指令係統。筆者使用PIC16F716單片機設計了一個電動機保護器,在設計過程中遇到很多問題,通過多方查找資料以及向Microchip公司技術人員尋求支持,問題一一得到解決。現將部分問題記錄如下,與大家一起探討。
1 ICD2作為(wei) 程序燒寫(xie) 的使用
1.1 ICD2簡介
MPLAB ICD2在線調試器是一款低價(jia) 位的PIC開發工具。它利用Flash工藝芯片的程序區自讀寫(xie) 功能來實現仿真器調試功能;使用的軟件平台是Microchip的MPLAB IDE(集成開發環境軟件包),兼容Windows NT、Windows 2000和Windows XP等操作係統。其通信接口方式可以是USB(最高可達2 Mb/s)或RS-232串行接口方式;工作電壓範圍為(wei) 2.0~5.5 V,可支持最低2.0 V 的低壓調試.
MPLAB ICD2可以支持大部分Flash工藝的芯片。它不僅(jin) 可以用作調試器,同時還可以作為(wei) 開發型的燒寫(xie) 器使用。
1.2 ICD2作為(wei) 燒寫(xie) 器時的配置
燒寫(xie) 芯片的方式有兩(liang) 種:普通燒寫(xie) 和在線燒寫(xie) 。在線燒寫(xie) 是適合大批量生產(chan) 方式的燒寫(xie) 辦法。使用在線燒寫(xie) 時通常用戶都已經把芯片焊到了板上,此時就要求用戶板上有預留的燒寫(xie) 接口。用戶板上的接口是通過一條6芯的扁平電纜與(yu) ICD2主機上同樣的接口一一對應連接的。圖1顯示了MPLAB ICD2與(yu) 目標板上模塊連接插座的互連狀況。
ICD連接插座有6個(ge) 引腳,但隻使用了其中的5個(ge) 引腳,分別是VDD(電源)、Vss(地)、Vpp(編程電壓)、PGC(同步時鍾)和PGD(數據)。
1.3 ICD2作為(wei) 燒寫(xie) 器時容易出現的問題及解決(jue) 方法
盡管MPLAB ICD2與(yu) 目標板的互連非常簡單,但是一不小心就會(hui) 出現問題,基本上每一個(ge) PIC的入門者都會(hui) 碰到類似的問題。下麵就一些常見問題作簡要敘述。
如圖1所示,在Vpp與(yu) VDD之間通常要串接一個(ge) 上拉電阻(通常約為(wei) 10 kΩ),這樣Vpp線可置為(wei) 低電平來手動複位PICmicro單片機。但是對一般設計者來說,都是采用上電自動複位。如果在這裏采用集成器件DMP809,那麽(me) 就會(hui) 導致連接不上,程序沒有辦法燒入。
對於(yu) PGC、PGD兩(liang) 根線,由於(yu) 在ICD2內(nei) 部已經進行了上拉,所以在外圍設計中,不要再進行上拉,否則會(hui) 造成分壓。對於(yu) PGC、PGD和Vpp三根線,不要對地接電容,因為(wei) 電容會(hui) 阻礙在數據和時鍾線上電平的快速轉換,從(cong) 而影響ICD2與(yu) 目標板的連接。同樣對於(yu) PGC、PGD,由於(yu) 數據或時鍾都是雙向傳(chuan) 輸的,這時如果在中間串一個(ge) 二極管,則會(hui) 影響ICD2與(yu) 單片機的雙向通信。
但是,對PGC和PGD來說,在單片機上同時複用為(wei) 普通I/O 口,而有些使用上必須要接對地電容或者是串接二極管。對於(yu) 這種情況,唯一的處理方式就是在燒寫(xie) 時從(cong) 芯片的PGC和PGD端口直接跳線到程序燒寫(xie) 口。
2 A/D轉換通道切換問題
筆者所設計的電動機保護器需要進行很多A/D轉換,比如三相電流轉換、零序電流轉換以及各種定位器等。但是筆者所采用的PIC16F716單片機隻有5路A/D轉換通道,因此附加了一個(ge) 多位選擇開關(guan) 對一個(ge) A/D通道進行複用。而在調試中發現這樣一個(ge) 問題,就是A/D轉換值不準確,甚至有點亂(luan) ,但從(cong) 程序流程以及代碼角度均查不出任何問題。後查明PIC16F716單片機進行A/D轉換通道切換時,需要一定的延時,延時時間是毫秒級。解決(jue) 辦法是:在通道間切換時,當第一個(ge) 通道轉換完成後,先轉到另一個(ge) 通道;然後延時1 ms左右,再進行A/D轉換。而對同一個(ge) 通道信號切換時,要在第一個(ge) 信號轉換完成後,禁止信號輸入,延時1 ms左右;然後輸入信號,再進行A/D轉換。
這種做法比較麻煩,也很占用時間,並且從(cong) 調試結果來看,問題並沒有解決(jue) 。在反複進行調試中,最後得到的優(you) 化解決(jue) 辦法是:對於(yu) 通道間轉換以及同一通道信號轉換,要對每一個(ge) 信號至少進行兩(liang) 次A/D轉換;第一次的轉換結果,舍棄不予處理,隻取第二次A/D轉換的結果。從(cong) 調試結果來看,很好地解決(jue) 了這一問題。
3 軟件開發小技巧
PIC單片機采用精簡指令集,例如對於(yu) PIC16F716單片機,隻有35條單字節指令。要用這麽(me) 少的指令實現複雜的控製或計算,顯然要在軟件設計上多下功夫,並且PIC的指令係統與(yu) 51係列單片機有很大不同,這讓PIC初學者很不適應。下麵筆者就自己的體(ti) 會(hui) ,談一些軟件設計需要注意的問題。
3.1 指令的大小寫(xie) 問題
編寫(xie) PIC單片機的源程序,除了源程序的開始處需要嚴(yan) 格的列表指令外,還須注意源程序中字母符號的大小寫(xie) 規則,否則在PC機上匯編程序時不會(hui) 成功。在源程序中都會(hui) 使用偽(wei) 指令INCLUDE。這條指令將列表中指定的單片機文件(在MPLAB中)讀入源程序作為(wei) 源程序的一部分,所以凡是MPLAB中有關(guan) 該單片機已有的寄存器在源程序中無需再用賦值指令(EQU)賦值,這就使所建立的源程序大為(wei) 簡化。
此外,由於(yu) 有了偽(wei) 指令INCLUDE,所以根據MPLAB軟件中的格式,在源程序中的操作數凡是涉及MPLAB已規定的寄存器名稱的,其字母一律隻能大寫(xie) ,不能小寫(xie) 。其餘(yu) 操作碼、符號字母可任意大小寫(xie) ,但0x中的X應小寫(xie) ,否則匯編不會(hui) 成功。鑒於(yu) 上述原因,為(wei) 了書(shu) 寫(xie) 方便,在使用MPLAB軟件時,PIC單片機的源程序均用大寫(xie) 字母為(wei) 宜(0x例外)。
3.2 振蕩器的配置以及時序的計算
PIC係列單片機可以工作於(yu) 以下4種不同的振蕩器方式:LP(低功耗晶體(ti) 振蕩器)、XT(晶體(ti) 諧振器)、HS(高速晶體(ti) 諧振器)和RC(阻容振蕩器)。用戶可以根據其係統設計的需要,通過對配置位(FOSC1和FOSC2)編程,選擇其中一種工作模式。
而一旦振蕩器配置完成,那麽(me) 根據用戶的配置,可以輕鬆地計算出程序運行的時間以及A/D轉換所占用的時間,這樣就會(hui) 很輕鬆地安排好單片機的時序。例如,如果采用4 MHz的HS振蕩模式,那麽(me) 單片機的時鍾頻率為(wei) Fosc/4,也就是說執行一條指令需要1us;對於(yu) 需要兩(liang) 個(ge) 指令周期的指令,需要2us。而對於(yu) A/D轉換,如果A/D轉換時鍾位選擇為(wei) Fosc/8,那麽(me) A/D轉換模塊轉換一個(ge) 位的時間Tad就為(wei) 2us。對一個(ge) 8位的轉換來說,需要的時間為(wei) 9.5Tad,也就是完成一次A/D轉換的時間為(wei) 19us。這樣隻需要查看源程序的行數並作簡要分析,就可以計算出程序運行的時間。
3.3 存儲(chu) 體(ti) 的選擇
PIC單片機的數據存儲(chu) 器通常分為(wei) 兩(liang) 個(ge) 存儲(chu) 體(ti) ,即存儲(chu) 體(ti) O(Bank0)和存儲(chu) 體(ti) 1(Bank1)。每個(ge) 存儲(chu) 體(ti) 都是由專(zhuan) 用寄存器和通用寄存器兩(liang) 部分組成的。兩(liang) 個(ge) 存儲(chu) 體(ti) 中的一些寄存器單元實際上是同一個(ge) 寄存器單元,卻又具有不同的地址。
不同型號的PIC單片機,其數據存儲(chu) 器的組成(即功能)是不完全相同的,所以設計人員一旦選用了某個(ge) PIC單片機的型號後,就要查找該單片機的數據存儲(chu) 器資料,以便編程使用。
筆者所采用的PIC16F716單片機的存儲(chu) 區,是通過STATUS寄存器的RP1位和RP0位來選擇的。當配置為(wei) 00時,表示選擇存儲(chu) 區0;當配置為(wei) 01時,表示選擇存儲(chu) 區1。因為(wei) 存儲(chu) 區的改變隻須改變RP0位,所以通常在程序編寫(xie) 時,隻改變RP0位來選擇存儲(chu) 區。但是這樣容易造成程序的混亂(luan) ,因此,筆者建議在每次更換存儲(chu) 區時,要分別對RP0和RP1進行置位。在程序初始化時,最好將寄存器的初始化分為(wei) 兩(liang) 部分:第一部分為(wei) 存儲(chu) 區0;第二部分為(wei) 存儲(chu) 區1。然後將每個(ge) 需要初始化的寄存器分別在對應的存儲(chu) 區進行初始化即可。
3.4 GOTO和CALL指令的不同使用
在PIC的匯編程序中,CALL與(yu) GOTO 指令使用的場合不同。CALL是用來調用子程序的,在調用完子程序後返回到調用前的程序;而GOTO是無條件轉移,即由此狀態進入另外一個(ge) 狀態而不需要返回。
為(wei) 了使程序更加具有可讀性,使流程更加清晰、合理,通常程序都采用模塊化程序設計,即將程序按照功能分成不同的子程序,而主程序則相當簡潔,隻須采用CALL 指令對子程序進行調用。
由於(yu) PIC單片機的堆棧有限,在程序中不能無止境地使用GOTO指令,否則會(hui) 使堆棧溢出,程序無法正常運行。但是在有些時候,例如當程序出現分支時,則不得不使用GOTO指令。對於(yu) PIC16F7x係列單片機,程序出現分支時隻能通過STATUS寄存器的Z位或C位進行判斷。這時在兩(liang) 種情況.的前一種情況下,必須使用GOTO指令進行轉移;否則在執行完第一種情況後,緊接著又執行第二種情況。程序如下:
BTFSS STATUS,Z
GOTO A
GOTO B
在跳轉到A時,必須使用GOTO指令;否則執行完這條語句以後,緊接著執行GOTO B。這樣無論Z為(wei) 何值,程序都將跳轉到B。而對於(yu) GOTO B,則可以不必使用GOTO指令。
在上麵這種情況下,由於(yu) GOTO隻在子程序內(nei) 部進行跳轉,小程序內(nei) 部循環占用堆棧的級數不多,因此使用GOTO指令是可行的。但是在大的程序中使用GOTO指令,將有可能無法返回到調用前的下一條指令。
因此,筆者建議,在使用匯編語言進行程序設計時,應該將程序分解成一級級的子程序;然後在程序之間進行調用,盡量將GOTO指令跳轉的範圍縮小。
3.5 對芯片的重複燒寫(xie)
對沒有硬件仿真器的設計者來說,總是選用帶有EPROM 的芯片來調試程序,通過反複的修改來觀看運行結果,以便對程序進行調試。每更改一次程序,都是將原來的內(nei) 容先擦除,再編程,浪費了相當多的時間,又縮短了芯片的使用壽命。如果後一次編程較前一次,僅(jin) 是對應的機器碼字節的相同位由1變為(wei) 0,那麽(me) 就可在前一次編程芯片上再次寫(xie) 入數據,而不必擦除原片內(nei) 容。
在程序調試過程中,經常遇到常數的調整。如果常數的改變能保證對應位由1變0,則都可在原片內(nei) 容的基礎上繼續編程。另外,由於(yu) 指令NOP對應的機器碼為(wei) 00,調試過程中指令的刪除,可先用NOP指令替代,編譯後也可在原片內(nei) 容上繼續編程。
結語
在采用PIC單片機進行設計過程中,注意到PIC單片機自身的特點,可盡量少走彎路,從(cong) 而縮短開發周期。同樣在軟件設計上采用合適的方法,可以使整個(ge) 程序運行穩定,而且程序空間的使用也將有所減少,避免了調試中的Bug。以上隻是筆者在實際設計過程中一些小小的體(ti) 會(hui) 。希望與(yu) 大家一起探討,並在共同學習(xi) 中為(wei) PIC單片機的普及和推廣做出貢獻。