اطلاعیه

Collapse
No announcement yet.

مشکل برنامه ADC زیر با تایمر چی هست ؟

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    مشکل برنامه ADC زیر با تایمر چی هست ؟

    با سلام برنامه ای نوشتم که میخوام هر 1 یک دقیق یکبار ورودی adc0 رو بخونه که همون vkey هست اما برنامه کار نمیکنه ممنون میشم راهنمایی کنید :


    #include <mega16.h>
    #include <delay.h>

    #define ADC_VREF_TYPE 0x40
    // Read the AD conversion result
    float vkey;
    // Timer1 overflow interrupt service routine


    unsigned int read_adc(unsigned char adc_input)
    {
    ADMUX=adc_input|ADC_VREF_TYPE;
    // Start the AD conversion
    ADCSRA|=0x40;
    // Wait for the AD conversion to complete
    while ((ADCSRA & 0x10)==0);
    ADCSRA|=0x10;
    return ADCW;
    }

    interrupt [TIM1_OVF] void timer1_ovf_isr(void)
    {


    vkey=read_adc(0);
    vkey=(vkey*5)/1024;


    }

    void main(void)
    {

    TCCR1A=0x00;
    TCCR1B=0x05;
    TCNT1H=0x1B;
    TCNT1L=0x1E;

    DDRB.0=1;
    DDRB.1=1;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x04;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;

    // ADC initialization
    // ADC Clock frequency: 15.625 kHz
    // ADC Voltage Reference: AVCC pin
    // ADC Auto Trigger Source: None
    ADMUX=ADC_VREF_TYPE & 0xff;
    ADCSRA=0x86;

    // Global enable interrupts
    #asm("sei&quot

    while (1)
    {
    TCCR1B=0x05;
    vkey=(vkey*5)/1024;

    if(vkey<1.80)
    {
    PORTB.0=1;
    PORTB.1=0;
    }
    else if(vkey>3.5)
    {
    PORTB.0=0;
    PORTB.1=1;
    }

    };
    }


    اضافه شده در تاریخ :
    لطفا راهنمایی کنید .

    #2
    پاسخ : مشکل برنامه ADC زیر با تایمر چی هست ؟

    سلام
    دوست عزیز من به صورت عجله ایی به برنامت یه نگاه انداختم شما دو بار مقدار vkey رو تبدیل کردین یه با تو حلقه یه بار تو روتین تایمر حالا شما این یکی رو تو while پاک کنید
    اینو میگم:
    [code=c]vkey=(vkey*5)/1024; [/code]
    [img width=281 height=100]http://cdn.persiangig.com/preview/acPBCNLNNr/images.jpg[/img]

    دیدگاه


      #3
      پاسخ : مشکل برنامه ADC زیر با تایمر چی هست ؟

      پاک کردم جواب نداد !!

      اضافه شده در تاریخ :
      واقعا اینقدر سخته این برنامه که همه نگاه میکنن ولی نمیتونن جواب بدن !!!

      دیدگاه


        #4
        پاسخ : مشکل برنامه ADC زیر با تایمر چی هست ؟

        بنده کدویژن کار نیستم ولی این کد کارتو راه میندازه هر 100 میلی ثانیه مقدار adc رو میگیره:
        [code=c]
        #include <mega16.h>
        #include <delay.h>

        #define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))

        // Read the AD conversion result
        unsigned int read_adc(unsigned char adc_input)
        {
        ADMUX=adc_input | ADC_VREF_TYPE;
        // Delay needed for the stabilization of the ADC input voltage
        delay_us(10);
        // Start the AD conversion
        ADCSRA|=(1<<ADSC);
        // Wait for the AD conversion to complete
        while ((ADCSRA & (1<<ADIF))==0);
        ADCSRA|=(1<<ADIF);
        return ADCW;
        }
        float vkey;
        void main(void)
        {


        DDRC = 0XFF;
        DDRB.0=1;
        DDRB.1=1;

        ADMUX=ADC_VREF_TYPE;
        ADCSRA=(1<<ADEN) | (0<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
        SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);

        ASSR=0<<AS2;
        TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (1<<CS22) | (1<<CS21) | (1<<CS20);
        TCNT2=0x9E;
        OCR2=0x00;

        // Timer(s)/Counter(s) Interrupt(s) initialization
        TIMSK=(0<<OCIE2) | (1<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0);

        // Global enable interrupts
        #asm("sei&quot

        while (1)
        {
        if(vkey<1.5)
        {
        PORTB.0=1;
        PORTB.1=0;
        }
        else if(vkey>3.8)
        {
        PORTB.0=0;
        PORTB.1=1;
        }

        };
        }

        interrupt [TIM2_OVF] void timer2_ovf_isr(void)
        {
        // Reinitialize Timer2 value
        TCNT2=0x9E;
        // Place your code here
        PORTC = ~PORTC;
        TCCR1B=0x05;
        vkey = read_adc(0);
        vkey=(vkey*5)/1024;
        }[/code]
        در ضمن پایه avcc و aref رو به 5 ولت بده.
        [img width=281 height=100]http://cdn.persiangig.com/preview/acPBCNLNNr/images.jpg[/img]

        دیدگاه


          #5
          پاسخ : مشکل برنامه ADC زیر با تایمر چی هست ؟

          این کد رو ببین یکمیییی تغییرش دادم فقط برو ببین ریجستر هاش درسته یا نه چون نگاه نکردم
          و این که تایمر 1، رو بزار رو 1 میگ، و مثلا هر سر ریزش میشه 10 میلی ثانیه، تو تابع وقفه سرریز یه متغییر تعریف کن و بگو هر موقع x تا سر ریز رخ داد(که این x تا ضربدر 10میلی ثانیه بشه 1 ثانیه، یعنی زمان مد نظرت)، و هر موقع این مقدار 1 ثانیه شد بیا و تابع Calculate رو فراخونی کن
          اشتباهی اگه هم تو کد ها هستش خودت کامپایل کن و خطا گیری کن چون من کاپایل نکردم و فقط یکم تغییر دادم
          [code=c]#include <mega16.h>
          #include <delay.h>

          void Calculate(void);

          float vkey;

          #define ADC_VREF_TYPE 0x40
          unsigned int read_adc(unsigned char adc_input){
          ADMUX=adc_input|ADC_VREF_TYPE;
          // Start the AD conversion
          ADCSRA|=0x40;
          // Wait for the AD conversion to complete
          while ((ADCSRA & 0x10)==0);
          ADCSRA|=0x10;
          return ADCW;
          }

          interrupt [TIM1_OVF] void timer1_ovf_isr(void){
          Calculate();
          }

          void Calculate(void){
          vkey=read_adc(0);
          vkey=(vkey*5)/1023;

          if(vkey<1.80){
          PORTB.0=1;
          PORTB.1=0;
          }
          else if(vkey>3.5){
          PORTB.0=0;
          PORTB.1=1;
          }
          else{
          PORTB.0=1;
          PORTB.1=1;
          }
          }

          void main(void)
          {
          DDRB |= (1<<DDRB0) | (1<<DDRB1);

          TCCR1A=0x00;
          TCCR1B=0x05;
          TCNT1H=0x1B;
          TCNT1L=0x1E;
          TIMSK=0x04; // Timer(s)/Counter(s) Interrupt(s) initialization

          ACSR=0x80; // برای_کاهش_مصرف_جریان_مقایسه_گر_رو_غیر_فعال_میکنیم_

          // ADC initialization
          // ADC Clock frequency: 15.625 kHz
          // ADC Voltage Reference: AVCC pin
          // ADC Auto Trigger Source: None
          ADMUX=ADC_VREF_TYPE & 0xff;
          ADCSRA=0x86;

          #asm("sei&quot // Global enable interrupts

          while (1);
          }
          [/code]


          در خط 35 اون else رو برا این گزاشتم که :
          اینو_برا_این_گزاشتم_تا_مطمئن_بشی_برنامه_درست_کار
          میکنه چون دو حالت بالا تمام حالات رو پشتیبانی نمیکردن،
          بعد از اتمام برنامه و اطمینان از صحیحت برنامه میتونی
          این 2-3 خط کد راهنما رو پاک کنی
          اللَّهُمَّ صَلِّ عَلَى مُحَمَّدٍ وآلِ مُحَمَّدٍ وعَجِّلْ فَرَجَهُمْ

          اگه دوس دارید سریع به جواب برسید :
          1) قبل از پرسیدن سوال، بسرچید.
          2) سوالاتون رو با جزئیات کامل مطرح کنید.

          دیدگاه


            #6
            پاسخ : مشکل برنامه ADC زیر با تایمر چی هست ؟

            سلام برنامه جواب نمیده !!! تست کنید شما هم

            دیدگاه

            لطفا صبر کنید...
            X