best view IE mode 800x600 Text Size Medium

Home
แผนที่เว็บไซต์

 

 

 

บทความ

การเขียนโปรแกรมภาษาซี ด้วย CCS กับ PIC16F877 ให้พอร์ตเทเบิล
ตอน 1. การควบคุมพอร์ตของ PIC16F877

    ในการเขียนโปรแกรมควบคุมและใช้งานไมโครคอนโทรลเลอร์หลายคนคงปฏิเสธไม่ได้ว่าภาษาแอสเซมบลี(Assembly) เป็นภาษาที่มีประสิทธิภาพสูงสุดในการควบคุมการทำงานของไมโครคอนโทรลเลอร์ แต่ข้อเสียที่เห็นได้ชัดเจนคือ เราต้องผูกติดกับภาษานี้ไปพร้อมกับไมโครคอนโทรลเลอร์ตระกูลนั้นเช่น เขียนแอสเซมบลีบน PIC ไม่สามารถนำไปใช้งานได้บน mcs-51 เป็นต้น

    แต่มีอยู่ภาษาหนึ่งที่ศึกษาและเขียนเพียงครั้งเดียวแต่สามารถนำไปใช้งานได้บนไมโครคอนโทรลเลอร์อีกตระกูลหนึ่งได้ เพียงแก้ไขเล็กน้อยเท่านั้น โดยมีเงื่อนไขในการเขียนโค้ดครั้งแรกที่ต้องคำนึงถึงคือเรื่องของความสามารถในการย้ายข้ามระบบ(Portability)เป็นสำคัญนั้นคือภาษาซี(c language) ในบทความนี้จะเป็นการนำเสนอการเขียนโค้ดด้วยคอมไพเลอร์ CCS แล้วสามารถที่จะย้ายโค้ดไปทำงานบนคอมไพเลอร์ของตัวอื่นในตระกูล PIC ได้เช่นเดียวกัน

    พื้นฐานในการเขียนโปรแกรมให้พอร์ตเทเบิล เพื่อที่สามารถนำโค้ดที่ได้เขียนไว้แล้วไปใช้งานอื่นได้ต่อหรือพอร์ตไประบบอื่น โดยการแก้ไขใหม่อีกเพียงเล็กน้อยเท่านั้น มีหลักสำคัญหรือพื้นฐานเพียง 2 ข้อคือ

1. ใช้ไดเรกทีฟ #define หรือ typedef ในการกำหนดใช้งานตัวแปรและค่าคงที่
     เพื่อใช้ในการควบคุมค่าคงที่ต่าง ๆ รวมถึงชนิดและขนาดของตัวแปรที่แตกต่างกันของแต่ละคอมไพเลอร์

2. สร้างชุดคำสั่งใหม่ด้วยฟังก์ชัน ถ้าคำสั่งนั้นไม่ได้เป็นคำสั่งมาตรฐานของภาษาซี
     เพื่อใช้ในการรวบรวมชุดคำสั่งของคอมไพเลอร์นั้นให้อยู่ในโมดูลที่เราเขียนไว้ เมื่อมีการแก้ไขชุดคำสั่งทำให้ สามารถที่จะแก้ไขเพียงฟังก์ชันในโมดูลที่เราได้เขียนขึ้นมา

พอร์ตใช้งานของ PIC16F877

   ไมโครคอนโทรลเลอร์ PIC16F877 มีพอร์ตให้เราใช้งานได้ทั้งหมด 5 พอร์ตคือ

  1. พอร์ต A จำนวน 6 ช่อง(RA0-RA5) เน้นใช้งานเป็นพอร์ตอินพุตเอาต์พุตปกติและการแปลงสัญญาณ ADC
  2. พอร์ต B จำนวน 8 ช่อง(RB0-RB7) เน้นใช้งานเป็นพอร์ตที่เกี่ยวข้องกับการใช้งานอินเตอร์รัปต์
  3. พอร์ต C จำนวน 6 ช่อง(RC0-RC5) เน้นใช้งานเป็นพอร์ตที่เกี่ยวข้องกับตัวนับ/จับเวลาและการสื่อสาร
  4. พอร์ต D จำนวน 8 ช่อง(RD0-RD7) เน้นใช้งานเป็นพอร์ตอินพุตเอาต์พุตแบบขนาน
  5. พอร์ต E จำนวน 8 ช่อง(RE0-RE7) เน้นใช้งานเป็นพอร์ตแปลงสัญญาณ ADC และพอร์ตที่เกี่ยวข้องกับพอร์ต D

