วันอาทิตย์ที่ 3 ตุลาคม พ.ศ. 2553

Lab13: การวัด Position Encoder

จะใช้ Code นี้ได้ต้อง Copy QEI Lib เข้าไปไว้ใน 18F2431, 18F4431, 18F2331, 18F4331 แล้วแต่ว่าใช้เบอร์ไหน

#include <18F2431.h>
 #use delay(clock=20000000)
#fuses HS,PUT,BROWNOUT,MCLR,NOWDT,NOPROTECT,NOLVP
#define  TxD         PIN_C6  
#define  RxD         PIN_C7  
#use rs232(baud=115200, xmit=TxD,rcv=RxD)

void main()
{
   POSCNT = 0;
   MAXCNT = 0xFFFF;
   QEICON = 24;         // quad in x4 mode, resettable by maxcount

   enable_interrupts(GLOBAL);               
   enable_interrupts(INT_IC2QEI);


   while(true)
   {
printf("%lu\r\n", POSCNT);

}
}


Lab14: การวัด Velocity Encoder

#include <18F2431.h>
 #use delay(clock=20000000)
#fuses HS,PUT,BROWNOUT,MCLR,NOWDT,NOPROTECT,NOLVP
#define  TxD         PIN_C6  
#define  RxD         PIN_C7  
#use rs232(baud=115200, xmit=TxD,rcv=RxD)

void main()
{
   int16 pos1,pos2;
   float time;
   float Vel;

   POSCNT = 0;
   MAXCNT = 0xFFFF;
   QEICON = 24;         

   enable_interrupts(GLOBAL);               
   enable_interrupts(INT_IC2QEI);
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);

   while(true)
   {
set_timer1(0);
pos1 = POSCNT;
printf("%.3f\r\n", Vel);
pos2 = POSCNT;
time = get_timer1();
time = time*8*0.0000002;

  if(pos2>pos1){
      Vel = (float)(pos2 - pos1)/time;
       }
      else{
       Vel = (float)(pos1 - pos2)/time;
      }

}
}

Lab12: การใช้งาน MCP3201(Analog to Digital 12 bits)

#include <16F877.h>
#fuses HS,NOLVP,NOPROTECT,NOWDT
#use delay(CLOCK = 20000000)
#define use_portb_lcd
#use fast_io(A)
               
#define Vbe 0.0012210012210012210012210012210012     // Vref/4095(5/4095)

#define cs   PIN_A0                 // bit output. //
#define clkm PIN_A1                 // bit output. //
#define Dout PIN_A2                 // bit input. //


unsigned int16 Read_mcp3201()
{
   unsigned int16 digi;
   unsigned char z;
  
   output_high(cs);
   digi = 0;
   output_low(clkm);
   output_low(cs);
  
   //clock 1.//
   output_low(clkm);
   output_high(clkm);
   //clock 2.//
   output_low(clkm);
   output_high(clkm);
   //clock 3.//
   output_low(clkm);
   output_high(clkm);
  
   //clock 4-15.//  
       for(z=0;z<12;z++)
       {  
         output_low(clkm);
         output_high(clkm);
         digi = digi << 1;
         digi = digi | input(Dout);          
       }    
   output_high(cs);
   return(digi);
}

void main(void)
{
      unsigned int16 a;       // digi 12 bit. //
      float vol;              // volte type float. //
     
      set_tris_a(0xFC);       // set port output PINA0,PINA1 ||
      while(TRUE)
      {
         set_tris_a(0xFC);
         delay_ms(10);
         a = Read_mcp3201();
         vol = (a*Vbe);
      }    
}

Lab11: การใช้งาน MCP4922(Digital to Analog 12 bits)


การใช้งาน IC MCP4922 เป็น IC D to A ขนาด 12 bits ซึ่งสามารถหาซื้อได้ทั่วไปในเมืองไทย

#include <16F877A.h>
#DEVICE ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,  parity=N, Bits=8, xmit=PIN_C6, rcv=PIN_C7)

#define MCP4922_CS    PIN_B1
#define MCP4922_CLK   PIN_B2
#define MCP4922_DIN   PIN_B3
#define MCP4922_LDAC  PIN_B4
#define MCP4922_SHDN  PIN_B5

