اطلاعیه

Collapse
No announcement yet.

مشکل در ریجیستر های تایمر 1

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

    مشکل در ریجیستر های تایمر 1

    سلام دوستان
    من دارم زمان یک پالس رو با تایمر 1 اندازه میگیرم . کلاک تایمرم هم روی 1 مگ تنظیم شده . برنامم به این شکل که با پالس مورد نظر را به وقفه دادم و تو لبه بالا رونده ریجستر های TCNT1L=0x00 TCNT1H=0x00 برابر صفر قرار میدهم و توی لبه پایین رونده اطلاعات ریجستر هارو برداشت می کنم. ریجستر پایین درست کار می کنه اما ریجستر باللایی همیشه صفر هستش . مثلا اگه پالسم 600 میکرو ثانیه باشه رجیستر پایینی 0b01011000 را که عدد88 هستش رو نشون میده اما ریجستر بالایی که باید عدد 2 را نشون بده ، صفر هستش .
    لطفا کمکم کنید چون کارم گیره
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    TCNT1H=0x00;
    TCNT1L=0x00;


    }

    // External Interrupt 1 service routine (falling edge)
    interrupt [EXT_INT1] void ext_int1_isr(void)
    {
    p1=TCNT1H;
    p2=TCNT1L;


    }
    آنکس که بداند و بداند که بداند /، اسب شرف از گنبد گردون بجهاند
    آنکس که بداند و نداند که بداند / ، بيدارش نماييد که بسي خفته نماند
    آنکس که نداند و بداند که نداند / ، لنگان خرک خويش به مقصد برساند
    آنکس که نداند و نداند که نداند / ، در جهل مرکب ابدالدهر بماند

    #2
    پاسخ : مشکل در ریجیستر های تایمر 1

    با سلام
    خوب من فکر میکنم این مسئله به خاطر نوع دسترسی شما به رجیستر 16 بیتی تایمر 1 هست خوب avr072 در رابطه با دسترسی به رجیستر های 16 بیتی میگه :

    تمام مدل های متوسط و بزرگ خانواده avr حداقل دارای یک تایمر 16 بیتی به همراه تعدادی کانال adc می باشند.
    این ماژول ها دارای رجیستر های 16 بیتی می باشند که هسته AVR می تونه با استفاده از دستورالعمل های اسمبلی IN , OUT به آن ها دسترسی داشته باشد. از طرفی ازآنجا که دیتا باس AVR ، 8 بیتی می باشد هسته CPU برای دسترسی به این رجیسترها به دوسیکل ماشین احتیاج دارد . توجه کنید که یک اینتراپت میتونه در بین همین دو دستور اتفاق بیوفته حال اگر تابع اینتراپت به همین منابع یعنی رجیستر های 16 بیتی تایمر یک و یا مثلا ADC باشد برای جلوگیری از ، از دست رفتن اطلاعات مورد نظر مان در این رجیسترها باید برنامه مان طوری باشد که دسترسی به این رجیسترها به صورت هسته ای باشد به عبارت دیگر باید یک عمل خواندن و نوشتن در این رجیستر ها اینتراپت ناپذیر باشد . تمام رجیسترهای I/O شانزده بیتی دارای یک رجیستر موقت برای دسترسی به 8 بیت بالای این رجیستر ها 16 بیتی می باشند توجه کنید که یک تایمر 16 بیتی مثل تایمر 1 در مگا 16 تنها دارای یک رجیستر موقت برای تمام 16 بیت رجیسترش می باشد .

    معمولا یک رجیستر 16 بیتی به صورت زیر خوانده می شود :


    Cycle 1: in r16, TCNT1L ;Reading low byte into r16,this triggers the high
    ; byte to be latched in the temporary shadow
    ; register.
    Cycle 2: in r17, TCNT1H ;Reading high byte from the temporary register.


    در مثال فوق اگر در بین دو دستور یک اینتراپپ حال به هر دلیلی رخ دهد و روتین تابع به هر کدام از بایت های رجیستر تایمر یک دسترسی داشته باشد این امکان وجود دارد که رچیستر موقت مقدار خودش را تغییر دهد که این امر باعث می شود که CPU در زمان برگشت از وقفه مقدار اشتباه را در داخل R17 بارگزاری کند.

    در تصویر زیر نحوه خواندن اطلاعات در رجیستر 16 بیتی تایمر یک نشان داده شده است :

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

    عمل نوشتن در رجیستر 16 بیتی تایمر 1 نیز به ترتیب زیر انجام میشود :


    ;r17 contains the high byte while r16 contains
    ;the low byte that is to be written.
    Cycle 1: out TCNT1H, r17 ;Writing the high byte to the temporary register.
    Cycle 2: out TCNT1L, r16 ;Writing both the low byte and the temporary
    ;register into the I/O Register.


    در تصویر زیر نحوه نوشتن اطلاعات در داخل رجیستر 16 بیتی تایمر1 نشان داده شده است :

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

    توجه کنید که عمل خواندن و نوشتن در رجیستر 16 بیتی تایمر 1 در شکل دسترسی به بایت بالا و پایین با هم فرق می کند که اگر این ترتیب معکوس شود اطلاعاتی که در بایت بالا نوشته و یا خوانده می شود ناصحیح خواهد بود .

    راه حل :

    برای اجتناب نمودن از حالات فوق می توان از ماکرو های زیر در اسمبلر AVR و کامپایلر IAR در زبان C استفاده نمود :

    ماکرو ها اسمبلی برای خواندن و نوشتن در رجیستر 16 بیتی :

    .macro outw
    cli
    out @0, @1
    out @0-1, @2
    sei
    .endmacro
    .macro inw
    cli
    in @1, @2-1
    in @0, @2
    sei
    .endmacro


    نحوه استفاده از ماکرو های فوق در برنامه اسمبلی :

    .include “8515def.inc”
    inw r17, r16, TCNT1H ; Reads the counter value (high, low, adr)
    outw TCNT1H, r17, r16 ; Writes the counter value (adr, high, low)


    ماکرو های زبان C برای خواندن و نوشتن در رجیستر 16 بیتی :

    IAR C MACROS
    #include <ina90.h>
    #define outw( ADDRESS, VAL )\
    {\
    _CLI();
    ADDRESS = VAL;\
    _SEI();\
    }
    #define inw( ADDRESS, VAL )\
    {\
    _CLI();
    VAL = ADDRESS;\
    _SEI();\
    }


    نحوه استفاده از ماکرو های فوق در زبان C :

    #include <io8515.h>
    inw( TCNT1, i ) ;/* Reads the counter value */
    outw( TCNT1, i ) ;/* Writes the counter value */


    : Notes

    1. The outw and the inw macros uses four instruction cycles which is the same amount
    of cycles as the ret instruction uses. Doing so the macros will not increase the worst
    case interrupt response time.
    2. The macros will not work for setting the EEPROM address since the address can not
    be changed during write operation. This will lead to corruption of the data written.



    پایان AVR072


    نتیجه اینکه شما باید اول بایت پایین رو بخونی و بعد بایت بالا رو !

    دیدگاه


      #3
      پاسخ : مشکل در ریجیستر های تایمر 1

      درود فراوان بر دوست گرامی
      واقعا دکارت درسته انگار که رفتی داخله میکرو همه چیو دیدی . واقعا ممنونم و دستت درد نکنه
      آنکس که بداند و بداند که بداند /، اسب شرف از گنبد گردون بجهاند
      آنکس که بداند و نداند که بداند / ، بيدارش نماييد که بسي خفته نماند
      آنکس که نداند و بداند که نداند / ، لنگان خرک خويش به مقصد برساند
      آنکس که نداند و نداند که نداند / ، در جهل مرکب ابدالدهر بماند

      دیدگاه


        #4
        پاسخ : مشکل در ریجیستر های تایمر 1

        دوست عزیز گفتم که این ها توی appnote های atmel نوشته شده ، اگه دوست داشتی من چندتا appnote رو بررسی کردم و دریافت هام رو توی تایپیک زیر نوشتم :

        http://www.eca.ir/forum2/index.php?topic=53745.0

        دیدگاه


          #5
          پاسخ : مشکل در ریجیستر های تایمر 1

          سلام.
          منم دقیقا همین مشکل رو دارم.
          توی codevision رجیستر ICR1 به صورت ICR1H , ICR1L تعریف شده و اصلا ICR1 براش نا مفهومه . حالا برای دسترسی به کل ICR به شیوه ماکرویی که تعریف کردید باید چی کار کنم ؟
          میشه برم توی هدر فایل meha16.h و اونجا چیزی رو دستکاری کنم ؟

          دیدگاه


            #6
            پاسخ : مشکل در ریجیستر های تایمر 1

            دلیل اینکه مقدار رجیستری که میخونید صفره اینکه رجیسترTCNT1 به صورت TEMP هست.

            میکروکنترلر برای اطمینان از اینکه هر دو بایت بالا وپایین به طور هم زمان در در اختیار cpu قرار میگیره یه رجیستر موقت (TEMP) رو به کار میگیره.

            بحث طولانی داره بنابراین من فقط نحوی خوندن و نوشتن در این نوع رجیسترهای دو بایتی رو میگم:

            در حالتی که میخوایم دیتایی توی این رجیستر بنویسیم ابتدا باید دیتا رو تو رجیسترTCNT1H بریزیم و بعد در TCNT1L

            در حالتی که میخوایم دیتایی رو از این رجیستر بخونیم ابتدا باید TCNT1L بخونیم وبعد TCNT1H
            [glow=red,2,300]گرد هم آمدن شروع است.با هم ماندن پيشرفت است.با هم کار کردن موفقيت است.[/glow]
            [img width=98 height=100]http://s3.picofile.com/file/7407857311/icon3.png[/img]

            دیدگاه

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