MPLAB® XC8 Getting Started Guide
MPLAB® XC8 Getting Started Guide
เราจะมาศึกษาการใช้ MPLABX IDE กับ XC8 Compiler ในการพัฒนางานด้านไมโครคอนโทรลเลอร์ของค่ายไมโครชิพ (Microchip) กันครับ เริ่มแรก เรามาทำความรู้จักกันก่อน ว่าทำไมต้องเป็น XC8 Compiler กันครับ
XC8 Compiler คือ โปรแกรมสำหรับแปลงโค๊ดภาษาซี ให้กลายเป็นภาษาเครื่อง (Mahcine Code) ที่ทางไมโครชิพพัฒนาให้มาทดแทน HI-TECH C Compiler PIC10/12/16 และ HI-TECH C Compiler PIC18 ซึ่งทั้งสองตัวนี้ ทางไมโครชิพได้หยุดพัฒนาแล้ว และได้ให้โปรแกรมเมอร์หันไปใช้ XC8 Compiler แทน ซึ่งเจ้า XC8 Compiler นี้ครอบคลุม 8-bit ไมโครคอนโทรลเลอร์ทั้งหมด (ถ้าเป็น 16-bit และ 32-bit ไมโครคอนโทรลเลอร์ ก็จะใช้ XC16 และ XC32 ตามลำดับ)
ปัจจุบัน XC8 เวอร์ชั่น 1.20 ถูกปล่อยออกมาเมื่อ July 2013 ในขณะที่ HI-TECH C ที่เป็น PIC10/12/16 เวอร์ชั่นล่าสุดนั้นหยุดอยู่ที่ 9.83
และปล่อยออกมาเมื่อ September 2011 และ HI-TECH C ที่เป็น PIC18 ก็หยุดอยู่ที่เวอร์ชั่น 9.80 ออกมาเมื่อ October 2011
เอาหล่ะเรามาเริ่มต้นกับ XC8 กันดีกว่า แน่นอน เราจะต้องมีโปรแกรม MPLABX IDE และ XC8 Compiler ทั้งสองอย่างนี้ก่อน ซึุ่งทั้งสองอย่างนี้ ฟรี ครับ เพียงแต่ XC8 ฟรี อย่างมีเงื่อนไข ก็คือ เราสามารถใช้ XC8 Compiler ให้โหมด Pro mode ได้ 60 วัน ซึ่งหลังจาก 60 วันแล้ว โปรแกรมจะถูกเปลี่ยนให้เป็น Free mode อัตโนมัติ ซึ่งความแตกต่างของ Pro Mode และ Free Mode นั้น ก็แตกต่างกันเพียงการ Optimize code เท่านั้น ซึ่งการ Optimize code นั้น จะทำให้โค๊ดจากภาษาซี ถึงแปลงเป็นภาษาเครื่อง มีขนาดแตกต่างกัน
เริ่มจากดาวน์โหลด MPLABX IDE หน้าดาวน์โหลด
ต่อด้วยดาวน์โหลด XC8 Compiler หน้าดาวน์โหลด
ทำการติดตั้ง MPLABX IDE ก่อนครับ จากนั้นให้ทำการติดตั้ง XC8 Compiler
ถ้าติดตั้งเสร็จแล้ว เราจะมาเริ่มต้นสร้างโปรเจคกัน จนกระทั่งถึงขั้นตอนการเบิร์นภาษาเครื่องเข้าไปที่ตัวไมโครฯ จริงๆ แล้วเราอาจจะแบ่งขั้นตอนได้เป็น 8 ขั้นตอน ดังนี้
ขั้นตอนที่ 1 สร้างชนิดของโปรเจค.
ขั้นตอนที่ 2 เลือกเบอร์ไมโครคอนโทรลเลอร์.
ขั้นตอนที่ 3 เลือกเครื่องสำหรับอัดภาษาเครื่องลงไปที่ตัวไมโครคอนโทรลเลอร์.
ขั้นตอนที่ 4 เลือกตัแปลงภาษา หรือ Compiler.
ขั้นตอนที่ 5 ตั้งชื่อโปรเจค กำหนดที่อยู่ของโปรเจค.
ขั้นตอนที่ 6 กำหนด Configuration bit ที่เหมาะสมกับบอร์ดไมโครคอนโทรเลอร์ของเรา.
ขั้นตอนที่ 7 เขียนโค๊ด และ Build Project.
ขั้นตอนที่ 8 อัดภาษาเครื่องลงไมโครคอนโทรลเลอร์ และดูผลลัพธ์.
ซึ่งเราจะมาดูแต่ละขั้นตอนกันครับ
ขั้นตอนที่ 1 สร้างชนิดของโปรเจค.
เมื่อเราเปิดโปรแกรม MPLABX ขึ้นมา ให้คลิกที่เมนู File->New Project.. ที่ส่วน Categories: ให้เลือก Microchip Embedded แล้่วเลือก Projects: เป็น Standalone Project
เรียบร้อยแล้วให้คลิก Next เพื่อไปขั้นตอนต่อไป
ขั้นตอนที่ 2 เลือกเบอร์ไมโครคอนโทรลเลอร์.
เราสามารถเลือกเบอร์ไมโครคอนโทรลเลอร์ตามเบอร์ที่เราต้องการ ด้วยการพิมพ์ชื่อเบอร์ไมโครคอนโทรลลเลอร์ ที่เราต้องการ และจะต้องเป็นเบอร์ที่เรามี Compiler ได้รองรับแล้ว
ในที่นี้ ผมต้องการใช้ PIC18F458 ซึ่ง XC8 Compiler รองรับอยู่แล้ว
ขั้นตอนที่ 3 เลือกเครื่องสำหรับอัดภาษาเครื่องลงไปที่ตัวไมโครคอนโทรลเลอร์.
ในขั้นตอนนี้ เราต้องเลือกชนิดของเครื่องอัดโปรแกรม บางทีเราก็เรียก ตัวโปรแกรม ซึ่งถ้าเป็นเครื่องโปรแกรมทางฝั่งค่ายไมโครชิพ ก็จะมี Pickit2, Pickit3, ICD2 (เลิกผลิตแล้ว) , ICD3 , RealICE เป็นต้น ซึ่งแต่ละตัวก็จะมีความสามารถที่ต่างกัน เราต้องเลือกตัวโปรแกรมให้ตรงกับที่เรามีอยู่ บางท่านอาจจะมีตัวโปรแกรม แบบชนิดเลียนแบบ เช่น Pickit3 clone ก็สามารถใช้ได้เหมือนกัน ถ้าเราต่อเอาไว้เรียบร้อยแล้ว โปรแกรม MPLABX จะดึง Serial number ของเครื่องโปรแกรมมาแสดงไว้เลย อย่าเช่น ผมมี Pickit2 แบบทำเอง ต่อไว้อยู่แล้ว เขาก็จะแสดง Serial number ออกมาแปลกๆ แต่ ก็ไม่เป็นไร ขอให้ใช้ได้ก็พอ
ขั้นตอนที่ 4 เลือกตัแปลงภาษา หรือ Compiler.
ในขั้นตอนนี้ เราต้องเลือกตัวแปลภาษา หรือ Compiler ที่เราต้องการจะใช้ในโปรเจคนี้ของเรา โปรแกรม MPLABX จะแสดง Compiler ที่เคยติดตั้งไว้แล้ว ที่อยู่ภายในเครื่องของเรา ที่เป็น Compiler ของค่ายไมโครชิพ แสดงออกมาให้เห็นทั้งหมด ซึ่งเราสามารถเลือก Compiler ที่เหมาะสมได้ ในที่นี้ ผมกำลังจะเขียนโปรแกรมลง PIC18F458 ซึ่งเจ้า XC8 ก็สามารถที่จะรองรับได้ ดังนั้้น ผมจึงคลิกเลือก XC8 เพื่อเป็น Compiler สำหรับโปรเจคนี้
ขั้นตอนที่ 5 ตั้งชื่อโปรเจค กำหนดที่อยู่ของโปรเจค.
ขั้นตอนนี้ ก็ไม่มีอะไรมาก แค่ตั้งชื่อโปรเจคของเรา ซึ่งเขาจะแสดงที่เก็บไฟล์โปรเจค และซอร์สโค๊ดของเรา ในกรณีที่มีหลายโปรเจคอยู่ก่อนหน้านี้ ให้เราคลิกเลือก Set as main project เพื่อให้เลือกโปรเจคใหม่ที่เรากำลังสร้างนี้เป็น main project ด้วย
ขั้นตอนที่ 6 กำหนด Configuration bit ที่เหมาะสมกับบอร์ดไมโครคอนโทรเลอร์ของเรา.
มาถึงขั้นตอนนี้ ต้องบอกว่าปฏิเสธไม่ได้เลย ที่จะไม่ดูดาต้าชีท เพราะการกำหนด Configuration bit นั้น จะต้องอ้างอิงจากดาต้าชีทของแต่ละเบอร์ไมโครคอนโทรลเลอร์ และความต้องการของผู้ออกแบบวงจรการทำงาน เช่น
ผมอยากใช้ CRYSTAL OSCILLATOR ที่มีค่า 10MHz เป็นตัวสร้างสัญญาณนาฬิกาของระบบ และไม่ต้องการให้ Watchdog timer ทำงานตรวจสอบการทำงานไมโครคอนโทรลเลอร์ตลอดเวลา และต้องการตรวจสอบแรงดันไฟเลี้ยง ถ้าต่ำกว่า 2.7V ให้ไมโครคอนโทรลเลอร์เข้าสภาวะรีเซต และปิดการรีเซตหากมีการใช้ stack เกิน ผมจะต้องตั้งค่า configuration bit ซึ่งในโปรแกรม MPLABX ได้เตรียมเครื่องมือสำหรับตั้งค่า Configuration bit ไว้เแล้ว คลิกที่เมนู Window -> PIC memory views -> Configuration bits
จะปรากฏหน้าต่างสำหรับตั้งค่า Configuration bit สำหรับเบอร์ PIC18F458 (ซึ่งถ้าเรากำหนดเป็นเบอร์อื่น เราก็อาจจะได้หน้าต่างไม่เหมือนกัน ขึ้นอยู่กับว่า อยู่ Family ใด) ดังนี้
เมื่อกำหนดเสร็จแล้ว ให้คลิก Generate Source Code to Output เราจะได้โค๊ดสำหรับการตั้งค่า Configuration bit เอาไว้ copy ไปไว้ใน source code ก่อนเข้า main function
ขั้นตอนที่ 7 เขียนโค๊ด และ Build Project.
ขั้นตอนนี้ เป็นการเพิ่ม source code เข้าไปในโปรเจค ในที่นี้ เราจะทดสอบด้วยโค๊ดตัวอย่างง่ายๆ ที่เขียนด้วยภาษาซี เข้าไปในโปรเจค ให้คลิกขวาที่ Source File ภายใต้ขื่อโปรเจคของเรา แล้วเลือก New->C Main file.. แล้วตั้งชื่อไฟล์ของเราชื่อ main (จริงๆ ตั้งชื่ออะไรก็ได้) เราจะได้โค๊ดเริ่มต้่นสำหรับ Main file
จากนั้นให้ copy configuration bit โค๊ด ที่เราได้จากขั้นตอนที่แล้่วมาใส่เข้าไปในโค๊ดนี้ด้วย จากนั้นให้เพิ่ม #define _XTAL_FREQ 10000000 เพื่อให้ _delay_ms() ทำงานได้อย่างถูกต้อง (ตรงนี้ เดี๋ยวค่อยว่ากันอีกที แต่ ให้กำหนดตามนี้ไปก่อน) และให้เพิ่ม delay_ms ฟังก์ชั่นเข้าไปอีกหน่อย
void delay_ms(unsigned int ms)
{
while(ms--){
__delay_ms(1);
}
}
จะได้โค๊ดทั้งหมดดังนี้
/*
* File: main.c
* Author: www.123microcontroller.com
*
* Created on December 27, 2013, 2:46 PM
*/
#define _XTAL_FREQ 10000000
#include <stdio.h>
#include <stdlib.h>
// PIC18F458 Configuration Bit Settings
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1H
#pragma config OSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config OSCS = OFF // Oscillator System Clock Switch Enable bit (Oscillator system clock switch option is disabled (main oscillator is source))
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON // Brown-out Reset Enable bit (Brown-out Reset enabled)
#pragma config BORV = 27 // Brown-out Reset Voltage bits (VBOR set to 2.7V)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 128 // Watchdog Timer Postscale Select bits (1:128)
// CONFIG4L
#pragma config STVR = OFF // Stack Full/Underflow Reset Enable bit (Stack Full/Underflow will not cause Reset)
#pragma config LVP = OFF // Low-Voltage ICSP Enable bit (Low-Voltage ICSP disabled)
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000200-001FFFh) not code protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000200-001FFFh) not write protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000200-001FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from Table Reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from Table Reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from Table Reads executed in other blocks)
void delay_ms(unsigned int ms)
{
while(ms--){
__delay_ms(1);
}
}
/*/
*
*/
int main(int argc, char** argv) {
TRISB = 0x00;
PORTB = 0x00;
while(1){
PORTB ^= 0x01;
delay_ms(500);
}
return (EXIT_SUCCESS);
}
ขั้นตอนที่ 8 อัดภาษาเครื่องลงไมโครคอนโทรลเลอร์ และดูผลลัพธ์.
เมื่อทุกอย่างเรียบร้อยแล้ว ให้ทำการ Build Project ดูครับ หากไม่มีอะไรผิดพลาด โปรแกรมจะแสดงข้อมความการ Compile source code และแสดงผลลัพธ์ว่า สำเร็จหรือไม่ หากเสร็จ จะแสดงข้อความฺ "BUILD SUCCESSFUL"
ขั้นตอนต่อมา เราจะทำการอัดไฟล์ที่ได้จากการ Build Project ซึ่งเราจะได้ hex file อัดลงไปบนไมโครคอนโทรลเลอร์ ในขั้นตอนนี้ เราจะต้องต่อเครื่องโปรแกรมของเรา กับ บอร์ดไมโครคอนโทรลเลอร์ของเรา หากเป็นบอร์ดสำเร็จรูปที่ขายอยู่ทั่วไป ผู้ผลิตมักจะทำช่องสำหรับเชื่อมต่อระหว่างบอร์ดไมโครคอนโทรลเลอร์ กับ เครื่องโปรแกรมไว้อยู่แล้ว ให้อ้างอิงตามคู่มือที่ผู้ผลิตบอร์ดแนะนำไว้ หากเป็นบอร์ดที่เราทำขึ้นมาเอง ก็คงต้องอาศัยดาต้าชีท เรื่อง In-Circuit Serial Programming เพิ่มเติม หากเราต่อวงจรสำหรับโปรแกรมเรียบร้อยแล้ว ให้กดปุ่ม Build and Run โปรแกรม MPLABX จะมองหาไฟล์ hex แล้วส่งผ่านเครื่องโปรแกรมลงสู่บอร์ดไมโครคอนโทรลเลอร์ของเรา สังเกตลหลอด LED ที่เราต่ออยู่บนขา PB0
วงจรที่แสดงนี้ ไม่ได้แสดงส่วนที่ต่อกับ PICKIT2 ในการโปรแกรมโค๊ดเข้าไมโครคอนโทรลเลอร์ ในการต่อวงจรจริง ผมต่อ Crystal Oscillator 20MHz เข้าไปที่ตัวไมโครฯ ที่ขา 13,14 แต่ในการ simulation ในโปรแกรมจำลอง Proteus ไม่จำเป็นต้องต่อนะครับ แต่ให้ไปกำหนดค่า Crystal ใน Properties ของ PIC18F458 เลย
เรียบเรียงจาก MPLABX XC8 Getting Started Guide