ผมอยากลองสร้าง LC Meter ครับ

Started by gajidirdz, June 13, 2013, 11:14:15 PM

Previous topic - Next topic

RoLRoR

เห็นตอนแรกใช้ CCS ก็จะประมาณนี้ครับ

#include <16f877a.h>
...

volatile unsigned int32 cnt_value;
...

#int_TIMER1
void  TIMER1_isr(void)
{ cnt_value += 65536;
}

void main(void)
{ unsigned int32 sum_value;
...

setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
...

enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

while(1)
{
delay_ms(1000);
sum_value = get_timer1(); set_timer1(0);
sum_value += cnt_value; cnt_value = 0;

...
printf(...,...,sum_value);
}
}

gajidirdz

Quote from: RoLRoR on August 29, 2013, 04:36:45 AM
เห็นตอนแรกใช้ CCS ก็จะประมาณนี้ครับ

#include <16f877a.h>
...

volatile unsigned int32 cnt_value;
...

#int_TIMER1
void  TIMER1_isr(void)
{ cnt_value += 65536;
}

void main(void)
{ unsigned int32 sum_value;
...

setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
...

//enable_interrupts(INT_TIMER1);
//enable_interrupts(GLOBAL);

while(1)
{ cnt_value = 0;
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

delay_ms(1000);
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);

sum_value = get_timer1();
sum_value += cnt_value;

...
printf(...,...,sum_value);
}
}


ขอบคุณสำหรับคำแนะนำครับ แต่ทำไมค่ามันถึงขึ้นๆลงๆ ไม่แน่นอนอ่ะครับ

RoLRoR

โปรแกรมแบบใช้ Timer1 เป็นเคาน์เตอร์ และใช้ Timer2 เป็น ฐานเวลาครับ
::: เพิ่มเติม ::: แก้เป็น @ crystal 20MHz ให้ละ

#include <16f877a.h>
...

volatile unsigned int32 f_count;
volatile unsigned int32 t1_count;
volatile unsigned char  t2_count;
volatile unsigned char  t2_ovf;
...

#int_TIMER1
void  TIMER1_isr(void)
{ t1_count += 65536;
}

#int_TIMER2
void  TIMER2_isr(void)
{ if(++t2_count > 79) // Overflow 1000ms
{ f_count = get_timer1(); set_timer1(0); // Fetch Timer1
f_count += t1_count; t1_count = 0; // Sum. Timer1 Overflow
t2_count = 0; t2_ovf = 1; // Clear/Set
}
}

void main(void)
{
...

setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); // External Clock
//setup_timer_2(T2_DIV_BY_16,234,16); // Overflow 20ms @12MHz
setup_timer_2(T2_DIV_BY_16,245,16); // Overflow 12.5ms @20MHz

enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

while(1)
{
if(t2_ovf)
{ t2_ovf = 0;

...
printf(...,...,f_count);
}
}
}


ทำไมใช้ x'tal 12MHz หรือครับ หรือลองใช้ x'tal ความถี่สูงๆ ดู ช่วยได้ไหม. ลองเอาไปปรับใช้ดูนะ
ค่าที่อ่านได้ไม่ตรง. calibrate โดยปรับเปลี่ยนฐานเวลา timer2 หรือใส่ c-var จูน x'tal osc เอาครับ โปรแกรมคงมีเท่านี้.

ความถี่ขึ้น-ลง ค่าใดครับ? ท่านว่าน่าจะมาจากไหนได้บ้าง จากสัญญาณที่เราไปวัด หรือจากโปรแกรมอ่านค่า ก็ได้.?


gajidirdz

Quote from: RoLRoR on August 31, 2013, 07:19:57 PM
#include <16f877a.h>
...

volatile unsigned int32 f_count;
volatile unsigned int32 t1_count;
volatile unsigned char  t2_count;
volatile unsigned char  t2_ovf;
...

#int_TIMER1
void  TIMER1_isr(void)
{ t1_count += 65536;
}

#int_TIMER2
void  TIMER2_isr(void)
{ if(++t2_count > 49) // Overflow 1000ms
{ f_count = get_timer1(); set_timer1(0); // Fetch Timer1
f_count += t1_count; t1_count = 0; // Sum. Timer1 Overflow
t2_count = 0; t2_ovf = 1; // Clear/Set
}
}

void main(void)
{
...

setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); // External Clock
setup_timer_2(T2_DIV_BY_16,234,16); // Overflow 20ms @12MHz

enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);

while(1)
{
if(t2_ovf)
{ t2_ovf = 0;

...
printf(...,...,f_count);
}
}
}


ทำไมใช้ x'tal 12MHz หรือครับ หรือลองใช้ x'tal ความถี่สูงๆ ดู ช่วยได้ไหม.
ลองเอาไปปรับใช้ดูนะ ปรับเปลี่ยนฐานเวลา timer2 หรือใส่ c-var จูน x'tal osc เอาครับ
โปรแกรมคงมีเท่านี้.

ความถี่ขึ้น-ลง ค่าใดครับ? ท่านว่าน่าจะมาจากไหนได้บ้าง จากสัญญาณที่เราไปวัด หรือจากโปรแกรมอ่านค่า ก็ได้

