[ บทความ : ทดลอง C คอมไพเลอร์ ]

ทดลอง C คอมไพเลอร์

สวัสดีครับ บทความคราวนี้จะเป็นการทดลอง เขียนโปรแกรมขับ LED  แบบธรรมดาๆ นี่ล่ะครับ แต่ เราจะเอาโปรแกรม ไปทำการคอมไพล์  ด้วยตัวแปล ภาษา ที่ต่างๆ กัน ซึ่งในการทดสอบครั้งนี้  จะเป็นการดูที่ ไฟล์ .HEX ที่ C คอมไพเลอร์ สร้างขึ้น  และทดลองรันบนบอร์ด EXP 4 MCU ของ ETT และใช้ I/O จาก EXP 4 I/O Lab 1

เงื่อนไขทาง ฮาร์ดแวร์

1. ใช้ AT89C51 ทำงานที่ XTAL 11.0592 MHz
2. ใช้ I/O จาก EXP 4 I/O Lab1 (ส่วนที่ใช้เป็น LED 8 ดวง)

เงื่อนไขของซอฟท์แวร์

มี 2 ฟังก์ชัน คือ
my_delay(mxloops) เป็นฟังก์ชัน delay ที่กำหนด จำนวนค่าวนรอบได้ โดยที่ ลูปด้านใน จะใช้การวนรอบ 200 ครั้ง
main เป็นโปรแกรมหลัก ที่จะทำการส่ง ข้อมูลออกทาง P1 โดย ข้อมูลนั้น จะมี รูปแบบดังนี้
   00000000
   10000001
   01000010
   00100100
   00011000
   00100100
   01000010
   10000001

ตัวแปลภาษาซี

ผมเลือกใช้ C คอมไพเลอร์ 4 ตัว จาก 3 บริษัท คือ
1. Micro C51 V2.4 จาก www.dunfield.com
2. Micro C51 V3.21 จาก www.dunfield.com
3. Keil C51 V6.x (Eval 2KB) จาก www.keil.com
4. RIDE 51 V6.x (Eval 4KB) จาก www.raisonance.com

Micro-C51

มาดูไฟล์โปรแกรมของ Micro-C51 กันเลยครับ

/*
 * Filename : mled01.c
 * Compiler : Micro-C/51 V2.4 or V3.21
 * Hardware : EXP4 I/O LAB1 and EXP4 MCU
 *
 * Command  : cc51 mled01 -piomf m=t
 */
#include <8051reg.h>

#define uchar unsigned char

my_delay(mxloops)
int mxloops;
{
    int i,o;
    for (o=0; o<mxloops; o++){
        for (i=0; i<200; i++);
    }
}

main()
{
    uchar patt[8];
    uchar i;

    patt[0]=0x00;
    patt[1]=0x81;
    patt[2]=0x42;
    patt[3]=0x24;
    patt[4]=0x18;
    patt[5]=0x24;
    patt[6]=0x42;
    patt[7]=0x81;

    while(1) {
        for (i=0; i<8; i++) {
            P1 = patt[i];
            my_delay(50);
        }
    }
}

ไฟล์ HEX จาก Micro-C51 V2.4

:020000000132CB
:2000320075810712023F12001B80FBC82581C822C92581C97A0022D083D082CF2581F581FA
:20005200CFC082C08322CF2581F581CF22FBE493CB22FCE493FB740193CC22FAE493F9749B
:200072000193CA2229F9E5F03AFA227C00CB30E7011CCB2275F00030E70215F022FDE49320
:20009200FF7401934F7004A3A3800C740293B50510740393B5F00AE493C0E0740193C0E067
:2000B20022A3A3A3A380D7FEEBA4FD8EF0ECA4FCEB8EF0A4C5F02C2DC5F02211D38EF0ED54
:2000D20022C002C001AAF0F97E007D007F11C3E933F9EA33FADF08F5F0E9D001D00222EDF5
:2000F20033FDEE33FEC3ED9BF5F0EE9C40E0ADF0FED380DBBB000122C333C5F033C5F0DBB0
:20011200F722BB000122C3C5F013C5F013DBF722240280022401C5F03400C5F022C39402A9
:200132008003C39401C5F09400C5F0223134F4C5F0F4C5F02245F070220422319640248041
:200152001A3196401E7014801A3196400E7014800A3196500E800431AA6008E4F5F0223105
:20017200AA60F8E4F5F0042231AA40F780ED31AA40F170E780ED31AA40E170E780DD31AAA2
:2001920050E180D7C39BC5F09C20E70720D207C345F02220D2F9D322C5F0C39C7003E5F0B9
:2001B2009B220581058105810581E4F5F078FD12003DF608A6F078FD12003DE60886F07897
:2001D200F712003D860308860412014D701902023678FD12003DE60886F012012618F60812
:2001F200A6F012013480CFE4F5F078FB12003DF608A6F078FB12003DE60886F07BC87C00BD
:2002120012014D701902023378FB12003DE60886F012012618F608A6F012013480D5020201
:200232001A0201E31581158115811581227F09120049E4F5F079F6120042120076E4F774EC
:200252000175F00079F61200421200767481F7740275F00079F61200421200767442F774A8
:200272000375F00079F61200421200767424F7740475F00079F61200421200767418F7740B
:200292000575F00079F61200421200767424F7740675F00079F61200421200767442F774BD
:2002B2000775F00079F61200421200767481F7740175F00045F0700302031CE478FE12007A
:2002D2003DF678FE12003DE675F0007B087C0012017A700C02031978FE12003DE60680E290
:2002F20078FE12003DE679F612004275F000120076E7F590743275F000C0E0C0F01201B403
:0F031200158115810202E90202C17FF70200582E
:00000001FF
ไฟล์ HEX จาก Micro-C51 V3.21