หมายเหตุ รายละเอียดและหน้าที่ของแต่ละขาของแต่ละพอร์ตดูได้จากคู่มือการใช้งานที่มากับบอร์ดทดลอง

การควบคุมพอร์ต PIC16F877 สำหรับ CCS

    ในการควบคุมพอร์ตของไมโครคอนโทรลเลอร์ตระกูล PIC จะต้องมีการกำหนดเงื่อนไขก่อนการใช้งานว่าต้องการให้ขาของพอร์ตที่จะใช้งานทำหน้าที่เป็นขาพอร์ตอินพุตหรือเอาต์พุต โดยการกำหนดค่าให้กับขาพอร์ตในรีจีสเตอร์ TRIS ก่อน จุดนี้สำคัญมาก เพราะถ้าไม่ระวังแล้วอาจทำให้ขาพอร์ตเสียหายได้

ถ้ากำหนดเป็นลอจิก "0" แสดงว่าต้องการให้ขาพอร์ตทำหน้าที่เป็นเอาต์พุต
ถ้ากำหนดเป็นลอจิก "1" แสดงว่าต้องการให้ขาพอร์ตทำหน้าที่เป็นอินพุต

คำสั่งกำหนดหน้าที่ของพอร์ต

set_tris_a (value) กำหนดหน้าที่ของพอร์ต A
set_tris_b (value) กำหนดหน้าที่ของพอร์ต B
set_tris_c (value) กำหนดหน้าที่ของพอร์ต C
set_tris_d (value) กำหนดหน้าที่ของพอร์ต D
set_tris_e (value) กำหนดหน้าที่ของพอร์ต E

การเขียนโค้ดกำหนดหน้าที่ของพอร์ตแสดงดังตัวอย่างข้างล่างนี้

SET_TRIS_B( 0x0F );   // B7,B6,B5,B4 ให้เป็นเอาต์พุต B3,B2,B1,B0 ให้เป็นอินพุต

จากตัวอย่างข้างต้นเป็นการกำหนดพอร์ต B ให้เป็นพอร์ตเอาต์พุต 4 บิตบนและอินพุต 4 บิตล่างหลังจากที่เรากำหนดหน้าที่ของขาพอร์ตแล้วเราจะควบคุมการทำงานของแต่ละพอร์ตตามหน้าที่ที่เราได้กำหนดไว้ดังนี้

ถ้ากำหนดเป็นอินพุต เราจะใช้ฟังก์ชัน input(pin) สำหรับการอ่านค่าของแต่ละขาของพอร์ต และใช้คำสั่ง input_a(),input_b(),..,input_e() สำหรับการอ่านค่าที่ละ 8 บิตหรืออ่านทั้งพอร์ต รูปแบบการใช้งานจะเป็นดังนี้

อินพุตค่าในระดับบิต(สำหรับอ่านเฉพาะเจาะจงไปที่ขาใดขาหนึ่ง)
value = input (pin) 

ตัวอย่างเช่น  
  value = input(PIN_B1)  // อ่านค่าที่ขาพอร์ต B ที่บิต 1 หรือ RB1

อิพุตค่าในระดับไบต์(สำหรับอ่านคราวละ 8 บิตหรือทั้งพอร์ต)
value = input_a()   
value = input_b()
value = input_c()
value = input_d()
value = input_e()

ตัวอย่างเช่น   set_tris_b(0xFF);   // B7,B6,B5,B4,B3,B2,B1,B0 ให้เป็นอินพุต
                    
value = input_b()   // อ่านค่าที่พอร์ต B

ถ้ากำหนดเป็นเอาต์พุต เราจะใช้ฟังก์ชัน output_bit (pin, value),output_float (pin),output_high (pin) ส่งค่าที่ละบิต และoutput_low (pin),output_a (value),output_b (value),...,output_e (value) ส่งค่าที่ละ 8 บิต รูปแบบการใช้งานจะเป็นดังนี้

เอาต์พุตค่าในระดับบิต

output_bit (pin, value)
ตัวอย่างเช่น              output_bit(PIN_B0, 0);             // กำหนดให้ขาพอร์ต B0 มีสถานะลอจิก "0"
 
output_float (pin)
ตัวอย่างเช่น              output_float(PIN_B0);             // กำหนดให้ขาพอร์ต B0 มีสถานะ high

output_high (pin)
ตัวอย่างเช่น              output_high(PIN_B0);              // กำหนดให้ขาพอร์ต B0 มีสถานะลอจิก high

