วันพฤหัสบดีที่ 27 กุมภาพันธ์ พ.ศ. 2563

 ทบทวนการเรียน

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

ภาพวงจร


CODE

void main()
{
  int i=3;
  int j;
  TRISC=0;
    do {
       switch (i)
         {
          case 1:
           PORTC.F3=1;
           delay_ms(200);
           PORTC.F3=0;
           delay_ms(200);
           break;
          case 2:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
          case 3:
           PORTC.F0=1;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
          case 4:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
         }
           j++;
      }
    while(j<5);
  }

 ทบทวนการเรียน

1.คำสั่ง while วนloop

   while  เป็นคำสั่งที่มีการทำงานซ้ำ ๆ เป็นลูป  และมีลักษณะการทำงานของคำสั่งคล้ายกับคำสั่ง  for  แตกต่างกันตรงที่  การใช้  while  ไม่ต้องทราบจำนวนรอบของการทำงานที่แน่นอน  แต่ต้องมีเงื่อนไขที่เป็นเท็จจึงจะออกจากคำสั่ง  while  ได้

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

ภาพวงจร


CODE
void main()

{
  int i=3;
  int j;
  TRISC=0;
    while(j<5)
    {
    switch (i)
    {
      case 1:
           PORTC.F3=1;
           delay_ms(200);
           PORTC.F3=0;
           delay_ms(200);
           break;
       case 2:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
        case 3:
           PORTC.F0=1;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
       case 4:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
    }
           j++;
    }
  }

ทบทวนการเรียน

1.คำสั่ง for

       ในการใช้ for  เราสามารถกำหนดค่าเริ่มต้น สร้างเงื่อนไข (expression) และทำการกำหนดการเพิ่มค่าหรือลดค่าของตัวทำซ้ำได้ก่อนที่ลูปจะเริ่มทำงาน

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

ภาพวงจร


CODE
void main()

{
  int i;
  TRISC=0;
    for (i = 0;i<5; i++)
    {
       PORTC.F0=1;
        delay_ms(200);
       PORTC.F0=0;
           delay_ms(200);
    }
   for (i = 0;i<10; i++)
    {
       PORTC.F7=1;
        delay_ms(200);
       PORTC.F7=0;
           delay_ms(200);
    }
}


1.คำสั่ง switch case
     เงื่อนไข(switch case)เป็นเงื่อนไขเช่นเดียวกับ if-else แต่จะมีความเที่ยงตรงที่สูงกว่า และใช้ได้ค่อยข้างจำกัด โดยส่วนใหญ่แล้วจะใช้ในการควบคุมการแสดงผลทางเมาส์ และคีย์บอร์ด แต่ก็สามารถนำมาใช้เป็นเงื่อนไขเช่นเดียวกับ if-else 

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


ภาพวงจร


CODE
void main()
{
  int i=3; //   i = 1,2,3,4
  TRISC=0;
    while(1)
    {
    switch (i)
    {
      case 1:           //   i = 1
           PORTC.F3=1;
           delay_ms(200);
           PORTC.F3=0;
           delay_ms(200);
           break;
       case 2:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
        case 3:        //   i = 3
           PORTC.F0=1;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
       case 4:
           PORTC.F0=0;
           delay_ms(200);
           PORTC.F0=0;
           delay_ms(200);
           break;
    }
    }
  }

Home work

งานที่ 18

PIC12f675