:020000000132CB
:2000320075811412023D12001B80FBC82581C822C92581C97A0022D083D082CF2581F581EF
:20005200CFC082C08322CF2581F581CF22FBE493CB22FCE493FB740193CC22FAE493F9749B
:200072000193CA2229F9E5F03AFA227C00CB30E7011CCB2275F00030E70215F022FDE49320
:20009200FF7401934F7004A3A3800C740293B50510740393B5F00AE493C0E0740193C0E067
:2000B20022A3A3A3A380D7FEEBA4FD8EF0ECA4FCEB8EF0A4C5F02C2DC5F02211D38EF0ED54
:2000D20022C002C001AAF0F97E007D007F11C3E933F9EA33FADF08F5F0E9D001D00222EDF5
:2000F20033FDEE33FEC3ED9BF5F0EE9C40E0ADF0FED380DBBB000122C333C5F033C5F0DBB0
:20011200F722BB000122C3C5F013C5F013DBF722240280022401C5F03400C5F022C39402A9
:200132008003C39401C5F09400C5F0223134F4C5F0F4C5F02245F070220422319640248041
:200152001A3196401E7014801A3196400E7014800A3196500E800431AA6008E4F5F0223105
:20017200AA60F8E4F5F0042231AA40F780ED31AA40F170E780ED31AA40E170E780DD31AAA2
:2001920050E180D7C39BC5F09C20E70720D207C345F02220D2F9D322C5F0C39C7003E5F0B9
:2001B2009B220581058105810581E4F5F078FD12003DF608A6F078FD12003DE60886F07897
:2001D200F712003D860308860412014D7003020234801378FD12003DE60886F01201261895
:2001F200F608A6F080D0E4F5F078FB12003DF608A6F078FB12003DE60886F07BC87C0012F3
:20021200014D7003020231801378FB12003DE60886F012012618F608A6F080D602021B02C1
:2002320001E51581158115811581227F09120049E4F5F079F6120042120076E4F774017590
:20025200F00079F61200421200767481F7740275F00079F61200421200767442F7740375A6
:20027200F00079F61200421200767424F7740475F00079F61200421200767418F774057509
:20029200F00079F61200421200767424F7740675F00079F61200421200767442F7740775BB
:2002B200F00079F61200421200767481F7E478FE12003DF678FE12003DE675F0007B087C57
:2002D2000012017A700302030D800978FE12003D06E680E078FE12003DE679F6120042757D
:2002F200F000120076E7F590743275F000C0E0C0F01201B4158115810202DD0202BF7FF7A0
:030312000200588E
:00000001FF

Keil C51 V6.x

ไฟล์สำหรับ Keil C51 V6.x ในการคอมไพล์นั้น ผมเลือก ใช้ MCU แบบ 8051 และเลือกระบบหน่วยความจำเป็น SMALL กับเลือก 2K funtion and 64K program  ดังรูป ต่อไปนี้

//
// Filename : KLed01.c
// Compiler : Keil C51 V6.x
// Hardware : EXP4 IO LAB1 & EXP4 MCU
// 
#include <reg51.h> // or reg52.h for AT89S8252/AT89C52

#define uchar unsigned char

void my_delay(int mxloops) 
{
    int i,o;
        for (o=0; o<mxloops; o++) {
            for (i=0; i<200; i++);
	}
}

void main()
{
    uchar patt[8];
    uchar i;

    patt[0]=0x00;
    patt[1]=0x81;
    patt[2]=0x42;
    patt[3]=0x24;
    patt[4]=0x18;
    patt[5]=0x24;
    patt[6]=0x42;
    patt[7]=0x81;

    while(1) {
        for (i=0; i<8; i++) {
            P1 = patt[i];
            my_delay(200);
        }
    }
}

ไฟล์ HEX ที่ได้จาก Keil-C51 V6.x

:03000000020057A4
:10000300E4F508750981750A42750B24750C18759A
:100013000D24750E42750F81E4F9740829F8E6F58D
:0E002300907FC87E0012003109B908EE80EA15
:10003100E4FDFCC3ED9FEE6480F8EC6480985015FC
:10004100E4FBFA0BBB00010AEB64C84A70F50DBD75
:0600510000010C80DE221C
:0C005700787FE4F6D8FD75810F020003ED
:00000001FF

