วันพุธที่ 27 พฤศจิกายน พ.ศ. 2562

7-segmentCC 1 digit

void main()
{
     char segment[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
     int i=0;
     TRISC=0;
     PORTC=segment[0];
     while(1)
     {
           delay_ms(500);
           i=i+1;
           if(i==10)i=0;
           PORTC=segment[i];
     }
}

ลูกเต๋า


void main()
{
     unsigned char dice[]={0x08,0x22,0x2A,0x55,0x5D,0x77};
     unsigned char i;
     TRISC=0;
     TRISB=0x01;
     PORTC=0;
     while(1)
     {
            if(PORTB.F0==0)
            {
                    PORTC=dice[i];
                    delay_ms(3000);
                    PORTC=0;
            }
            i++;
            if(i>5)i=0;
     }
}


หน้าจอสกอบอร์ด

#define digit1 PORTB.F5
#define digit2 PORTB.F6
#define digit3 PORTB.F7

unsigned char segment[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char i,j;

void interrupt()
{
     if(INTCON.INT0IF==1)
     {
            i++;
            if(i>9)i=0;
            INTCON.INT0IF=0;
     }
     if(INTCON3.INT1IF==1)
     {
            j++;
            if(j>9)j=0;
            INTCON3.INT1IF=0;
     }
}

void main()
{
   TRISB=0x03;
   TRISC=0;
   INTCON.INT0IE=1;
   INTCON.INT0IF=0;
   INTCON2.INTEDG0=0;
   INTCON3.INT1IE=1;
   INTCON3.INT1IF=0;
   INTCON2.INTEDG1=0;
   INTCON.GIE=1;
   while(1)
   {
           digit1=0;digit2=1;digit3=1;
           PORTC=segment[i];
           delay_ms(25);
           digit1=1;digit2=0;digit3=1;
           PORTC=~0x3F;
           delay_ms(25);
           digit1=1;digit2=1;digit3=0;
           PORTC=segment[j];
           delay_ms(25);
    }
}






โปรแกรมสวิตซ์กดติด-ปล่อยดับ

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

ขั้นตอนที่ 1

 ประกอบวงจรตามรูปด้านล่าง ลงในโปรแกรม Proteus ครับ



คำสั่งที่ใช้ในการโปรแกรม

while()  เป็นคำสั่งทำงานซ้ำแบบมีเงื่อนไขครับ ซึ่งจะทำงานวนซ้ำไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ

output_x(...)   เป็นคำสั่งส่งข้อมูลออกทางเอาต์พุตในพอร์อตที่ต้องการตามค่าที่กำหนด เช่น output_b(0x01);

delay_ms(...)  เป็นคำสั่งหน่วงเวลา เช่น delay_ms(500); โปรแกรมจะหน่วงเวลา 500ms ซึ่งค่านี้เราสามารถเปลี่ยนแปลงได้ตามความต้องการครับ

set_tris_x()  เป็นคำสั่งกำหนดพอร์ตใช้งานให้พอร์ตอินพุต หรือเอาต์พุต โดยการกำหนดค่าให้กับฟังก์ชัน set_tris_x() เช่น set_tris_b(0x00); , set_tris_a(0xff);


value = input() เป็นคำสั่งอ่านข้อมูลจากพอร์ตอินพุตที่ต้องการ เช่น a=!input(pin_a0);

output_bit()  เป็นคำสั่งส่งข้อมูลออกทางเอาต์พุตในระดับบิต เช่น output_bit(pin_b0,a);
 

ขั้นตอนที่ 2

เริ่มเขียนโปรแกรมกันเลยครับ



#include <16F84A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT
#use fast_io(A)
#use fast_io(B)


int1 a;                                      //  คำสั่งประกาศตัวแปร a เป็นเลขจำนวนเต็มขนาน 1 บิต

void main()

{
  set_tris_a(0xff);                        //  คำสั่งกำหนดพอร์ต A เป็นพอร์ตอินพุตทั้งหมด
  set_tris_b(0x00);                      //  คำสั่งกำหนดพอร์ต B ให้เป็นพอร์ตเอาต์พุตทั้งหมด

  output_b(0b00000000);            //  คำสั่งเคลียร์พอร์ต B ให้เป็น 0 ทุกบิต
  
  while(true)                              //  คำสั่งวนซ้ำแบบมีเงื่อนไข
        {
          a=!input(pin_a0);            //  คำสั่งอ่านข้อมูลจากพอร์ตอินพุต ขา a0
          output_bit(pin_b0,a);       //  คำสั่งส่งข้อมูลออกทางเอาต์พุตขนาด 1 บิต
        }                                      //  โดยนำค่า a ส่งออกที่ขา b0
}






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

  •    เมื่อยังไม่มีการกดสวิตซ์
           input(pin_a0) มีค่าเป็นลอจิก 1 เมื่อใส่เครื่องหมายนิเสธ "!" เข้าไปจะมีการกลับสถานะข้อมูลจากลอจิก 1 เป็นลอจิก 0 (!input(pin_a0) มีค่าเป็นลอจิก 0) ดังนั้น ค่า a = 0 เมื่อนำค่า a ส่งออกไปยังพอร์ตเอาต์พุตขา b0 LED1 จึงยังไม่ติด
  •   เมื่อมีการกดสวิตซ์ 
          input(pin_a0) มีค่าเป็นลอจิก 0 เมื่อใส่เครื่องหมายนิเสธ "!" เข้าไปจะมีการกลับสถานะข้อมูลจากลอจิก 0 เป็นลอจิก 1 (!input(pin_a0) มีค่าเป็นลอจิก 1) ดังนั้น ค่า a = 1 เมื่อนำค่า a ส่งออกไปยังพอร์ตเอาต์พุตขา b0 LED1 จึงติด


        หรือถ้าหากต้องการให้ LED1 ทำงานเป็นตรงกันข้าม คือ กดดับ-ปล่อยติด เราก็สามารถที่จะแก้โปรแกรมที่บรรทัด a=!input(pin_a0); ให้เป็น a=input(pin_a0); ได้เช่นกันครับ

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


Home work

งานที่ 2


โปรแกรมไฟกระพริบสลับกัน LED 2 ดวง

  บทความที่แล้วเราทำโปรแกรม โปรแกรมไฟกระพริบ LED 2 ดวง กันไปแล้วโดย LED ติดดับพร้อมกันไม่ยากอย่างที่คิดเลยใช่มั๊ยล่ะครับ ทีนี้เรามาเขียนโปรแกรมให้ LED ติดดับสลับกันบ้างครับ

ขั้นตอนที่ 1

 ประกอบวงจรตามรูปด้านล่าง ลงในโปรแกรม Proteus ครับ



คำสั่งที่ใช้ในการโปรแกรม

while()  เป็นคำสั่งทำงานซ้ำแบบมีเงื่อนไขครับ ซึ่งจะทำงานวนซ้ำไปเรื่อยๆจนกว่าเงื่อนไขจะเป็นเท็จ

output_x(...)   เป็นคำสั่งส่งข้อมูลออกทางเอาต์พุตในพอร์อตที่ต้องการตามค่าที่กำหนด เช่น output_b(0x01);

delay_ms(...)  เป็นคำสั่งหน่วงเวลา เช่น delay_ms(500); โปรแกรมจะหน่วงเวลา 500ms ซึ่งค่านี้เราสามารถเปลี่ยนแปลงได้ตามความต้องการครับ


ขั้นตอนที่ 2

เริ่มเขียนโปรแกรมกันเลยครับ


#include<16F84A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT

void main()
{
  while(true)                      // คำสั่งวนซ้ำแบบมีเงื่อนไข
         {
           output_b(0x01);     // คำสั่งส่งข้อมูลออกทางเอาต์พุตพอร์ต b0
           delay_ms(1000);    // คำสั่งหน่วงเวลา 1 วินาที
           output_b(0x02);     // 
คำสั่งส่งข้อมูลออกทางเอาต์พุตพอร์ต b1
           delay_ms(1000);    // คำสั่งหน่วงเวลา 1 วินาที
         }
}






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

      เมื่อโปรแกรมเริ่มทำงาน LED ทั้งสองดวง จะติดและดับสลับกัน โดยหน่วงเวลาในการติด 1 วินาที และหน่วงเวลาในการดับ 1 วินาที 

Home work

งานที่ 1

Microcontroller PIC 16F84A






รายละเอียด

        PIC คืออะไร
    PIC คือ microcontroller อีกระกูลหนึ่ง ย่อมาจากคำว่า Peripheral Interface Controller ซึ่ง concept ของเจ้า microcontroller ตระกูลนี้ก็คือ พยายามรวมเอาทุกอย่างเอาไว้ในตัวของมันไม่ว่าจะเป็นPROGRAM MEMROY, RAM, EEPROM, SERIAL, I2C, PWM, A/D ฯลฯ โดยไม่จำเป็นต้องต่ออุปกรณ์เสริมจากภายนอก ในตัวของ PIC จะมีฟังก์ชันที่ใช้ในการประมวลผล รวมทั้งหน่วยความจำ ซึ่งทำให้มันเหมือนกัน CPU ตัวนึงเลยทีเดียว

        ความเร็วของ PIC

    ภาคของความถี่สัญญาณนาฬิกา ปัจจุบันสามารถทำสัญญาณนาฬิกาได้ที่ 20 MHz ซึ่งทำให้หนึ่งคำสั่งของ PIC ใช้เวลาเพียง 0.25 uSec แต่อย่างไรก็ตามได้มีบริษัทอื่นได้ซื้อลิขสิทธิ์ PIC จาก microchipและได้สร้าง chip ที่มีความเร็วได้มากกว่าเดิมขึ้นไปอีก 
        หน่วยความจำของ PIC 
    ในอดีตหน่วยความจำของ PIC จะค่อนข้างน้อย คืออยู่ระหว่าง 512 words ถึง 4K words แต่ในปัจจุบัน บริษัท microchip ซึ่งเป็นเจ้าของ PIC ได้พัฒนาจนทำให้ memory ของ PIC มีขนาดเป็นหลายสิบกิโลไบต์ และมีทีท่าว่าจะขยายได้ใหญ่ขึ้นเรื่อยๆ ในเรื่องของการนับขนาดของหน่วยความจำของ PIC จะนับไม่เหมือนปกติ โดยที่ หนึ่งคำสั่งของ PIC จะมีขนาด 14 bits ดังนั้นเราจะเรียกว่า 1 word ของ PIC จะมีขนาด 14 bits เช่น PIC16F84A ระบุว่ามีหน่วยความจำ 1 K (ซึ่งหมายถึง 1 Kword ถ้าคำนวณให้เป็นแบบ 1 byte = 8 bit จะได้ว่า 1 x 1,024 x 14 = 14,336 bits ดังนั้นก็คือ14,336/(8 x 1,024) = 1.75K bytes นั่นเอง

        รายละเอียด Hardware เบื้องต้นของ PIC16F84A

    PIC16F84A จะมีโครงสร้างแบบ RISC(Reduced Instruction Set Computer) PIC ในตระกูล16xxx จะมีคำสั่งให้ใช้ทั้งหมด 35 คำสั่ง โดยจะแสดงโครงสร้างและการทำงานของ PIC16F84A ดังต่อไปนี้...


                                                        ภาพโครงสร้างขาของ PIC16F84A

    OSC1/CLKIN : Oscillator crystal input / External clock source input. OSC2/CLKOUT :Oscillator crystal output.ทั้งสองขานี้จะต่อกับ crystal หรือ resonator ในกรณีที่อยู่ใน crystal oscillator mode(ใช้สัญญาณนาฬิกาจากภายนอก)
    MCLR(inv) : Master clear(reset)input Programming voltage input. เมื่อขานี้เป็น LOW แล้ว MCU จะถูก reset อีกหน้าที่หนึ่งของขานี้ก็คือจะเป็น input ของ voltage programming ขณะที่ทำการ program ตัว MCU 
    RA0 - RA3 : Bi-directional I/O port. เป็นพอร์ตแบบ สองทิศทาง คือเลือกให้เป็น INPUT หรือ OUTPUT ก็ได้อย่างใดอย่างหนึ่ง RA4/T0CKI : Bi-directional I/O port. เป็นพอร์ตแบบสองทิศทาง คือ เลือกให้เป็น INPUT หรือ OUTPUT ก็ได้อย่างใดอย่างหนึ่ง อีกหน้าที่หนึ่งก็คือ Clock input to the TMR0 timer/counter. เป็น input ของ สัญญาณนาฬิกาเพื่อป้อนให้กับ Timer 0 ซึ่งอยู่ภายใน MCU ในกรณีที่
เลือกว่าแหล่งของสัญญาณนาฬิกาที่ป้อนให้กับ Timer 0 ให้ใช้จากภายนอก RB0/INT : Bi-directional I/O port. เป็นพอร์ตแบบสองทิศทาง คือเลือกให้เป็น INPUT หรือ OUTPUT ก็ได้ อย่างใดอย่างหนึ่ง อีกหน้าที่หนึ่งก็คือ External interrupt pinรับสัญญาณ interrupt เมื่อเกิดการเปลี่ยนแปลงของสัญญาณที่ขานี้ RB1 - RB7 : Bi-directional I/O port. เป็นพอร์ตแบบสองทิศทาง คือเลือกให้เป็น INPUT หรือ OUTPUT
ก็ได้ อย่างใดอย่างหนึ่ง VSS : Ground VDD : Positive Supply(+2.0V to +5.5V)

        ชุดคำสั่งของ PIC16F84A
                ความหมายของตัวแปร
      f หมายถึง รีจิสเตอร์ไฟล์
      d หมายถึง ที่เก็บปลายทาง ถ้าเป็น 0 จะเก็บไว้ที่ W , ถ้าเป็น 1 จะเก็บไว้ที่ รีจิสเตอร์ไฟล์
      k หมายถึง ค่าคงที่ ใด ๆ
      b หมายถึง ข้อมูลขนาด 8 บิท
      d หมายถึง ข้อมูลฐาน สิบ
      W หมายถึง รีจิสเตอร์ W ( Accumulator )
      X หมายถึงไม่สนใจ
      Label หมายถึงตำแหน่งที่ต้องการกระโดดไป
คำสั่ง
มาจาก
ความหมาย
MOVLW kMove data to W registerเป็นการกำหนดค่าคงที่ 8 บิท
MOVF f,dMove data from register to registerย้ายข้อมูลจากรีจิสเตอร์ไฟล์ไปเก็บไว้ที่ W
MOVWF fMove data from W register to file registerย้ายข้อมูลจากรีจิสเตอร์ W เก็บไว้ที่ รีจิสเตอร์ไฟล์
CLRF fClear file registerเคลียร์ค่าของรีจิสเตอร์ไฟล์ใด ๆ ให้เป็น 0
CLRWClear W registerเคลียร์ค่าของรีจิสเตอร์ W ให้เป็น 0
COMF f,dComplement registerคำสั่งกลับค่าของข้อมูล จาก 0 เป็น 1 หรือ จาก 1 เป็น 0
DECF f,dDecrement registerคำสั่งลดค่าของรีจิสเตอร์ไฟล์ลงที่ละ 1
INCF f,dIncrement registerคำสั่งเพิ่มค่าของรีจิสเตอร์ไฟล์ขึ้นที่ละ 1
BCF f,bClear bit in registerคำสั่งเคลียร์บิทในรีจิสเตอร์ไฟล์เป็น 0
BSF f,bSet blt in registerคำสั่งเซตบิตในรีจิสเตอร์ไฟล์เป็น 1
RLF f,dRotate left register through carryคำสั่งหมุนข้อมูลไปทางซ้ายเข้าสู่บิททด
RRF f,dRotate right register through carryคำสั่งหมุนข้อมูลไปทางขวาเข้าสู่บิททด
BTFSC f,bBit test register skip if clearคำสั่งกระโดดข้ามไป 1 ตำแหน่ง ถ้าบิทนั้นเป็น 0
BTFSS f,bBit test register skip if setคำสั่งกระโดดข้ามไป 1 ตำแหน่ง ถ้าบิทนั้นเป็น 1
DECFSZ f,dDecrement register skip zeroคำสั่งลดค่าข้อมูลและกระโดดข้ามไป 1 ตำแหน่ง ถ้าบิทเป็น 0
INCFSZ f,dIncrement register skip if zeroคำสั่งเพิ่มค่าข้อมูลและกระโดดข้ามไป 1 ตำแหน่ง ถ้าบิทเป็น 0
SLEEPSleep ( goto standby mode)คำสั่งกำหนดให้ซีพียูทำงานในโหมดสลีป
SWAPF f,dSwap registerคำสั่งสลับค่าข้อมูล 4 บิทบน หรือ 4 บิทล่าง เก็บไว้ที่ W
OPTIONLoad option registerคำสั่งกำหนดค่าของรีจิสเตอร์ option
GOTO kGoto addressคำสั่งกระโดดไปทำงานตามตำแหน่งที่ label นั้น ๆ
CALL kSubroutine callคำสั่งกระโดดไปทำงานที่โปรแกรมย่อย
RETURNReturn from subroutineคำสั่งที่ใช้ร่วมกับ return เพื่อกลับมาทำงานที่ตำแหน่งเดิม
RETLW kReturn from subroutine and to W registerคำสั่งกระโดดไปทำงานที่โปรแกรมย่อย และย้ายค่าได้
TRIS fLoad tris registerคำสั่งกำหนดค่าของรีจิสเตอร์ TRIS
NOPNo operatorคำสั่งที่มักใช้เมื่อต้องการหน่วงเวลาของซีพียู


       การจัดสรรตำแหน่งหน่วยความจำ ของ PIC16F84A
                                                    รีจิสเตอร์ STATUS ตำแหน่ง 0x03
                         


      bsf status , rp0 = กำหนดให้หน่วยความจำอยู่ที่ แบงก์ 1
TRISA = รีจิสเตอร์กำหนดทิศทางของ PORT A อยู่ที่ BANK 1 หน่วยความจำที่ 0x85
TRISB = รีจิสเตอร์กำหนดทิศทางของ PORT B อยู่ที่ BANK 1 หน่วยความจำที่ 0x86
การกำหนด PORT ของ PIC16F84A
    ในการกำหนด PORT ให้ทำหน้าที่เป็น INPUT PORT หรือ OUTPUT PORT กำหนดที่ TRIS ว่าทำหน้าที่เป็น INPUT / OUTPUT      
        กำหนดเป็น OUTPUT  = 0
        กำหนดเป็น INPUT     = 1


สถาปัตยกรรมและการทำงานภายในของ PIC


    ตอนนี้มี 3 สายหลักๆ สมัยก่อนมีแค่สอง คือขึ้นต้นด้วย 16xxx,17xxx และใหม่ล่าสุดคือ 18xxx ถ้าพูดถึง คุณสมบัติที่เหนือกว่าเรียงจากน้อยสุดไปมากสุดก็คือ 16 -> 17 -> 18 คำสั่ง assembly ของ 17 และมี 18 จะมีมากกว่า 16 ทำให้เขียนโปรแกรมได้ง่ายกว่า ราคาก็จะสูงกว่าด้วย แต่ที่เป็นที่นิยมก็คือ ตระกูล 16xxx
    สรุปว่า Concept สถาปัตยกรรมของ PIC จะยึดถือการออกแบบที่ว่ารวมทุกอย่างไว้ใน chip ตัวเดียวโดยไม่ต้องต่ออุปกรณ์ใดๆเพิ่มเติม ผลที่ตามมาก็คือแผ่นวงจรจะมีขนาดเล็ก และอุปกรณ์ที่ใช้จะไม่มาก บางงานอาจจะใช้แค่ PIC เพียงตัวเดียวโดยไม่ต้องใช้ chip อื่นมาเพิ่มเติมเลย นี่คือคุณสมบัติพิเศษของ PIC ครับ ซึ่งปัจจุบันหลายบริษัทที่ผลิต microcontroller ก็เริ่มจะหัดมาเลียนแบบแนวทางนี้ครับ แต่ทุกอย่างย่อมมีข้อเสีย เนื่องจาก concept ที่จะรวมทุกอย่างไว้ใน chip เดียว ทำให้ program memory และ data memory ไม่สามารถขยายโดยใช้กับ memory ภายนอกได้ (ในทางทฤษฎี นะครับ ของจริงนี่ทำได้ แต่ต้องใช้เทคนิคนิดหน่อยครับ ซึ่งไม่นิยม ต้องบอกกันไว้ก่อน) PIC จึงเหมาะสำหรับงานเล็กๆ ไม่ใช่งานใหญ่ๆ ที่ต้องใช้การคำนวณ และmemory เยอะๆ สำหรับผม PIC ก็คือมดครับ แมลงที่สามารถยกของที่มีน้ำหนักมากกว่ามันได้หลายสิบเท่า


     

รูปสถาปัตยกรรมภายในของ PIC16F84A

การแบ่งหน่วยความจำภายในของ PIC16F84A


         Flash Program Memory

    Flash memory เป็นพื้นที่หน่วยความจำสำหรับเก็บ program ที่เราเขียนขึ้น ซึ่งมีขนาด1,024 words ถึงแม้ว่าจะไม่มีไฟฟ้าจ่ายให้กับ MCU ข้อมูลที่เก็บอยู่ใน flash memory ก็จะไม่หายไป จุดเด่นของ Flash memory ก็คือสามารถเขียนทับเข้าไปใหม่ได้หลายๆ ครั้งซึ่งจำนวนครั้งจะอยู่ที่ประมาณ 1000 ครั้ง
        EEPROM(Electrically Erasable Programmable Read Only Memory)
    หน่วยความจำในส่วนนี้เมื่อไม่มีไฟฟ้าจ่ายให้กับ MCU แล้วข้อมูลที่อยู่ภายในยังคงอยู่จะไม่หายไปและสามารถเขียนด้วยคำสั่งของ program จะมีขนาด 64 bytes. อย่างไรก็ตามการเขียนซ้ำก็มีข้อจำกัด โดยสามารถเขียนทับใหม่ได้ประมาณ 1 ล้านครั้ง ดังนั้นหน่วยความในส่วนนี้จะใช้เก็บข้อมูลที่ไม่ค่อยจะเปลี่ยนแปลงบ่อยนัก หน่วยความจำในส่วนนี้สามารถเก็บข้อมูลได้นาน 40 ปี
        SFR Registers
    SFR(Special Function Registers) มีอยู่ 16 ชนิดด้วยกัน ซึ่งสามารถอ้างถึงด้วยการ เปลี่ยนตำแหน่งของ bank ที่จะอ้าง จากรูปข้างล่างแสดงถึงโครงสร้างของ File Registers. ทั้งหมดจะมีขนาด160 bytes แต่ในข้อเท็จจริงแล้วจะไม่สามารถอ้างได้ครบทั้งหมด ในส่วนที่เป็นสีขาวแล้วมีลูกศรชี้จะหมายถึงว่า ถ้าเราอ้าง RAM ที่ตำแหน่งนี้ใน BANK 1 ค่าที่ได้ก็คือค่าทางซ้ายมือที่อยู่ใน BANK 0 นั่นเอง เช่นเมื่อเราอ้างที่ address 84h ใน Bank 1 ค่าที่ได้ก็จะเป็น ค่า FSR ที่อยู่ใน BANK 0 สำหรับในส่วนที่เป็นสีเทาก็ คือ memory ที่ไม่สามารถอ้างถึงได้

            ตัวแปรใน SFR มีดังนี้
            INDF : จะเก็บค่าของ Data memory ที่ถูกชี้แบบ indirect addressing
            TMR0 : เป็นTimer counter ของ Timer 0
            PCL : เก็บค่า 8 bits ล่างของ program counter
            STATUS : จะเก็บค่า Flag ของผลลัพธ์ที่เกิดจากการคำนวณ
            FSR : เป็น pointer ใช้สำหรับอ้างอิง data memory แบบ indirect
            PORTA : เก็บค่าสถานะของ PORTA
            PORTB : เก็บค่าสถานะของ PORTB
            EEDATA : เก็บค่าของ Data ที่ EEPADR ชี้อยู่
            EEADR : ตำแหน่งของ EEPROM ที่ต้องการอ้างถึง
            PCLATH : เป็น 5 bits บนของ program counter
            INTCON : ใช้คำคุมการเกิด Interruption
            OPTION_REG : ใช้สำหรับกำหนด Mode การทำงานของ MCU
            TRISA : ใช้กำหนด Mode ของ PORTA ว่าเป็น INPUT หรือ OUTPUT
            TRISB : ใช้กำหนด Mode ของ PORTB ว่าเป็น INPUT หรือ OUTPUT
            EECON1 : เป็น register ที่ใช้ควบคุม EEPROM
            EECON2 : เป็น register ที่ใช้ป้องกันการเขียน EEPROM

        Program Counter
    เป็น counter ที่แสดงถึงตำแหน่ง address ของ program ที่เขียนเข้าไปไว้ใน flash memory ที่กำลังทำการประมวลผล ซึ่งจะเป็น counter ขนาด 13 bits โดยทั่วไปแล้ว counter ตัวนี้จะเพิ่มขึ้น 1 ทุกๆครั้งเมื่อมีการประมวลผลคำสั่งเกิดขึ้น 1 ครั้ง ซึ่งค่าที่แสดงก็คือตำแหน่งของคำสั่งต่อไปที่จะทำการประมวลผล แต่เมื่อประมวลคำสั่ง JUMP ตัว counter จะมีค่าเท่ากับตำแหน่งที่คำสั่ง JUMP นั้นอ้างถึง 8 Level Stack
    stack คือ memory ซึ่งจะเก็บค่า return address ของ program ตัวอย่างเช่น เมื่อต้องทำการประมวลผลอย่างหนึ่งหลายๆ ครั้ง ซึ่ง program ในส่วนนี้ถูกสร้างเป็น subroutine ไว้ ในตอนสุดท้ายของ subroutine ก็จะมีคำสั่ง RUTURN ทุกครั้ง ในการเรียกใช้เราจะใช้คำสั่ง CALL ในการเรียก subroutine ตำแหน่ง program address ที่ถัดจากคำสั่ง CALL ก็จะถูกเก็บลงสู่ stack (กระบวนการนี้บางครั้งจะ
เรียกว่า PUSH) หลังจากได้ประมวลผลคำสั่งใน subroutine แล้ว ในตอนสุดท้ายเมื่อมาเจอคำสั่ง RETURN มันก็จะทำการกระโดดไปยังตำแหน่งที่เก็บไว้ใน stack(กระบวนการนี้บางครั้งจะเรียกว่า POP) แต่เนื่องจากว่า stack มีขนาดเพียง 8 เท่านั้น นั่นก็หมายความว่าเราสามารถเรียก คำสั่ง CALL ได้ เก้าครั้งติดต่อกันเท่านั้น ซึ่งถ้าใช้คำสั่ง CALL ไปมากกว่านั้นโดยไม่ RETURN กลับ ค่า stack จะถูกทับเป็นผลทำให้ เมื่อใช้คำสั่ง RETURN ก็จะไม่สามารถกลับไปยังตำแหน่งเดิมได้

รูปภาพ Instruction Register ของ PIC16F84A


    คำสั่งต่างๆ ของโปรแกรม ที่ถูกชี้โดย program counter จะถูกอ่านข้าไปยัง register ตัวนี้ โดยกระบวนการนี้จะถูกเรียกว่า FETCH. Instruction Decode & Control คำสั่งที่ถูก FETCH ไว้ใน instruction register จะถูกแปลความหมายและทำงานตามคำสั่งนั้น Multiplexer and Arithmetic Logic Unit โดยการแปลความหมายและทำงานตามคำสั่งจะถูกกระทำโดย Multiplexer และ the Arithmetic Logic Unit(ALU) W Register ย่อมาจาก work register มันจะมีหน้าที่สำหรับเก็บผลของการคำนวณที่เกิดจาก ALU เอาไว้ชั่วคราว เพื่อที่จะนำมาคำนวณต่อไป ตัวของมันจะทำหน้าที่เป็นตัวกลางในการคำนวณต่างๆ และมันยังทำหน้าที่ส่งผ่านสถานะoutput ของ input-output port อีกด้วย

         STATUS Register

    เป็น register ซึ่งจะเก็บค่าผลของ ALU(เช่น ผลลัพธ์ของการ บวก ลบ ของ register เป็น 0, บวก,ลบ), เงื่อนไขการเกิด timeout , เป็นตัวกำหนดว่าขณะนี้ PIC อ้าง register ที่ bank ไหน
         FSR Register
    FSR(File Select Register) ใช้สาหรับอ้างตำแหน่งของ RAM ในรูปแบบ indirect address การอ้างแบบ direct address ก็คือรูปแบบที่อ้างถึง Address นั้นโดยเฉพาะเจาะจงเลย เช่น movfw h’20’ ซึ่งหมายความว่าทำการอ่านค่า ที่ address 20 มาเก็บไว้ที่ w register ในกรณีนี้สามารถอ้างตำแหน่งได้ตั้งแต่ 0 ถึง 127 หรืออ้างได้เพียง 7 bit ซึ่งจะอยู่ในขอบเขต 1 bank ในการที่จะเปลี่ยน bank จำเป็นที่จะต้องเกี่ยวข้องกับ RP0 bits ของ STATUS register การอ้างแบบ indirect address โดยใช้ FSR register จะนิยมใช้ในการอ้าง address ที่อยู่ติดๆ กันด้วยการอาศัยคำสั่ง inc FSR เพื่อเลื่อนไปยังตำแหน่ง memory ถัดไป
        Address Multiplexer
    ใช้เป็นตัวแบ่งแยกว่าเป็น indirect addressing หรือ the direct address. ซึ่งหมายความว่าทำการอ่านค่า ที่ address 20 มาเก็บไว้ที่ w register ในกรณีนี้สามารถอ้างตำแหน่งได้ตั้งแต่ 0 ถึง 127 หรืออ้างได้เพียง 7 bit ซึ่งจะอยู่ในขอบเขต 1 bank ในการที่จะเปลี่ยน bank จำเป็นที่จะต้องเกี่ยวข้องกับ RP0bits ของ STATUS register การอ้างแบบ indirect address โดยใช้ FSR register จะนิยมใช้ในการอ้าง address ที่อยู่ติดๆ กันด้วยการอาศัยคำสั่ง inc FSR เพื่อเลื่อนไปยังตำแหน่ง memory ถัดไป
         Address Multiplexer
    ใช้เป็นตัวแบ่งแยกว่าเป็น indirect addressing หรือ the direct address.

        EEDATA

    เป็น register ที่จะใช้เมื่อมีการอ่านหรือเขียนข้อมูล EEPROM
         EEADR
    เป็น register ที่ใช้สำหรับอ้าง address ของ EEPROM. ซึ่งใน PIC16F84A จะมีหน่วยความจำ EEPROM อยู่ทั้งหมด 64 bytes เมื่อจะทำการเขียน EEPROM จะต้อง เขียนข้อมูล 55h และ AAh ไปยัง EECON2 เสียก่อนจึงจะเริ่มต้นการเขียน EEPROM ได้
        Timer
    PIC16F84A จะมี timer เพียงแค่ตัวเดียว (TMR0) มีขนาด 8 bits การทำงานของมันก็คือมันจะทำการนับไปเรื่อยๆ และจะเกิดการ time-out เมื่อการนับมาถึง 256 ซึ่งจะทำให้ T0IF bit ของ INTCON register ซึ่งเป็น SFR กลายเป็น "1" ซึ่งมีผลทำให้เกิดการ interrupt เกิดขึ้นเมื่อเกิดการ time-out. สำหรับการที่จะกำหนดว่าจะให้มีการ interrupt ของ TMR0 เกิดขึ้นได้หรือไม่นั้นกำหนดได้จาก the GIF bit และ T0IE bit ของ INTCON register ซึ่งเป็น SFR โดยถ้าเป็น "1" ก็หมายความว่ากำหนดให้มีการ interrupt เกิดขึ้นได้
        I/O Ports
    PIC16F84(A) จะมี I/O Ports ทั้งหมด 13 ขา ซึ่งการกำหนดว่าจะให้ขานั้นเป็น INPUT หรือ OUTPUT นั้นสามารถกำหนดได้ด้วยโปรแกรม ทั้ง 13 ขานั้นสามารถแบ่งออกได้เป็น 2 กลุ่มด้วยกันก็คือ 5 ขาเป็น A port และอีก 8 ขาที่เหลือเรียกว่า B port

         Timing Generation

    PIC จะมีวงจรภายในที่จะสร้างสัญญาณนาฬิกาในการกำหนดความจังหวะของการทำงานของตัวมัน โดยสัญญาณนาฬิกานี้จะมีแหล่งกำเนิดมาจาก crystal หรือ ceramic oscillator จากภายนอก เมื่อสัญญาณนาฬิกาต้องการความแม่นยำสูงเราจะต้องเลือกใช้ crystal แต่โดยปกติทั่วๆไปแล้วจะใช้ ceramic resonator ต่อเข้ากับ capacitors เป็น module อยู่ภายนอก PIC16F84A จะ execute 1 คำสั่ง(1 cycle) จะใช้สัญญาณนาฬิกา 4 pulses โดยจะใช้ pipeline architecture แต่ในกรณีของคำสั่ง JUMP จะใช้ 2 cycle สำหรับเวลาที่ใช้ในการ execute นั้นโดยปกติแล้วจะใช้เวลา 200 nanoseconds ถ้าใช้ crystal ที่ความถี่ 20MHz, 1/(20MHz) = 50 nanoseconds. หมายความว่าสามารถ execute คำสั่ง 5,000,000 instructions ภายในเวลา 1 วินาที Initialization circuits 

        ภายใน PIC16F84A จะต้องมีการกำหนดคุณสมบัติการทำงานให้แต่ตัวมันหลายอย่างดังนี้

    - POWER ON Timer  เป็น Timer ที่ใช้สำหรับสร้างช่วงระยะเวลาก่อนที่จะใช้ MCU ทำงานเพื่อรอจนกระทั่งแรงดันไฟฟ้าที่ป้อนให้กับ MCU จะนิ่งในกรณีเมื่อมีการป้อนไฟเข้าไปใหม่

    - OSC Start Timer เป็น Timer ที่ใช้สำหรับสร้างช่วงระยะเวลาก่อนที่จะใช้ MCU ทำงานเพื่อรอจนกระทั่งสัญญาณนาฬิกาที่ป้อนให้กับ MCU จะนิ่งในกรณีเมื่อมีการป้อนไฟเข้าไปใหม่

    - POW ON Reset จะทำการ RESET วงจรภายใน PIC ใหม่เมื่อมีการป้อนไฟเข้าไปใหม่

    - Watchdog Timer เป็น Timer สำหรับจับเวลาว่าโปรแกรมบางช่วงใน PIC ทำงานนานเกินไปหรือไม่เพื่อป้องกันอาการที่เรียกว่า Dead Lock ซึ่ง Timer ตัวนี้จะต้องทำการ clear ด้วยคำสั่งทาง software เมื่อ timer ตัวนี้นับจนกระทั่ง time-out เกิดขึ้น PIC จะกลับไป
อยู่ในสถานะเหมือนกับสภาพที่มีการป้อนไฟเข้าไปใหม่

        การเขียนโปรแกรม Microcontroller
    ภาษาที่ใช้สำหรับการเขียนโปรแกรมบน Microcontoller (ต่อไปจะของเรียกสั้นๆว่า MCU) แบ่งได้ เช่นเดียวกับการเขียนโปรแกรมบนคอมพิวเตอร์คือ ภาษาระดับสูง และภาษาระดับต่ำ ภาษาระดับสูงเช่น C, Basic ข้อดีคือเขียนง่ายแก้ไขเปลี่ยนแปลง หรือเพิ่มเติมได้ง่าย ส่วนข้อเสียก็คือการทำงานจะช้า ขนาดโปรแกรมที่เขียนมีขนาดใหญ่ ภาษาระดับต่ำ ซึ่งก็คือ ภาษา Assembly ข้อดีคือ ตัว Compiler แจกฟรีขนาดโปรแกรมหลังจาก Compiled แล้วมีขนาดเล็ก โปรแกรมมีความเร็ว แต่ข้อเสียก็คือเขียนยาก เพราะลักษณะภาษาไม่ค่อยสื่อความหมาย แก้ไขเปลี่ยนแปลงยาก




ตัวอย่างการประยุกต์ใช้งาน PIC16F84A




        -Thermometer



    เป็นเครื่องวัดอุณหภูมิที่เรียบง่าย โดยมีส่วนประกอบเพียงไม่กี่ชิ้น
ใช้ PIC16F84A และเซ็นเซอร์เป็น DS18B20 
ช่วงของเซ็นเซอร์ -55
° C  ถึง 125 ° C 


           

รูปแสดงการนำ PIC16F84A มาใช้ในการทำ Thermometer 



        -Accurate LC Meter based on PIC16F84A

    เป็นเครื่องที่ใช้วัดค่าความเหนี่ยวนำและค่าประจุ(LC) ช่วยให้การวัด Inductances เริ่มต้นจากการ 10NH ถึง 1000nH , 1uH ถึง 1000uH , 1mH ถึง 100mH และความจุจาก 0.1pF ถึง 900nF 

        

      

     
  
รูปแสดง Accurate LC Meter based on PIC16F84A





________________________________________________________________________________










งานที่2

 เกลียว ชนิดและส่วนต่างๆของเกลียว เกลียว ( Thread)  หมายถึงสันหรือร่องที่เกิดขึ้นบนผิวงานวนไปรอบ ๆจะซ้ายหรือขวาก็ไดด้วยระยะทางที่สม่ำเสมอ เ...