คุณสมบัติไมโครคอนโทรลเลอร์พิเศษ:
• ตัวเลือก oscillator ภายในและภายนอก
- โรงงานออสซิลเลเตอร์ความแม่นยำ 4 MHz ภายใน
สอบเทียบถึง± 1%
- ตัวรองรับ Oscillator ภายนอกสำหรับคริสตัลและ
resonators
- ปลุก 5 5 จาก SLEEP, 3.0V, ทั่วไป
• โหมดประหยัดพลังงาน SLEEP
• ช่วงแรงดันไฟฟ้าที่กว้าง - 2.0ถึง 5.5V
• ช่วงอุณหภูมิอุตสาหกรรมและขยาย
• ใช้พลังงานต่ำรีเซ็ต (POR)
• Power-up Timer (PWRT) และ Oscillator Start-up
จับเวลา (OST)
• เครื่องตรวจจับ Brown-out (BOD)
• ตัวจับเวลา Watchdog (WDT) ที่เป็นอิสระ
oscillator เพื่อการทำงานที่เชื่อถือได้
• มัลติเพล็กซ์ MCLR / อินพุตขา
• การเปลี่ยนแปลงขัดจังหวะบนขา
• อัพพูลอัพที่สามารถตั้งโปรแกรมได้แต่ละอัน
• การป้องกันรหัสโปรแกรม
• ความทนทานสูง FLASH / EEPROM เซลล์
- 100,000 ความอดทนในการเขียน FLASH
- 1,000,000 ความอดทนการเขียน EEPROM
- แฟลช / การเก็บข้อมูล EEPROM:> 40 ปี

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

ภาพวงจร

 CODE



Home work

งานที่ 17

โปรแกรมไฟวิ่ง

     บทความนี้เราจะมาศึกษาโปรแกรมไฟวิ่งกันครับ หลังจากที่ได้ทดลองเขียน โปรแกรมไฟกระพริบ LED 2 ดวง กันไปแล้ว ทีนี้เรามาทดลองเขียนโปรแกรมไฟวิ่งกันบ้างครับ ซึ่งจะใช้ LED ทั้งหมด 8 ดวงต่อเข้ากับพอร์ตเอาต์พุต B ทั้งหมด เพื่อที่จะให้ท่านที่เขียนไมโครคอนโทรลเลอร์มือใหม่ ได้เข้าใจการใช้งานเอาต์พุตพอร์ตดิจิตอลทั้ง 8 บิตควบคุม LED 8 ดวง มาเริ่มกันเลยครับ

ขั้นตอนที่ 1

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



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

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


for() เป็นคำสั่งทำงานซ้ำที่มีจำนวนลูปที่แน่นอน และจะหยุดทำซ้ำเมื่อเงื่อนไขเป็นเท็จ เช่น
for(i=1;i<=9;i++)

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

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


set_tris_b()  เป็นคำสั่งกำหนดให้พอร์ต B เป็นเอาต์พุตทั้งหมดนั่นเอง โดยการกำหนดค่าให้กับฟังก์ชัน set_tris_b() เท่ากับ 0x00 เช่น set_tris_(0x00);


ขั้นตอนที่ 2

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



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

void main()
{
  char i,j;                                   //  กำหนดตัวแปร i,j
  set_tris_b(0x00);                      //  คำสั่งกำหนดพอร์ต B ให้เป็นพอร์ตเอาต์พุตทั้งหมด
  output_b(0b00000000);            //  คำสั่งเคลียร์พอร์ต B ให้เป็น 0 ทุกบิต
  
  while(true)                              //  คำสั่งวนซ้ำแบบมีเงื่อนไข
        {
           j=1;                               //  กำหนดตัวแปร j=1
           for(i=1;i<=8;i++)           //  คำสั่งทำซ้ำโดยกำหนดให้ i=1,i<=8,i=i+1
              {
                output_b(j);               //  กำหนดให้เอาต์พุตพอร์ต B = j
                j=j<<1;                    //  ให้ตัวแปร j เลื่อนบิตไปทางซ้าย 1 ตำแหน่ง
                delay_ms(1000);        //  คำสั่งหน่วงเวลา 1 วินาที
              }
         }
  }
      



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

      เมื่อ
