เมื่อมี Code ที่ทำงานซ้ำๆมากๆ ขอแนะนำให้ดูเรื่อง การเขียน Macro และการสร้า่ง function หรือ subroutine จะช่วยได้หากเป็นเรื่อง Macro ลองศึกษาได้จากที่นี่ครับ
http://www.cprogramming.com/tutorial/cpreprocessor.htmlในหัวข้อเรื่อง Macro โดย Macro ทำตัวเป็นการแทนที่คำสั่งลงไป เวลาใช้ก็ตั้งชื่อให้สื่อกับความหมายในการสร้าง Macro นั้นได้ก็จะทำให้ดูง่ายขึ้นบ้าง (หลีกเลี่ยงการตั้งชื่อแบบ MAC_01 , MAC_02 มันไม่สื่อ) และมักนิยมตั้งชื่อของ Macro ให้เป็นตัวใหญ่กัน
อย่างไรก็ตาม Macro จะยังไม่มีประสิทธิภาพนักกับเรื่องของการทำ Code (แค่เขียน Code สั้นลงบ้าง)
จากกรณี Code ข้างบน อาจเขียน Macro ทำเป็นตัวอย่างสักตัว เพื่อ Guide ให้นะ ที่เหลือลองคิดต่อเอา
#include <stdio.h>
#define PULSE_TRIGGER(pbit,ton,toff) { pbit=1; delay(ton); pbit=0; delay(toff); }
...
เวลาใช้ก็่เขียนเพียง
...
case 'A' :
PULSE_TRIGGER(DCTG,3500,1000); // PLUSE at DCTG
PULSE_TRIGGER(DCFU,3000,1000); // PLUSE at DCFU
PULSE_TRIGGER(DCTB,1000,3500); // PLUSE at DCTB
...
หากลองมาดูเรื่อง function หรือ subroutine ก็ลองอ่านได้จากที่นี่
http://en.wikipedia.org/wiki/Subroutine#C_and_C.2B.2B_examples http://www.thepmk.ac.th/kum/tc/programming_c_7.pdfการสร้า่ง subroutine หรือ function จะได้่ประสิทธิภาพกว่าการใ้ช้ Macro แค่วางแผนการรับส่ง ตัวแปรต่างๆให้เหมาะสม
และควรตั้งชื่อให้สื่อกับความหมายใน subroutine นั้นด้วยก็จะดีมาก (หลีกเลี่ยงการตั้งชื่อแบบ sub_01 , sub_02 เช่นกัน) และใน C มักนิยมใช้ Underscore (คือ _ แทน space ในชื่อ )
จริงๆ จาก Code ข้างบน delay ก็เป็น subroutine อย่างหนึ่ง
และจากกรณี Code ข้างบน อาจเขียน function ทำเป็นตัวอย่างสักตัวเพื่อ Guide ให้ ที่เหลือก็ลองคิดต่อเอาเองเช่นกัน
...
void pulse_trigger_DCTG(unsigned ton,unsigned toff)
{
DCTG = 1;
delay(ton);
DCTG = 0;
delay(toff);
}
...
เวลาใช้ก็่เขียนเพียง
...
case 'A' :
pulse_trigger_DCTG(3500,1000);
...
case 'B' :
pulse_trigger_DCTG(3500,1000);
...
case 'C' :
pulse_trigger_DCTG(3500,1000);
...
case 'D' :
pulse_trigger_DCTG(3500,1000);
...
case 'E' :
pulse_trigger_DCTG(3500,1000);
...
ค่าที่ส่งมันซ้ำๆ ก็อาจเขียนร่วมกันให้สั้นได้อีก ก็ใช้ Macro และ function ร่วมกันไปเช่น
...
#define FIX_PULSE_TRIGGER_DCTG { pulse_trigger_DCTG(3500,1000); }
...
case 'A' :
FIX_PULSE_TRIGGER_DCTG;
...
case 'B' :
FIX_PULSE_TRIGGER_DCTG;
...
case 'C' :
FIX_PULSE_TRIGGER_DCTG;
...
case 'D' :
FIX_PULSE_TRIGGER_DCTG;
...
case 'E' :
FIX_PULSE_TRIGGER_DCTG;
ทั้งนี้ก็สามารถใช้ทั้งสองอย่างร่วมด้วยช่วยกันได้ ก็จะได้ประโยชน์อย่างเต็มที่เลย
แนะนำเพิ่มอีกนิด สามารถ เพิ่ม function หรือ subroutine ได้อีก แม้จะมีการเรียกเพียงครั้งเดียวก็ตาม ทั้งนี้เพื่อเป็นการอธิบาย ให้สื่อความว่าทำอะไร ใน function นั้น (เพราะ function ย่อมจะต้องมีชื่อ) เช่้นการ Initialize เป็นต้น
ดังนั้น ใน main อาจให้ดูง่ายๆก็ทำได้โดยใส่ function เพิ่มเข้่าไป ก็เหมือนเป็นการ อธิบายว่า main นั้นทำอะไรบ้างแล้วเช่น
...
void initialize(void )
{
DCFU = 0;
DCFD = 0;
....
}
void process_motor_program_A(void )
{
....
}
void process_motor_program_a(void )
{
....
}
...
void main(void )
{
char a;
initialize();
while(1) {
a = _getkey();
switch (a) {
case 'A' :
process_motor_program_A();
break;
case 'a' :
process_motor_program_a();
break;
....
}
}
}
ลองศึกษาและแก้ไขด้วยตนเองนะครับ อยากให้ทำเองมากกว่านะ จะได้ประสบการณ์ที่ดี
แก้ไขด้วยตนเองได้ ตอบอาจารย์ได้ และน่าจะไม่ยากลำบากอะไร ในเรื่องย่อ Code นี้