PIC12F675的一點使用心得筆記

我以前是從8051開始學的,不過都只是粗淺的認識及使用,後來發現有PIC這種單晶片,他因為腳位少,功能上滿多樣化的,所以我也是好奇心的驅使下,玩了一點點,只是把這些東西,當成是一種認識,並沒有真的利用它來從事設計的工作,就是玩玩嘛!

我的心得純粹是針對初學者而寫的,最好是有組合語言概念的人,相對的,您對電腦的架構也要有概念比較好,因為我不會去探討學理上的東西。而且是我自己的一些認知,希望能將PIC這種好玩的東西推廣,目的是要讓想要玩玩PIC的人士,對PIC有一個初步的瞭解,進一部的可以簡單的運用。所以難免在用詞上會採取簡單的譬喻,為的是讓初學的USER能瞭解,如有疏漏或是觀念有錯誤之處,也歡迎先進門的指正,以正確的觀念去幫助那些想入門,卻不得其門而入的求知者,功德無量。

剛開始玩的時候,我想每一位玩單晶片的玩家,最先碰到的就是零件的取得及燒錄器的問題,這些問題大概就讓我玩PIC又延遲了半年到一年的時間,因為畢竟自己也是要工作的。首先是PIC買不到的問題,市面上都買不到,最後找代理商,解決了問題。然後是燒錄器的問題,一直到我在國外網站上找到了自製的燒錄器之後,終於燒錄成功,開始玩起來了。當然,有一本參考書是最好的,我當初是買全華的書,吳一農先生寫的,還不錯,是以介紹PIC16F84為主,只是他當中所用的組譯器是SPASM,這個組譯器的好處是,因為他可以使用類8051指令,也就是說,他可以讓您像寫8051一樣的方式使用PIC。但是後來漸漸地發覺,這種方式會讓你自己跳脫不了8051的束縛,尤其是當你已經漸漸瞭解PIC,準備要開始使用其他型號的PIC時,就會知道不會使用正統的PIC指令時,你恐怕就很難去寫程式了,因為SPASM不能用在其他的PIC型號上。所以,奉勸大家還是學正統的PIC指令吧!

這是我第一次使用12F675,剛開始使用時還真的是不順利,因為跟之前的16F84比較起來,它要精簡多了,除了I/O pin腳較少外,其他的功能,都遠在16F84之上,尤其是頻率,可以達到20MHZ,就算是使用內部震盪頻率,也可以有4MHZ的頻率。

PIC單晶片最大的好處,我個人認為是它的指令非常少,少到只有35個指令,所以不需要背太多的指令,因此在設計程式時,會比較好寫,同時它的硬體結構功能強,往往一個接腳同時兼具多樣功能,讓使用者有很多種的選擇。


基本配備