โปรแกรมไฟวิ่งเริ่มทำงาน LED 1 จะติดโดยหน่วงเวลา 1 วินาทีถึงจะดับ พร้อมกันนี้ LED 2 ก็จะติดด้วยโดยหน่วงเวลา 1 วินาทีเช่นกัน เป็นอย่างนี้ไปเรื่อยๆ จนถึง LED 8 แล้วก็จะวนซ้ำกลับมาติดที่ LED 1 อีกครั้ง

    เป็นยังไงบ้างครับโปรแกรมไฟวิ่ง เมื่อได้ลองกันแล้วง่ายมากเลยใช่มั๊ยครับ
    ทีนี้ก็ลองแก้โปรแกรมที่บรรทัด for(i=1;i<=8;i++) ให้เป็น for(i=1;i<=5;i++) แล้วทำการคอมไพล์โปรแกรมใหม่ดูบ้างนะครับว่าLED 1 ถึง LED 8จะมีการเปลี่ยนแปลงยังไงบ้าง

    แล้วลองแก้ที่บรรทัด  j=1; ให้เป็น j=3; แล้วทำการคอมไพล์โปรแกรมใหม่เช่นกัน แล้วสังเกตุดูการเปลี่ยนแปลงของ LED 1 ถึง LED 8 ว่ามีการเปลี่ยนแปลงยังไงบ้าง

   อีกบรรทัดครับ แก้ j=j<<1; ให้เป็น j=j<<2; แล้วทำการคอมไพล์โปรแกรมใหม่ สังเกตุดูการเปลี่ยนแปลงของ LED 1 ถึง LED 8 ว่ามีการเปลี่ยนแปลงยังไงบ้าง

Home work

งานที่ 16

   

โปรแกรมสวิตซ์กดติด-กดดับ เป็นอีกหนึ่งทักษะพื้นฐานในการเขียนโปรแกรมไมโครคอนโทรลเลอร์ 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 ทุกบิต
  a=0;                                       //  คำสั่งกำหนดค่า a=0
  
  while(true)                              //  คำสั่งวนซ้ำแบบมีเงื่อนไข
     {
        while(!input(pin_a0))         //  คำสั่งทำซ้ำ โดยรับค่าอินพุตจากพอร์ต a0
           { 
              a=~a;                        //  คำสั่งเปลี่ยนข้อมูล a เป็นตรงกันข้าม
              output_bit(pin_b0,a);   //  คำสั่งส่งข้อมูลออกทางเอาต์พุตขนาด 1 บิต
              while(!input(pin_a0))   //  คำสั่งทำซ้ำ โดยรับค่าอินพุตจากพอร์ต a0
                 {
                   delay_ms(100);     //  คำสั่งหน่วงเวลา 100 ms
                      
            }  
      }                                   
}





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

Home work

งานที่ 15

PIC16F676



คุณสมบัติ: 
หน่วยความจำข้อมูล EEPROM 128 ไบต์ 
ตัวต้านทานแบบดึงขึ้นที่ตั้งโปรแกรมได้ 
ช่องสัญญาณแอนะล็อกที่เลือกแยกได้ 
การสนับสนุนการเขียนโปรแกรม ICD2 หรือการสนับสนุนการดีบักด้วยอะแดปเตอร์ส่วนหัวเพิ่มเติม
- 8 oscillator sellections รวมถึงความแม่นยำ 4 MHz RC oscillator พร้อมการสอบเทียบที่ตั้งโปรแกรม
ได้และการเปิดเครื่องใหม่

ตัวอย่างการใช้งาน : การต่อ Voltmeter
ภาพวงจร



CODE
#include <16f676.h>
#FUSES NOWDT                   
#FUSES INTRC                 
#FUSES NOMCLR                 
#FUSES NOBROWNOUT            
#FUSES PUT
#device ADC=10
#use delay(INT=4Mhz)



#define aon    output_LOW(PIN_C0);
#define aof    output_HIGH (PIN_C0);

#define bon    output_LOW(PIN_C1);
#define bof    output_HIGH (PIN_C1);

#define con    output_LOW(PIN_C2);
#define cof    output_HIGH (PIN_C2);

#define don    output_LOW(PIN_C3);
#define dof    output_HIGH (PIN_C3);

#define eon    output_LOW(PIN_C4);
#define eof    output_HIGH (PIN_C4);