// กำหนดค่า Register ต่างๆ ของ MCP4922
#define MCP4922_DAC_A_BUFFERED_GAIN_1X_NON_SHDN      0x70  // DAC A, Buffered, Gain 1x, Output power control
#define MCP4922_DAC_A_BUFFERED_GAIN_2X_NON_SHDN      0x50  // DAC A, Buffered, Gain 2x, Output power control
#define MCP4922_DAC_A_NON_BUFFERED_GAIN_1X_NON_SHDN  0x30  // DAC A, Non buffered, Gain 1x, Output power control
#define MCP4922_DAC_A_NON_BUFFERED_GAIN_2X_NON_SHDN  0x10  // DAC A, Non buffered, Gain 2x, Output power control
#define MCP4922_DAC_B_BUFFERED_GAIN_1X_NON_SHDN      0xF0  // DAC B, Buffered, Gain 1x, Output power control
#define MCP4922_DAC_B_BUFFERED_GAIN_2X_NON_SHDN      0xD0  // DAC B, Buffered, Gain 2x, Output power control
#define MCP4922_DAC_B_NON_BUFFERED_GAIN_1X_NON_SHDN  0xB0  // DAC B, Non buffered, Gain 1x, Output power control
#define MCP4922_DAC_B_NON_BUFFERED_GAIN_2X_NON_SHDN  0x90  // DAC B, Non buffered, Gain 2x, Output power control

void mcp4922_init() {  //ฟังก์ชั่นเริ่มต้นการทำงาน
   output_high(MCP4922_CS);
   output_high(MCP4922_CLK);
   output_high(MCP4922_DIN);
   output_high(MCP4922_LDAC);
   output_high(MCP4922_SHDN);
}

void main()
{
   int8 cmd[2],i;              //ประกาศตัวแปร cmd, I เป็น integer 8 bits
   int16 data;                  //ประกาศตัวแปร data เป็น integer 16 bits
   mcp4922_init();           //กำหนดฟังก์ชั่นเริ่มต้นการทำงาน

   while(TRUE) {

   data =  4095;            //กำหนด data = 4095((4095 * 5)/(2^12-1) = 5 V)
   cmd[0]=data;              // cmd[0] = data 8 bits ล่าง
   cmd[1]=(data>>8)|MCP4922_DAC_B_BUFFERED_GAIN_1X_NON_SHDN;
                                    // cmd[0] = data 4 bits บน

   output_low(MCP4922_CS);               //เริ่มต้นการแปลงสัญญาณด้วย MCP4922
   output_low(MCP4922_CLK);
   output_high(MCP4922_LDAC);

   for(i=0;i<=15;i++) {
      output_bit(MCP4922_DIN,shift_left(cmd,2,1));
      output_high(MCP4922_CLK);
      output_low(MCP4922_CLK);
   }
   output_high(MCP4922_CS);
   output_low(MCP4922_LDAC);
   delay_us(10);
   output_HIGH(MCP4922_LDAC);
   delay_us(10);
    
  }
}

Lab10: การควบคุม DC MOTOR


การควบคุม DC MOTOR มีประโยชน์ในด้านสามารถควบคุมทิศทาง และความเร็วในการเคลื่อนที่ ซึ่งจะสามารถพัฒนาไปเป็นการควบคุมแบบป้อนกลับ (Feed Back Control)

#include<18F4431.h>
#define  CLOCK_SP    20000000 // ความเร็วสัญญาณนาฬิกา
#fuses HS                     //   โหมดการทำงานแบบ High Speed
#fuses NOLVP,NOWDT           // No Low Voltage Program, No Watchdog timer
#fuses NOPROTECT              // Code no protection
#use delay (clock=CLOCK_SP)   // ใช้งานฟังก์ชัน delay_ms() & delay_us()
#use rs232(baud=9600,xmit= PIN_C6,rcv= PIN_C7 ) // ใช้งาน module RS232