RIDE 51 V6.x 

ในการคอมไพล์ด้วย RIDE 51 ผมกำหนด คอนฟิก ดังนี้

//
// Filename : rLed01.c
// Compiler : RIDE 51 V6.x
// Hardware : EXP4 IO LAB1 & EXP4 MCU
// 
#include <reg51.h> // or reg52.h for AT89S8252/AT89C52

#define uchar unsigned char

void my_delay(int mxloops) 
{
    int i,o;
        for (o=0; o<mxloops; o++) {
            for (i=0; i<200; i++);
	}
}

void main()
{
    uchar patt[8];
    uchar i;

    patt[0]=0x00;
    patt[1]=0x81;
    patt[2]=0x42;
    patt[3]=0x24;
    patt[4]=0x18;
    patt[5]=0x24;
    patt[6]=0x42;
    patt[7]=0x81;

    while(1) {
        for (i=0; i<8; i++) {
            P1 = patt[i];
            my_delay(200);
        }
    }
}

ไฟล์ HEX ที่ได้จาก RIDE 51

:03000000020003F8
:0F000300758112E4787FF6D8FD75A0FF02003CEE
:10001200E4F510F5118EF0B2F7E5106480B5F00545
:07002200E511B507005012C3
:1000290078C8D8FEE4FC7DC80511E51170E005101B
:0300390080DC2246
:10003C00750800750981750A42750B24750C1875C5
:08004C000D24750E42750F81B1
:020054007B002F
:10005600EB2408F88690E4FE7FC811120BBB08F06B
:0200660080EC2C
:00000001FF

สรุป

จาก HEX File ที่ได้จาก Micro-C51, Keil C51  และ RIDE 51 ผมก็ทำการแปลงไฟล์ดังกล่าวให้เป็น binary file (ไฟล์เก็บรหัสฐานสอง) จะพบว่า Keil C51 มีขนาดเล็กที่สุด (99 Bytes) , RIDE 51 (104 Bytes) ใกล้เคียงกับ Keil C51 (ใหญ่กว่านิดหน่อย)  แต่ Micro-C51 (V2.4 = 801 Bytes และ V3.21 = 591 Bytes) นั้น จะมีขนาดที่ใหญ่ กว่าตัวแปลภาษา จากค่ายทั้งสอง (V2.4 จะ optimize สู้ v3.21 ไม่ได้) แต่ว่า ราคาของ Micro-C51 นั้น ถูก ที่สุด คือ ประมาณ $100  ส่วน RIDE 51 ตัวทดลองนั้น สามารถคอมไพล์ โปรแกรมได้ 4KB  ซึ่งก็เพียงพอสำหรับ งานแบบตัวแปรจำนวนเต็ม และไม่ซับซ้อนมากนัก ส่วน Keil C51 นั้น ให้คอมไพล์ได้เพียง 2KB ซึ่ง ก็เหมาะกับพวก AT89C2051 หรือ โปรแกรมขนาดเล็กๆ ...

    -----------------------------------------------------------
    Compiler                 HEX file size.     Binary files
                             (Bytes)            (Bytes)
    -----------------------------------------------------------
    Micro C51 V2.4           1,844               801
    Micro C51 V3.21          1,820               591
    Keil C51 V6.x              315                99
    RIDE 51 V6.x               364               104
    -----------------------------------------------------------

หมายเหตุ

จากการทดลองพบว่า ผมไม่สามารถใช้ค่า my_delay() เหมือนกันได้ ทั้งนี้เพราะ ถ้าผมใช้ my_delay(50) เหมือนกันทั้งหมด ไฟล์ที่ได้ จาก Keil C51 และ RIDE 51 นั้น จะทำงานเร็วมากจนดูไม่ทัน ดังนั้น ใน Micro-C51 ผมใช้ my_delay(50) ใน Keil C51 และ RIDE 51 ผมใช้ my_delay(200) แต่จากการทดลองพบว่า my_delay(200) ที่ได้จาก RIDE 51 จะทำงานเร็วกว่าจาก Keil C51

การทดสอบนี้เป็นการทดสอบ แบบดูไฟล์ BIN จาก ตัวอย่างโปรแกรม ที่ติดต่อกับ P1 เท่านั้น  ดังนั้น ผลลัพธ์ที่ได้ นั้น ไม่อาจจะเป็น การบ่งบอก ถึงประสิทธิภาพของตัวแปลภาษาได้ทั้งหมด  เพราะ ตัวแปลภาษาซี ของ Keil และ Raisonace นั้น จะสามารถใช้ตัวแปรแบบ float ได้ และยังมีความสามารถที่มากมายกว่าที่ทำการทดลองในครั้งนี้


เขียนโดย : ศุภชัย บุศราทิจ
Author : Supachai Budsaratij
วันที่ทำการปรับปรุง : ๑๔ ต.ค. ๒๕๔๔