#define fon    output_LOW(PIN_C5);
#define fof    output_HIGH (PIN_C5);

#define gon    output_LOW(PIN_A2);
#define gof    output_HIGH (PIN_A2);






#define d1_of    output_LOW(PIN_A1);
#define d1_on    output_HIGH (PIN_A1);

#define d2_of    output_LOW(PIN_A0);
#define d2_on    output_HIGH (PIN_A0);

#define d3_of    output_LOW(PIN_A5);
#define d3_on    output_HIGH (PIN_A5);




int32  value=0,val2,ind=0,ind2=0,cnt5=0,d1;

void off();
int thu,ten,unit,digit;


void zero(){
 aon;
 bon;
 con;
 don;
 eon;
 fon;
 gof;
}
void one(){
 aof;
 bon;
 con;
 dof;
 eof;
 fof;
 gof;
}

void two(){
 aon;
 bon;
 cof;
 don;
 eon;
 fof;
 gon;
}

void three(){
 aon;
 bon;
 con;
 don;
 eof;
 fof;
 gon;
}
void four(){
 aof;
 bon;
 con;
 dof;
 eof;
 fon;
 gon;
}

void five(){
 aon;
 bof;
 con;
 don;
 eof;
 fon;
 gon;
}

void six(){
 aon;
 bof;
 con;
 don;
 eon;
 fon;
 gon;
}

void seven(){
 aon;
 bon;
 con;
 dof;
 eof;
 fof;
 gof;
}

void eight(){
 aon;
 bon;
 con;
 don;
 eon;
 fon;
 gon;
}

void nine(){
 aon;
 bon;
 con;
 don;
 eof;
 fon;
 gon;
}


void comp1(){

if(digit==0)zero();
if(digit==1)one();
if(digit==2)two();
if(digit==3)three();
if(digit==4)four();
if(digit==5)five();
if(digit==6)six();
if(digit==7)seven();
if(digit==8)eight();
if(digit==9)nine();

 DELAY_MS(1);

}



void mux(){
d1_on;digit=thu;comp1();d1_of;
d2_on;digit=ten;comp1();d2_of;

d3_on;digit=unit;comp1();d3_of;


//d3_on;digit=unit;comp1();d3_of;

}


void mdelay()
{
mux();mux();//mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
//mux();mux();mux();mux();
//mux();mux();mux();mux();

}



void getad(){
      int32   result=0;int8 i;
     SET_ADC_CHANNEL(3);
//       for(i=0;i<2;i++)
 //  {
  //   delay_ms(1);
 mux(); mux();mux();mux(); mux();mux();
 result=read_adc();
//}
   val2=result;

  //   value = (int8) (read_adc() * 500)/1023;
//val2 = read_adc ();
  value =   (val2* 5000)/1023;

 thu = (value/1000); mux(); mux();mux();mux(); mux();mux();

 ten = (value/100)%10; mux(); mux();mux();mux(); mux();mux();
 unit = (value/10)%10; mux(); mux();mux();mux(); mux();mux();


/*
putc(thu+48);
putc(ten+48);
putc(unit+48);
 unit = value%10;
putc(unit+48);
putc(10);putc(13);
*/


}

void main ()
{

 DELAY_MS(1);
/*
 //SETUP_ADC_PORTS(NO_ANALOGS);
//   set_tris_a(0);

   set_tris_c(0x00);
   setup_comparator(NC_NC_NC_NC);
   setup_adc_ports(sAN0 | VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);

setup_adc(ADC_CLOCK_INTERNAL );


 set_tris_c(0x00);
     set_tris_a(0xff);
     set_tris_a(0b00011001);
    

  setup_comparator(NC_NC_NC_NC);  
   setup_adc_ports( sAN3 | VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64);
     set_tris_a(0b00011001);



zero();
//DELAY_MS(1000);

while(1)
 {
// DELAY_MS(10);
//pwmd();

getad();

mdelay();



}


Home work

งานที่ 14

PIC16F84A


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

งานที่2

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