先介紹一下玩PIC的最基本配備,在一個非專業人士的條件下,以下東西一定要有:

  1. 電表一定要有,示波器是沒有辦法的,因為我不是賺美金過生活的,可是電表不可沒有,否則連電壓都沒法量測,是無法抓問題的。

  2. 麵包板,別說你不知道,否則,別玩了!難道都要直接悍在電路板上做實驗嗎?

  3. 一些簡單的電子元件,自己要看者辦吧!或是邊實驗邊買,買個整套的電阻板是不錯的方法,其實粗淺的PIC設計,只會用到LED,電阻,電容,按鈕開關等幾樣小零件而已。

  4. 電源,拿一個7805的5V穩壓IC做一個就可以了。

  5. 參考書一本以及您使用那款型號PIC的datasheet資料,沒有書參考做實習,是極為困難的一件事,難道要用想像的嗎?datasheet就是那個PIC型號的電子檔,也就是那一個型號PIC零件的使用說明書,一個零件的說明書就有百來頁喔,而且是英文的,慢慢K吧!只要會使用其中的一種PIC,學其他的也都應該差不多。

  6. 一本筆記本,記錄你的實驗過程及問題,包含程式草稿,線路草稿等等的記錄,不要太相信腦袋瓜,忘的很快的,趕緊養成寫筆記的習慣吧!或是馬上以電腦建檔,也是一個不錯的方法,也可以馬上分享網友,是個不錯的方法。

  7. PIC燒錄器一部,不需要花大錢去買好幾千塊的燒錄器,因為我們都不是專業的RD,網路上的DIY燒錄器很多,從幾十塊到幾百塊的都有,看您自己的選擇,可以參考我網頁上的一篇文章照者做也行,或是跟我買也可,先說聲謝謝您的惠顧了。這裡的建議是,依自己的需求製作簡單的燒錄器就可以了,功能太多用不到,製作時的失敗率也高。等學會PIC基礎之後,再決定是否要升級高階的PIC燒錄器。燒錄器的軟體也是一定要的啦,否則如何將您寫好的程式傳輸到PIC上呢?

  8. 任何一款型號的PIC,最好是市面上或是網路上常看得到的,用太特殊的,會找不到人問問題喔,目前市面最常用的,當然是16F877囉!不過腳位太多,對於初學者來說,有點複雜。最好挑8PIN的或是18PIN腳位的PIC來學,當中以16f84及16f628較普遍吧。不過16f84缺少一些功能,而且價格也貴,因為製程的關係,所以建議大家用16f628來用,不然就學我,拿顆8pin的PIC來玩玩,因為簡單,心理障礙比較沒那麼大喔。如果您有找不到PIC方面的困擾,可以找我問問,或是跟我買吧!不過我先聲名,因為我也是要吃飯的,不一定會便宜,但是至少是一個讓您取得PIC的管道之一,就當成您是花錢消災吧,不過我的價錢應該也還好吧?呵呵!

  9. 電腦一部,不需太好等級的,P-II的就可以了,因為主要是寫程式用的,而且以文書為主,頂多是完成程式後的組譯工作,也不需要太快的電腦。除非您是使用C語言編寫程式,不過我本身對C並沒有研究,我知道C的功能強大,但是實在是學不動了。

  10. 組譯軟體一套,可以使用Microchip公司的免費程式就可以了,而且功能強大,叫做MPLAB IDE,他內含寫程式的文書軟體以及組譯組合語言用的MPASM程式。如果不使用C語言寫程式,這一套就很好用了。因為C組譯器不是免費的,所以MPLAB IDE當中的C組譯器是有試用日期限制的。

這裡再解釋一個概念,我們所寫的程式是給人類看的,機器本身是看不懂我們的程式的,因此必須經由一個程式,將我們所了解的程式碼,翻譯成機器碼,然後透過燒錄器,將這些機器碼送到PIC單晶片的程式記憶體中,PIC就是依據這些存在程式記憶體中的指令,依序依設定條件做出反應及動作。簡單的說,PIC也是一部電腦,是一部微電腦,所以我們常常在看電器產品廣告時,會強調微電腦控制,就是指這一類的簡易型微電腦,別把他想的太玄了。

12F675長相

12F675腳位圖

電路圖

繪製中.....請見諒,以後再補上。

一個簡單的程式

首先我先說明PIC的最簡單用法,就是利用I/O pin來輸出訊號,點亮LED。
使用的組譯程式是Microchip公司提供的MPASM程式,可到Microchip公司網站下載安裝。
功能:用12F675做出LED一閃一閃的動作。

接線:將12f675第7腳,也就是GP0接上限流電阻及LED,我們就是利用這個接腳來做輸出。

請看圖示

程式的基本寫法:

                list p=12f675                         ;定義我們所要使用的PIC型號
                #include <P12f675.INC>     ;12f675的含入檔
                __CONFIG _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF
                                                            ;設定PIC燒錄時,PIC的內部狀態。
                loops       Equ     0x21
                loops2     Equ     0x22
Init:
                bcf           STATUS,RP0
                clrf           GPIO
                movlw     07h
                movwf     CMCON                 ;disable comparator
                bsf           STATUS,RP0
                clrf           ANSEL
                clrf           TRISIO
                bcf           STATUS,RP0           ;Bank 0 這很重要
                clrf           GPIO

                main
                bsf             GPIO,0
                call             Wait
                call             Wait
                bcf             GPIO,0
                call             Wait
                call             Wait
                goto             main
                Wait
                movlw         .250
                movwf         loops
                wai
                movlw         .110
                movwf         loops2

wai2

        nop
                nop
                nop
                nop
                nop
                nop
                decfsz          loops2,F
                goto             wai2
                decfsz l        oops,F
                goto             wai
                retlw 0
                end


程式說明

list p=12F675

這一行是宣告我們寫的程式是運用在哪種型號的PIC,便於MPASM組譯出正確的PIC碼。