void forward(){
output_high(pin_c4);
output_low(pin_c5);
}           // ฟังก์ชันควบคุมการเคลื่อนที่ไปข้างหน้า
void backward(){
output_low(pin_c4);
output_high(pin_c5);
}          // ฟังก์ชันควบคุมการเคลื่อนที่ถอยกลับ
void stop(){
output_low(pin_c4);
output_low(pin_c5);
}          // ฟังก์ชันหยุดการเคลื่อนที่

void main(void){
 
    enable_interrupts(GLOBAL);           //เปิดการใช้งาน interrupt รวม
    enable_interrupts(INT_CCP1);         //เปิดการใช้งาน interrupt CCP1
    setup_ccp1(CCP_PWM);                 // กำหนดค่า CCP1 ทำงานโหมด PWM
    setup_timer_2(T2_DIV_BY_1, 255, 1);       //กำหนดค่า Timer2 ควบคุมความถี่ของ PWM
    set_timer2(0);                                               //กำหนดค่า Timer2 เป็น 0
  
while(true){

if(!input(pin_a0)){                     //ตรวจสอบ input pin a0 ถ้า Low (กด switch)
   forward();                              //เคลื่อนที่ไปข้างหน้า
   set_pwm1_duty(1000);         //กำหนดความเร็วโดยปรับ duty Cycle 0 - 1023
}
if(!input(pin_a1)){                     //ตรวจสอบ input pin a1 ถ้า Low (กด switch)
   backward();                          //เคลื่อนที่ถอยหลัง
   set_pwm1_duty(1000);         //กำหนดความเร็วโดยปรับ duty Cycle 0 - 1023
}
if(!input(pin_a2)){                     //ตรวจสอบ input pin a2 ถ้า Low (กด switch)
   stop();                                   //หยุดการเคลื่อนที่
}
}
}

Lab9: การควบคุม RC SERVO MOTOR


การใช้งาน RC SERVO MOTOR นั้นสามารถเขียนโปรแกรมได้หลายวิธี ยกตัวอย่างเช่น ใช้ Library “SERVOS.c” , การใช้งาน Power PWM โดยกำหนดค่า Frequency = 50 Hz และการใช้งานฟังก์ชัน Delay ง่ายๆ ในที่นี้ขอนำเสนอวิธีใช้งานฟังก์ชัน Delay

#include<18F4431.h>
#define  CLOCK_SP    20000000 // ความเร็วสัญญาณนาฬิกา
#fuses HS                     //   โหมดการทำงานแบบ High Speed
#fuses NOLVP,NOWDT           // No Low Voltage Program, No Watchdog timer
#fuses NOPROTECT              // Code no protection
#use delay (clock=CLOCK_SP)   // ใช้งานฟังก์ชัน delay_ms() & delay_us()
#use rs232(baud=9600,xmit= PIN_C6,rcv= PIN_C7 ) // ใช้งาน module RS232

void main(void){

while(true){

if(!input(pin_a0)){                      //ตรวจสอบ input pin a0 ถ้า Low (กด switch)
output_high(pin_b0);    
delay_us(2000);
output_low(pin_b0);
delay_ms(20);
//RC SERVO MOTOR หมุนที่ +90 องศา
}

if(!input(pin_a1)){          //ตรวจสอบ input pin a1 ถ้า Low (กด switch)
output_high(pin_b0);
delay_us(1000);
output_low(pin_b0);
delay_ms(20);
}
//RC SERVO MOTOR หมุนที่ -90 องศา

}
}

Lab8: การวัดค่า Duty Cycle (CCP1,CCP2)


#include<18F4431.h>
#define  CLOCK_SP    20000000 // ความเร็วสัญญาณนาฬิกา
#fuses HS                     //   โหมดการทำงานแบบ High Speed
#fuses NOLVP,NOWDT           // No Low Voltage Program, No Watchdog timer
#fuses NOPROTECT              // Code no protection
#use delay (clock=CLOCK_SP)   // ใช้งานฟังก์ชัน delay_ms() & delay_us()
#use rs232(baud=9600,xmit= PIN_C6,rcv= PIN_C7 ) // ใช้งาน module RS232

