Tuesday, September 14, 2010

Microcontroller II


โปรแกรมรอง จะเป็นโปรแกรมที่ทำการอ่านค่าของระดับน้ำและ อุณหภูมิและ แสดงค่าออกทางส่วนแสดงผล
การอ่านค่าจากเซนเซอร์นั้นมีการกำหนดให้อ่านค่าทุกๆ 200 ms ดังนั้นจึงต้องมีการเขียน Software timer เพื่อนำมาใช้งาน
           
                Software timer เป็นการเขียนโปรแกรมขึ้นมาเพื่อทำการจำลองการทำงานของ hardware timer ซึ่งมีจำนวนจำกัด การเขียน software timer นั้นจะต้องสร้างฐานเวลาขึ้นมาให้มีการinterrupt ทุกๆ 1 หน่วยเวลาที่คงที่ จากนั้นให้มีการนับจนถึงค่าที่ตั้งไว้แล้วให้ ตัวแปรมีค่าเพิ่มขึ้นเพื่อ ใช้เช็คว่านับถึงค่าแล้วสำหรับเป็นเงื่อนไขในการเข้าไปทำงาน
Software timer code

                struct softwaretimerstruct
{
   int TmrEn;
   int16 TmrCnt;
   int16 TmrInt;
   int TmrRdy;
   int TmrErr;
   int TmrMod;
};
struct softwaretimerstruct stmr[6];  
void softwaretimer()
{
   int n;
   for(n=0;n<6;n++)
   {
      if(stmr[n].TmrEn==1)
      {
         stmr[n].TmrCnt--;
         if(stmr[n].TmrCnt==0)
         {
            if(stmr[n].TmrRdy==0)
            {
               stmr[n].TmrErr=1;
            }
            stmr[n].TmrRdy++;
            stmr[n].TmrCnt=stmr[n].TmrInt;
            if(stmr[n].TmrErr==0)
            {
               stmr[n].TmrEn=0;
            }
         }
       }
   }
}


การจะอ่านค่าจากเซนเซอร์นั้นจะต้องใช้งานฟังก์ชั่น Analog to Digital CCS C complier นั้นมี built in function สำหรับใช้งานอยู่แล้ว
                setup_adc_ports();        เป็นฟังก์ชั่นที่ใช้ในการตั้งค่าว่าจะให้ port ไหนบ้างทำหน้าที่เป็น ADC port และ ใช้อะไรเป็น voltage reference
            setup_adc();                เป็นฟังก์ชั่นที่ใช้ในการตั้งค่า ADC clock
            set_ADC_channel();    ใช้ในการเลือกช่องที่ใช้ในการทำงานเป็น ADC ณ ขณะนั้น
                Read_ADC()                ใช้ในการอ่านค่าของ ADC แล้วนำค่าไปเก็บไว้ที่ตัวแปร



การสื่อสารระหว่าง โปรแกรมหลัก และ โปรแกรมรอง นั้นจะใช้ I2C Bus ใน CCS C complier นั้น มี built in function อยู่แล้วโดยฟังก์ชั่นในการใช้งาน
                ในโปรแกรมหลัก จะ ใช้คำสั่ง
                I2C_Start ();                ใช้เพื่อเริ่มการสื่อสารของ I2C Bus
            I2C_Stop ();                ใช้เพื่อหยุดการสื่อสารของ I2C Bus
            i2c_write ();                 ใช้เพื่อส่งค่าไปยังMCU ตัวอื่นๆบนบัสสื่อสาร
                i2c_read ();                  ใช้เพื่อรับค่าจาก MCU ตัวอื่นๆบนบัสสื่อสาร

ในโปรแกรมหลักนั้นจะต้องมีการประกาศให้เป็น Master on bus และ ตั้งค่าขา SDA และSCL ด้วยคำสั่ง
#use i2c(master, scl = ,sda =)

            ในโปรแกรมรองจะใช้คำสั่ง
                i2c_write ();                 ใช้เพื่อส่งค่าไปยังMCU ตัวอื่นๆบนบัสสื่อสาร
                i2c_read ();                  ใช้เพื่อรับค่าจาก MCU ตัวอื่นๆบนบัสสื่อสาร
                i2c_isr_state ();         ใช้เพื่อตรวจสอบว่า โปรแกรมหลักต้องการ ส่งค่ามาให้หรือ ต้องการให้ส่งค่ากลับไป
ในโปรแกรมรองนั้นจะต้องมีการประกาศให้เป็น  Slave on bus และ ตั้งค่า address ,ขา SDA และSCL ด้วยคำสั่ง
#use i2c(slave,scl = ,sda = ,address = )                                                           

การเขียนโปรแกรมนั้นจะต้องเขียนไว้ ใน ssp interrupt เนื่องจากว่า โปรแกรมรองนั้น ไม่สามารถที่จะส่งหรือรับค่าอย่างอิสระบน บัสได้ต้องให้ โปรแกรมหลักนั้นส่งคำสั่งมาแล้วเกิดการ interrupt ขึ้นแล้วทำการรับหรือส่งค่ากลับไป
เช่น
#int_ssp
void ssp_interrupt()
{
   BYTE incoming, state,n=0;
   state = i2c_isr_state();
   if(state < 0x80)     // Master is sending data
   {
      if(state==0)
      {
        incoming = i2c_read();
      }
   }
  if(state==0x80)
   {
      if(n==0)
      {
         i2c_write(wlv.wlv8[0]);
         n=1;
      }
      if(n==1)
      {
         i2c_write(wlv.wlv8[1]);
         n=2;
      }
      if(n==2)
      {
         i2c_write(tmp.tmp8[0]);
         n=3;
      }
      if(n==3)
      {
         i2c_write(tmp.tmp8[1]);
         n=0;
      }
   }
}
                การสื่อสารบน I2C นั้นจะสามารถส่งค่าได้เพียงครั้งละ 1 Byte ดังนั้นหากเราต้องการให้ส่ง รับข้อมูลที่มีขนาดใหญ่เกินกว่า 1 Byte เราจำเป็นต้องใช้การประกาศให้เป็นตัวแปร แบบ union ก็จะสามารถทำให้ส่งรับค่าได้เพราะการประกาศตัวแปรแบบ union นั้นจะทำให้ตัวแปรสองตัวเก็บค่าไว้ที่หน่วยความจำตำแหน่งเดียวกัน
union waterlevel
{
     int16 wlv16;
     int   wlv8[2];
};
union waterlevel wlv;  


โปรแกรมที่ใช้ควบคุม DC motor
            โปรแกรมจะรับค่า 1-5 V จากโปรแกรมหลักแล้วทำการหมุน มอเตอร์ ให้ได้ตำแหน่งโดยตรวจสอบจาก สัญญาณที่ป้อนกลับเข้ามา

No comments:

Post a Comment