#include <P12f675.INC> 

這一行是將PIC12F675的含入檔帶入程式中,如果看一下P12F675.INC這個檔案,可以看到他的內容其實是已經幫我們定義好一些暫存器的代號,這樣我們就不必再寫程式時再將每個暫存器的名稱重新要定義一次,因為人家寫好現成的東西拿來使用是最方便的,否則每個程式開頭,我們都要將程式中要使用的各種暫存器要事先定義好,光是這樣的工作,就會花掉很多時間了。您想看看,如果像SFR,INDF這類的指令都要我們自己去定義,除非你的腦袋瓜夠好,都直接記住這些暫存器的十六進位的位址,否則目前的這種方式是最簡單的。

其實含入檔,就是在現有的程式中,將其他的程式以檔案的方式讀入,以簡化現有程式的內容,尤其是一些內容重複相同的程序,可以用含入檔的方式使用於程式中。但是含入檔一般都是使用在程式中被使用的次數少,甚至是只有程式開始時才被使用的程式。因此,為了簡化程式內容及方便程式維護,會採取含入檔的方式,是不錯的一個方法。

  __CONFIG _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF

這一行主要是定義當燒錄器在燒入PIC程式時,PIC燒錄器要採取什麼樣的工作模式。因為PIC本身要動作的必要條件就是除了電源以外,我們必須給他clock訊號,這個clock時脈訊號在PIC中就有很多種,可以使用RC震盪,可以使用石英晶體震盪器,也可以使用PIC內部的震盪器,而這些選擇,就是這一行的功能。其他還有看門狗的功能是否打開,您辛苦寫的程式是否禁止被燒錄器讀出,以免被COPY,可以設定的選項很多,請自行尋找相關的文件說明。

        loops       Equ     0x21
                loops2     Equ     0x22

這兩行是定義loops以及loops2的定義,由字面上不難理解,loops等於就是0x21位址,而loops2就等於0x22這個位址,而0x21與0x21分別代表十六進位的位址。一但定義過,以後在程式中,我們就可以用loops這個字代表十六進位的位址0x21,如果寫成21h或是22h,則表示是一個十六進位的數值而不是十六進位的位址值喔!這個可要分清楚。因為有這個功能,我們就不必記憶那些難以記憶的十六進位的位址值,只要記憶我們所能理解的文字名稱就行了,以後在程式中只要看到這個文字,就可以知道它代表的意義了,同時也方便程式本身的可閱讀性,方便日後的程式維護修改工作。


Init:

這是一個標記,在程式中來說就是某個程式段落的開始,他可能是一段附程式的標記,也可能是主程式的開始標記,也有可能是我們為了將程式分段,便於以後閱讀時所做的程式標記,總之,是依個人需求來定義的。要注意的是,如果程式當中有使用到標記名稱,可是我們並沒有做定義時,程式在組譯時就會有錯誤發生,這點要加以注意。以本例子來說,Init是某一個程式的段落,作用是定義程式開始執行時,一些程式中會使用到的暫存器或是變數的初始值。Init:後面的冒號也可以不用打,MPASM組譯器允許兩種寫法。

                bcf           STATUS,RP0

將PIC目前的特殊功能暫存器記憶頁,切到第0頁。因為我們接下去要定義PIC的GPIO輸出入PORT,所以必須將特殊功能暫存器記憶頁切到第0頁。這裡說明一下PIC的記憶體結構,除了我們常聽說的記憶體外,單晶片就是將RAM,CPU,I/O等等的硬體結構都濃縮到一個IC上的積體電路,因此,我們所有的程式,包含我們所使用的功能,也都被侷限在這個積體電路中。也就是說,他的結構是一個封閉的記憶體區塊,通常這個記憶體被分為兩個部分,一個就是我們寫程式時,我們的程式所存放的地方,一但被燒錄器燒入以後,就沒有辦法被更改的,相當於我們電腦中硬碟的角色。另一種就是為了程式運作的記憶區塊,相當於我們電腦的RAM記憶體,這塊區域當沒有電源時,記憶內容就會消失回復到原始設定值,通常是00h值。