float time1,time2;
BOOLEAN hook_cpp1, HookRise;

#int_ccp1
void capture_isr()
{
   if(HookRise)
   {
    time1 = get_timer1();
    HookRise = FALSE;
   }
   else
   {
    time2 = get_timer1();
    HookRise = TRUE;
    hook_cpp1 = FALSE;                          //done
   }
}

// ฟังก์ชัน interrupt CCP1 เพื่อจับเวลาขอบขาขึ้นของสัญญาณ โดยเก็บเวลาที่ตัวแปร time1,time2

long rise,fall,pulse_width;

#int_ccp2
void isr()
{
   rise = CCP_1;
   fall = CCP_2;

   pulse_width = fall - rise;    
}
// ฟังก์ชัน interrupt CCP2 เพื่อจับเวลาขอบขาขึ้นของสัญญาณ และขอบขาลงของสัญญาณ โดยเก็บเวลาที่ตัวแปร rise, fall

void main(void)
{
   float T,F,width,duty;  //ประกาศตัวแปร T,F,width,duty เป็น floating point number

   while(true)
   {

      HookRise=TRUE;
      hook_cpp1=TRUE;
      setup_ccp1(CCP_CAPTURE_RE);           //กำหนดค่า CCP1 Capture ขอบขาขึ้น
      setup_ccp2(CCP_CAPTURE_FE);           //กำหนดค่า CCP2 Capture ขอบขาลง
      enable_interrupts(INT_CCP1);              // เปิดการทำงาน interrupt CCP1
      enable_interrupts(INT_CCP2);                   // เปิดการทำงาน interrupt CCP2
      enable_interrupts(GLOBAL);                // All interrupts ON
      set_timer1(0);                                             // กำหนดค่า Timer1 เป็น 0
      while(hook_cpp1==TRUE);                       //เงื่อนไขการตรวจสอบสัญญาณครบ 1 period
     
      setup_ccp1(CCP_OFF);                            //ปิดการทำงาน CCP1
      disable_interrupts (GLOBAL);                    //ปิดการทำงาน interrupt รวม
      
      T = (time2-time1)*0.0000002*8;                // Period time = cycle*(4/fosc)*PR
      width = (float)pulse_width / 5000000;            //width = pulse_width / (clock / 4)
      duty = (width*100)/T;                      //หาค่า Duty Cycle (T_on*100 / Period time)
     
      printf(“ %.3f\r\n",duty);                   //แสดงค่าผ่าน RS232
   
   }
}

Lab7: การใช้งาน CCP(Counter)


#include<18F4431.h>
#define  CLOCK_SP    20000000 // ความเร็วสัญญาณนาฬิกา
#fuses HS                     //   โหมดการทำงานแบบ High Speed
#fuses NOLVP,NOWDT           // No Low Voltage Program, No Watchdog timer
#fuses NOPROTECT              // Code no protection
#use delay (clock=CLOCK_SP)   // ใช้งานฟังก์ชัน delay_ms() & delay_us()
#use rs232(baud=9600,xmit= PIN_C6,rcv= PIN_C7 ) // ใช้งาน module RS232

int16 A;                                    //ประกาศตัวแปร time1,time2 เป็น floating point number
BOOLEAN hook_cpp1, HookRise;     //ประกาศตัวแปร hook_cpp1, HookRise เป็น Boolean

#int_ccp1
void capture_isr()
{
   if(HookRise)
   {
    A = A+1;
    HookRise = FALSE;
   }
}
// ฟังก์ชัน interrupt ในการตรวจสอบสัญญาณเข้า ให้นับขึ้นที่ 1 เก็บไว้ที่ตัวแปร A

void main(void){
  
   while(true){

      HookRise=TRUE;
      hook_cpp1=TRUE;
      setup_ccp1(CCP_CAPTURE_RE);           //กำหนดค่า CCP1(Capture)
      enable_interrupts(INT_CCP1);              // Enable interrupt CCP1
      enable_interrupts(GLOBAL);                // ตั้งค่า interrupt รวมทำงาน
      printf("%lu\r\n",A);              //แสดงค่าผ่าน RS232
   
   }
}