Saturday, June 21, 2014

LPC1114FN28的GPIO使用方式

在學習微控制器最基礎的想必是動動I/O接腳, 推個LED燈或是讀取外部按鈕輸入.但經過實驗發現, 改變上次實驗內容的電路圖接法,將LED接至其他GPIO並單純的修改程式碼中的腳位設定,其實是無法直接驅動LED的!
作為一顆32位元的多功能ARM微處理器, 對於GPIO的設定與操作使用自然比較複雜些, 此次的心得將紀錄LPC1114FN28的GPIO使用方式, 以及在datasheet中的相關章節閱讀提示.

元件列表

  1. NXP LPC1114FN28 x 1
  2. 按鈕 x 3
  3. 電阻 330 Ω x 1
  4. 電阻 4.7k Ω x 2
  5. LED x 1

使用工具

  1. USB轉UART轉接線
  2. 3.3V位準電源

電路圖

LPC1114_GPIO_experiment_schematic

電路說明

於本次實驗將LED接至PIO1_0接腳,藉以測試在多功能的IO接腳上如何進行功能的切換;同時將燒錄按鍵PIO0_1作為此次實驗的外部輸入.

操作原理

在這次的實驗中, 希望能夠藉由一組按鈕接腳輸入(PIO0_1)來改變另一組LED接腳(PIO1_0)輸出, 藉以驗證基礎的GPIO功能; 當按鈕按下時, LED燈熄滅, 反之當沒有按下按鈕時, LED啟動.

有別於AVR ATmega系列的8位元微控制器, 以ARM Cortex-M0作為核心的LPC1114內部結構較為複雜些, 對於時脈的掌控更是需要注意; 在LPC1114的使用手冊中第3.4節中, 便提示了有一組名為SYSAHBCLKCTRL的暫存器掌控了所有週邊界面的時脈. 在本次的實驗中需要使用GPIO, 因此在系統啟動時,必須開啟I/O部份的時脈輸入;在手冊3.5.14章節中有對SYSAHBCLKCTRL之內容進行說明, 針對I/O時脈引入的設定在第16位元(IOCON),需將此暫存器內容寫入1:

LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_IOCON;

為了達成多種應用, 現今的微控制器需要支援多種界面(peripheral),從一般GPIO,ADC轉換的單一接腳用途,以至於多組接腳所一起組成的通訊界面如SPI,UART,I2C等,加上計數器…如此眾多的功能需要在有限的接腳資源內完成, 想必一定有些接腳是具備多種功能以備切換的,這樣的狀況在LPC1114FN28接腳數較少(Low Pin Count)的封裝中格外明顯.
參閱手冊10.4的Table 168.可發現這次實驗中要連接LED的PIO1_0腳位除了可作為一般數位I/O外, 還能作為A/D類比轉換以及計數器使用. 因此在開始點滅LED前,必須指定該接腳作為一般數位I/O功能:

LPC_IOCON->R_PIO1_0 |= (1 << 0);    //GPIO function select, manual 8.4.29

而按鈕輸入的接腳PIO0_1在預設狀態下便已經是一般數位I/O功能, 此時可設定該接腳內部直接接上上拉電阻(Pull-up resistor), 在未有輸入的狀況下直接測得高位電位; 而透過與一按鈕與電阻串接至地, 可藉由按鈕按下時測得低電位.

 LPC_IOCON->PIO0_1 |= (1 << 4);     //Pull-up enable, manual 8.4.4

在設定完各接腳模式後, 接著需要設定訊號方向; 在手冊的12.3.2節提到有一組GPIO data direction register用來控制GPIO輸入輸出方向的切換,將所需設定腳位的register寫入1即為輸出, 反之0則為輸入.

LPC_GPIO0->DIR |= (1 << 0); //set PIO0_1 to be output
LPC_GPIO1->DIR &= ~(1 << 0);    //set PIO1_0 to be input

完成了接腳方向的設定後, 便可以對輸出腳位輸出高低電位的切換,以及從輸入腳位讀取外部電位資訊; 在此次實驗中的操作非常單純, 透過不斷讀取輸入接腳之按鈕狀態,直接反應在輸出接腳的LED上. 對於接腳資訊的讀取或寫入來自於GPIO data register, 其操作如下:

  LPC_GPIO1->DATA |= (1 << 0);  //write HIGH to PIO1_0
  LPC_GPIO1->DATA &= ~(1 << 0); //write LOW to PIO1_0
  LPC_GPIO0->DATA &= (1 << 1);  //check the state from PIO0_1