我們特別要說明的就是這一塊區域的記憶體,這一塊記憶體並非全部都是可以被我們隨便寫入資料的,因為有些位址是拿來作為PIC運作時,放置一些重要的資料,以便PIC能順利的運作程式。拿電腦來舉例,他有點像是電腦中的作業系統,有些位址是被系統看管,不能被使用者佔據使用的,以免造成系統當機,這些位址通常都是位於RAM位址的最前面。PIC也是一樣,特殊暫存器區的位址是從00h到FFh位址,但是為了方便使用者使用,PIC又將這個連續區域話分成兩個區塊,00h到7Fh以其80h到FFh這兩塊,每塊剛好都是128個位址。而這兩塊RAM記憶體中的前32個位址,都是定義給特殊暫存器使用,從第33個位址開始一值到第128個這一段,才是使用者可以自行規劃運用的,也就是20h~7Fh及A0h~FFh這兩塊區域,請參照PIC的datasheet當中的說明,每種不同型號的PIC,他們的使用區塊都略有不同,但是大同小異。

經由以上簡短的說明,我們就可以知道,當我要使用某些特殊暫存器時,就必須要知道那個暫存器的位址,然後將其找出,並寫入或是讀出資料。可是因為PIC對於這塊記憶體區域的管理方式不是採用直接定義位址的方式,而是利用區塊管理的方式來切換記憶區塊的。因此我們要使相關的特殊功能暫存器時,必須先將區塊切到那個暫存器所在的區塊後,然後再到那個暫存器的位址去讀取或是寫入資料。因此才會有這行程式指令bcf           STATUS,RP0出現。詳細的使用方式,請參考datasheet說明。
                clrf           GPIO

由於前一行已經將特殊功能暫存器區塊已經切到第0區了,所以我們就可以使用GPIO暫存器的功能,這行的功能是將GPIO暫存器內容清除為零。GPIO本身是一個6位元的雙向PORT(本例說明是針對PIC12F675),他的方向是由TRISIO暫存器決定的,也就是說TRISIO暫存器的位元跟他是相對應的關係,當TRISIO對應的位元被設定成1時,GPIO的相對應位元就設定為input輸入,相反的,當TRISIO對應的位元被設定成0時,GPIO的相對應位元就設定為output輸出。當GPIO設定為輸入狀態時,就是說我們可以透過它讀到PIC接腳上的訊號,藉此可以偵測外面的接腳電位,經由判斷外界的電位,來決定程式的步驟。同樣的,當GPIO為輸出時,我們可以寫資料到GPIO中,實際上是將資料先寫到一個GPIO的閂鎖器中,然後閂鎖器再將資料送到PIC的接腳上,我們就可以在PIC接腳上接上LED等負載,來顯示GPIO的狀態了。也就是寫資料輸出到PIC接腳上的步驟是,先將GPIO內的資料讀出,並修改資料後寫到GPIO暫存器,然後再將結果寫入到GPIO閂鎖器中,閂鎖器再將資料輸出到PIC的接腳上。作為AD轉換接腳的I/O引腳,讀到的值始終為0。
                movlw     07h
                movwf     CMCON                 ;disable comparator

由於PIC的接腳是多工能的接腳,每個接腳也都可以設定成不同的功能,因為可以作為輸入,輸出,AD轉換,比較器功能,也可以當作clock時脈輸入腳,因此,當我們要將PIC接腳當成一般的I/O功能的接腳時,就必須將其他的功能關閉,這兩道指令,就是關閉接腳的比較器功能,因為GP0,GP1,GP2這三支腳同時也扮演類比比較器的功能,因此必須先將他們的比較器功能關閉,才可以正常使用PIC接腳I/O功能。至於比較器的功能,也請參考相關PIC的datasheet說明。
                bsf           STATUS,RP0
                clrf           ANSEL

bsf  STATUS,RP0不用解釋了,應該知道涵義了,而clrf   ANSEL這個指令,則是PIC12F675特有的暫存器,ANSEL   是AD轉換用的選擇暫存器,所謂AD就是類比數位轉換啦!由於本例用不到這個功能,所以要將他的功能關閉啦!ANS3~ANS0位元都被設定為零時,PIC相對應的接腳就當成一般的I/O接腳使用了。
                clrf           TRISIO

前面已經有提到,它跟GPIO是相對應的關係,這裡是將GPIO都設定成output輸出功能。

         bcf           STATUS,RP0           ;Bank 0 這很重要

