[ บทความ : ทดลอง 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
ไฟล์ HEX จาก Micro-C51 V3.21: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
: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 ได้ และยังมีความสามารถที่มากมายกว่าที่ทำการทดลองในครั้งนี้