มันก็ไม่ได้ขึ้น-ลง อะไรหรอกครับ แต่ผมว่าน่าจะมาจากการที่ประกาศ delay_ms() อ่ะครับ เพราะถ้าผมป้อนสัญญาณ 100kHz ผมที่ได้คือ 100,000 Hz และ 100,333 อะไรประมาณนี้แหละครับ ผมว่าน่าจะเกิดจากตรงนี้ อย่างที่ท่านแนะนำอะครับ ที่การใช้ timer ไม่ควรหน่วงเวลาโดยใช้ delay ^^ ขอบพระคุณมากครับ จะลองไปปรับแก้ดูนะครับ
ส่วนเรื่อง Xtal ใช้ 20MHz อยู่ครับ ถ้าได้ผลอย่างไร จะนำมาแจ้งนะครับ ขอบคุณมากครับ

gajidirdz

ตอนนนี้ผมทำได้แล้วนะครับ ข้างล่างนี้คือ โค๊ดของโปรแกรม

#include <16f877a.h>
#use delay(clock=20M)
#include <LCD.c>
#fuses hs,nowdt,nocpd,nolvp,noprotect




unsigned int32 cnt_value;
   
#int_TIMER1
void  TIMER1_isr(void)
{   cnt_value += 65536;
}
void C()
{   unsigned int32 FC;
   float ans1,ans2,ans3,ans4,F1,F2;
    F1=672500;
   lcd_init();
   lcd_gotoxy(1,1);
      printf(lcd_putc,"LC Meter");

   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
      while(1)
   {
      delay_ms(1000);
      FC = get_timer1();   set_timer1(0);
      FC += cnt_value;      cnt_value = 0;
      ans1=FC*0.0920022502;
      F2=FC-ans1;
     
      ans2=F1/F2;
      ans3=ans2*ans2;
      ans4=ans3-1;
     
      if (ans4>10000)
      {   lcd_gotoxy(1,1);
         printf(lcd_putc,"LC Meter");
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Choose Mode");
      }
      else
     {
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Capacitance");
         lcd_gotoxy(1,2);
         printf(lcd_putc,"C = %3.2f nF",F2);
     }

     
     
            if (input(pin_A0)==0)
         {
            break; 
   }
}
}

void L()
{   unsigned int32 FL;
   float ans5,ans6,ans7,ans8,ans9,ans10,F3,F4;
    F3=672500;
   
   lcd_init();
   lcd_gotoxy(1,1);
      printf(lcd_putc,"Inductance");

   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
      while(1)
   {
      delay_ms(1000);
      FL = get_timer1();   set_timer1(0);
      FL += cnt_value;      cnt_value = 0;
      ans5=FL*0.096322502;
      F4=FL-ans5;
      ans6=F3/F4;
      ans7=ans6*ans6;
      ans8=ans7-1;
      ans9=ans8*56;
     
      if(ans9>10000)
      { lcd_gotoxy(1,2);
         printf(lcd_putc,"L = 0.00 uH");
      }
      else
      {
         lcd_gotoxy(1,2);
         printf(lcd_putc,"L = %3.2f uH",ans9);
      }

     
       if (input(pin_A0)==1)
     
         {
            break; 
   }
   }
}

    void main(void)

while(true)
{
         
         if (input(pin_A0)==1)
         {
            C();
         }
         
         else
         {
            L();
         }
         
         
         
}         

}

โปรแกรมนี้ใช้หลักการนับความถี่จาก LC - Oscillator จากที่ท่าน RoLRoR แนะนำนะครับ แล้วนำมาคำนวณโดยใช้สูตร และแสดงผลออกทาง LCD
มีการใช้ sw dpdt 3 ทาง หวังว่าจะเป็นประโยชน์ต่อทุกคนนะครับ

gajidirdz

ผมมีอีกเรื่องอยากจะปรึกษาครับ

http://electronics-diy.com/lc_meter.php

อยากทราบถึงหลักการวิเคราะห์ตัว comparator ic lm311 อ่ะครับ ว่าทำการกำเนิดสัญญาณสี่เหลี่ยมได้อย่างไร และทำให้เกิดคาบได้อย่างไร

RoLRoR

เยี่ยมครับ. ยินดีด้วยที่ได้ทดลองได้สำเร็จครับ  :D

เรื่อง comparator เปรียบเทียบแรงดัน.ระหว่างขาบวกกับลบ เป็นคุณสมบัติพื้นฐานของ opamp อยู่แล้ว
ถ้าขาบวก มีแรงดันมากกว่า ขาลบ output ออก hi
และในทางกลับกัน output ก็ออก low.

ส่วนเรื่อง opamp frequency oscillator ผมยังไม่แน่น รอพี่ๆเพื่อนๆมาตอบให้ต่อนะครับ  ;D

gajidirdz

http://microcontrollers.2385.n7.nabble.com/Nodal-analysis-of-an-OPamp-oscillator-td31406.html

ช่วยอธิบายการทำงานนะครับ ผมไม่เก่งภาษาอังกฤษ  :'(