為什麼說他很重要呢?因為很多人都忘了這一步驟,結果是電路都不動作。由於往後的程式會做一個清除GPIO的動作,而且之後的程式都是針對GPIO做讀或寫的動作,由於之前的程式因為使用了clrf   ANSEL這個指令,所以特殊暫存器區塊已經切到第個區塊,所以我們接下來因為要使用到GPIO,而GPIO是存在於第0個區塊的,因此必須將特殊暫存器區塊切回第0區,往後的程式才能正常的使用GPIO,當初我就是在這裡被搞死的,還以為自己的程式有問題,或是PIC有問題。而且datasheet當中的範例都沒有寫到這一行,因此會被初學者忽略掉。
                clrf           GPIO

將GPIO暫存器內容清除,以便往後程式的利用。

main

一般我們都喜歡將主程式開頭的標記用MAIN或是START作為標記開頭。

                bsf             GPIO,0
                call             Wait
                call             Wait
                bcf             GPIO,0
                call             Wait
                call             Wait
                goto             main
Wait
                movlw         .250
                movwf         loops
wai
                movlw         .110
                movwf         loops2

wai2

        nop
                nop
                nop
                nop
                nop
                nop
                decfsz          loops2,F
                goto             wai2
                decfsz          loops,F
                goto             wai
                retlw             0

以上只是簡單的延時程式,請自行研究吧,在此不多加以敘述了。
                end
程式的結尾一定是以end指令作為結束,end之後的指令是不會被組譯器組譯的。所以end之後的程式是不會被組譯及執行的。

其他功能

以後再陸續編寫內容,因為我也是初學中.....

用12F675完成的電路及程式

四位數Displayer LTM8328KP使用說明已經放在網頁上,是關於LTM8328這個四位數顯示器元件的控制程式寫法,由於程式我要拿來賣錢買電腦週邊及賺些零用錢,因此只公開燒錄碼及電路圖,請大家見諒!

四路可切換音源的控制電路:也算是無聊時的一個作品,因為電腦喇叭只有一對,除了電腦的聲音外,有時又想聽聽CD或是收音機,同時也預留了一路音源作為其他聲音的輸入用,看使用者自己要如何用吧。這個電路可以輸入四個立體音源,透過一個按鈕就可以切換四路聲音,只需要一對喇叭即可。可是只用於二聲道的輸入及輸出,也就是一般的立體耳機插孔。

個人的一些寫程式心得

這些都是我個人玩PIC時的過程,不見得每個人都一樣,也許您的方式比我還要好,我只是寫出來供網友參考。

從日常生活中先找到問題及動機,日常生活中總是會碰到一些問題,有些可以用現成的產品解決,有些不行。不行的就要自己想辦法解決,當成好玩的心態去做,會比較有趣,也沒有壓力。

先試圖用最簡單省錢的方法解決問題,因為只是自己DIY,所以解決問題最重要,只要有好方法,不一定非用電子的方式達成。

不見得一定馬上要做出功能很多的程式,功能穩定正常最重要,可以慢慢的將功能逐步加上去,因為是可程式可修改的,就是有這個好處。

設計製作過程中,盡量考慮到往後方便維修以及更換元件的情況,如果可以將各種功能模組化更好,可以一物多用。盡量在線路上預留可以擴充的空白,以便要加元件時有可以放置的位置,或是預留接頭可以連結外部線路。零件的選擇最好是選擇普通好買的元件,除非是一些專用的零件。

程式要分段編寫,最好是用副程式的結構,每個功能都是獨立的副程式,這樣再抓程式bug時,十分好用。絕對不要把程式統統混寫在一起,很麻煩的,特別是呼叫跳躍,避免有交叉的情形。

有時思維一定會進入死胡同,不妨暫時忘掉,換個方式寫程式,重新寫程式有時會比修改程式還輕鬆,而且您會發覺,有時我們自己的思維每次都會不一樣,大概跟日常生活所見所聞有相關聯,會影響思考的。

因為是DIY的,所以不要給自己壓力,不是靠這個吃飯,犯不著不吃不喝,做不出來就算了!上網看看有沒有現成可以DIY的資料,國外的資料真的很多,也很實用。

所有的過程,將他紀錄下來,最好發表出來,供網友參考討論指教,三個臭皮匠勝過一個諸葛亮。如果希望程式能賣錢,最好也能在一段時間後公開,或是有新版的程式出來後,公佈舊版的,讓後進者不須重複摸索浪費時間,知識的進步需要的是累積,不是藏私。


回DIY首頁