綜合以上的所有操作, 主程式簡短如下:
當PIO0_1的按鈕未被按下時, 由於內部已經被設定為Pull High組態, 因此讀取輸入為高電位,並將此狀態直接反應於接於PIO1_0接腳上的LED;反之, 在按鈕被按下時PIO0_1接地,讀取輸入為低電位,亦將此狀態反應於PIO1_0之LED上.

int main(void)
{
        volatile uint32_t count, count_max = 1000000; 
        pll_start(CRYSTAL, FREQUENCY);

        //generate the clock to I/O peripheral
        LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_IOCON;   

        //set PIO1_0 for GPIO function
        LPC_IOCON->R_PIO1_0 |= (1 << 0);    
        //set PIO0_1 with pull high 
        LPC_IOCON->PIO0_1 |= (1 << 4); 

        //set PIO1_0 to be output
        LPC_GPIO1->DIR |= (1 << 0); 
        //set PIO0_1 to be input
        LPC_GPIO0->DIR &= ~(1 << 1);   

        while (1)
        {
                //check the button state on PIO0_1
                if(LPC_GPIO0->DATA &= (1 << 1)){   
                    //turn on the LED on PIO1_0
                    LPC_GPIO1->DATA |= (1 << 0);    
                }else{
                    //turn down the LED
                    LPC_GPIO1->DATA &= ~(1 << 0);   
                }
        }
}

如果接線正常且程式運作順利, 應該在壓下按鍵時LED熄滅, 而在放開按鍵時LED啟動.
enter image description here

Sunday, June 1, 2014

麵包板上的ARM(LPC1114FN28 最簡電路)

每個有點年紀的台灣韌體工程師都不會忘記第一次在麵包版上插出8051電路時那如同初戀的感覺, 但現在已是2014年, 整個市場都在往ARM靠攏, 讓我們也歸順吧!

元件列表

  1. NXP LPC1114FN28 x 1 (ARM Cortex M0, Datasheet)
  2. 按鈕 x 2
  3. 電阻 330 Ω x 1
  4. 電阻 4.7k Ω x 2
  5. LED x 1

使用工具

  1. USB轉UART轉接線
  2. 3.3V位準電源

電路圖

LPC1114 Minimal Circuit

電路說明

  1. VDD需接上3.3V之電源, VSS需接地
  2. Pin 23為系統重置(reset)接腳, 此一接腳為低位準致能,因此需接一4.7k之上拉電阻至正電源, 以維持系統運作; 當需要重置系統時, 可透過一按鈕將此接腳接地.
  3. Pin 24為ISP(In System Programming)燒錄致能接腳,需接上4.7k之電阻串連一組按鈕接地;當此一接腳於晶片reset時處於低電位,將觸發ISP模式作用
  4. Pin 17為PIO1_8, 接上330之限流電阻與LED串接至地, 作為除錯用LED

LPC1114 on a Breadboard

Cable接線說明

使用 USB to 3.3V UART Cable 供電給微控制器,並進行序列通訊.cable有四個杜邦端子頭,VCC, GND, RX, TX;將VCC與GND接至微控制器之VDD與VSS, 將UART的RX接至微控制器的TX、TX接至RX。

軟體環境

使用Linux
- 下載”GNU Tools for ARM Embedded Processors” (Readme.txt)

$ tar -xf gcc-arm-none-eabi-4_8-2014q2-20140609-linux.tar.bz2 
$ sudo mv gcc-arm-none-eabi-4_8-2014q2 /opt/
$ echo "PATH=$PATH:/opt/gcc-arm-none-eabi-4_8-2014q2/bin" >> ~/.bashrc
  • 下載並編譯lpc21isp程式燒錄工具
$ svn checkout svn://svn.code.sf.net/p/lpc21isp/code/ lpc21isp-code
$ cd lpc21isp-code
$ make
$ mkdir -p $HOME/bin && cp lpc21isp $HOME/bin
  • 複製Zuph所修改製作之範例專案
$ git clone git://github.com/Zuph/lpc1114-blink
  • 編譯lpc1114-blink專案
$ cd lpc1114-blink
$ make
 
- 重複檢查電路接線是否正確; 完成後, 先按下RESET不放開, 再按下ISP按鍵, 爾後放開RESET, 再放開ISP按鍵, 進入ISP模式, 輸入下列指令進行燒錄
$ lpc21isp out/*.hex /dev/ttyUSB0 115200 12000 # FILE BAUDRATE CRYSTAL_HZ
  • 若操作正確無誤, 應該可看到LED以1.5Hz的頻率進行閃爍

參考資料

LPC1114FN28 with Open Source Tools