output_low (pin)
ตัวอย่างเช่น              output_low(PIN_B0);                 // กำหนดให้ขาพอร์ต B0 มีสถานะลอจิก low

เอาต์พุตค่าในระดับไบต์
output_a (value)
output_b (value)
output_c (value)
output_d (value)
output_e (value)

ตัวอย่างเช่น              output_b(0xF0);

    หลังจากที่เรารู้เกี่ยวกับฟังก์ชันหรือชุดคำสั่งที่เกี่ยวข้องกับการควบคุมและใช้งานพอร์ตแล้ว เราสามารถที่จะเขียนโปรแกรมควบคุมขาพอร์ตของ PIC เพื่อให้พอร์ตเทเบิลได้โดยการสร้างฟังก์ชันที่เกี่ยวข้องกับอินพุตเอาต์พุตพอร์ตใหม่รวมทั้งการกำหนดชนิดของตัวแปรเพื่อการใช้งานดังนี้

//  กำหนดให้ bit แทนตัวแปรชนิด int1 ซึ่งมีการใช้งานใน CCS แต่อาจไม่มีในคอมไพเลอร์ตัวอื่น
typedef int1 bit;  

// สร้างฟังก์ชันควบคุมคำสั่งเฉพาะของคอมไพเลอร์ CCS
void delay_millisec(int n) {

    delay_ms(n);
}

void outportb_high(int pin) {

    switch(pin) {
        case 1: output_high(PIN_B1);
        break;
        case 2: output_high(PIN_B2);
        break;
        case 3: output_high(PIN_B3);
        break;
        case 4: output_high(PIN_B4);
        break;
        case 5: output_high(PIN_B5);
        break;
        case 6: output_high(PIN_B6);
        break;
     }
        delay_millisec(delay_time);
}

    ฟังก์ชันและตัวแปรที่พอร์ตเทเบิล ในตัวอย่างข้างต้นเราสามารถที่จะแก้ไขตัวแปรและฟังก์ชันที่เกี่ยวข้องกับเอาต์พุตพอร์ตได้ในส่วนของ outportb_high() และในส่วนของการหน่วงเวลาใน delay_millisec()

โปรแกรมตัวอย่าง ในบทนี้จะแสดงการทำงานของไฟวิ่งด้วย LED โดยเริ่มต้นการทำงานจากซ้ายไปขวาแล้วรอค่าที่รับเข้ามาจากขา RB7 และ RB0 ทำงานที่ลอจิกศูนย์ เพื่อสลับการวิ่งของไฟ LED จากซ้าย เป็นขวาหรือขวาเป็นซ้าย การทดลองนี้จะใช้บอร์ดทดลอง NX-877 (บอร์ดไมโครคอนโทรลเลอร์ PIC16F877)  เมนหลักของโปรแกรมแสดงดังนี้

void main(void) {
    int1 bit_chk;

    set_tris_B(0x81); // 10000001 set trisb RB0,RB7 input, RB1-RB6 output

    while(1) {
        if(!input(PIN_B0)) bit_chk = TRUE; // active low
        if(!input(PIN_B7)) bit_chk = FALSE; // active low

        if(bit_chk) {
               left_led();
        } else {
               right_led();
        }
    }
}

ผลการทดลองแสดงดังรูป

การต่อสายใช้งาน

ปุ่มควบคุมการแสดงผล ซ้ายขวาของ LED

ผลการทำงานของโปรแกรม

Home Page
>> หากมีข้อเสนอและแนะนำส่ง email มาได้ที่ support@appsofttech.com  ครับ

 

Home Page

best view IE mode 1024x768 Text Size Medium
ผู้จำหน่ายไมโครคอนโทรลเลอร์และอุปกรณ์อิเล็กทรอนิกส์ทุกประเภท
Copyright © 2005 Appsofttech Co., Ltd.


บริษัท แอพซอฟต์เทค จำกัด 19/6 หมู่ 6 หมู่บ้านเอกวัฒนา ซ.เพชรเกษม 53 ถนนเพชรเกษม แขวงบางแค เขตบางแค กรุงเทพฯ  10160 Tel: 0-2413-3985-6, Fax: 0-2413-3165(auto)
Hotline 081-4850870, 081-4316541

[ วิธีสั่งซื้อ | บริษัท | Term of use | Privacy Policy ]
 
Contact email: info@appsofttech.com  Designed by : : Appsofttech Co.,Ltd.