اطلاعیه

Collapse
No announcement yet.

اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

Collapse
این موضوع بسته شده است.
X
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

    تایمر های pic18f452 یا بصورت 8 بیتی کار میکنند یا 16 بیتی . ولی من میخواهم زمان صفر تا یک ثانیه را با دقت یک میکرو بسازم . یعنی اینکه بتوانم تاخیر تولید شده را با دقت یک میکرو ثانیه از صفر تا یک ثانیه بسازم . برای اینکار اگر بخواهم از تایمر استفاده کنم ، تایمر من باید 20 بیت داشته باشد . چون یک میلیون حالت میشود و یک میلیون در مبنای دو ، بیست بیت دارد . برای همین با یک تایمر 16 بیتی نمیتوانم کار کنم . به نظر شما استفاده از دستور delay_us معقول است ؟ چون شنیدم که این دستورها خیلی قابل اطمینان نیستند و ممکن است زمانشان دقیق نباشد و هی تغییر کند . میشه delay_us را با یک متغیر بکار برد ؟ مثلا عدد 956384 را در یک متغیر بریزیم و به دستور delay_us بگیم که به اندازه این متغیر صبر کن ؟ غیر از دستور delay و تایمر کسی راه دیگه ای میتونه به این حقیر ؟ :cry2: :cry2: :cry2:پیشنهاد کنه
    دلا خوبـــان دل خونيــــن پســـندند
    دلا خون شو که خوبان اين پسندند
    متاع کفر و دين بيآ‌مشتري نيست
    گروهــــي آن گروهي اين پســـندند

    #2
    پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

    یک کم بیشتر توضیح بدم :من در واقع میخوام یک تاخیر به اندازه 0 تا یک ثانیه داشته باشم ، به طوریکه این قدرت را داشته باشم که میکرو ثانیه میکرو ثانیه ، اون را کم و زیاد کنم ... اگر من تا تاخیر 65536 میکرو ثانیه هم میخواستم ، میتوانستم از تایمر ها استفاده کنم ... چون که رجیستر تایمر ها 16 بیت جا دارند ... اما تا یک میلیون میکرو ثانیه (یا همون یک ثانیه) نمیتونم تاخیر ایجاد کنم ... برای همین گیر کردم.
    هیچکس نیست لطف کنه کمکم کنه؟ :cry2:
    دلا خوبـــان دل خونيــــن پســـندند
    دلا خون شو که خوبان اين پسندند
    متاع کفر و دين بيآ‌مشتري نيست
    گروهــــي آن گروهي اين پســـندند

    دیدگاه


      #3
      پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

      می تونی دایی جان
      باید یک رجیستر دیگه تعریف کنی که بعنوان بایت سوم تایمر میشه. مثلا timerbyte3
      هر بار که تایمر 16 بیتی به 65535 رسید ( اول برنامه اینتراپت آورفلو تایمر رو فعال کن) می تونی داخل اینتراپت روتین مقدار timerbyte3 را یکی اضافه کنی.
      این جوری یه تایمر 24 بیتی داری
      با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

      دیدگاه


        #4
        پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

        میتونی از overflow تایمر استفاده کنی
        و مقدار تایمر تا بینهایت( بزرگترین متغییر از لحاظ بیتی)رو داشته باشی
        time=ovf_counter*65535+counter
        www.tehranelec.com

        دیدگاه


          #5
          پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

          اگر تاخیر دقیق میخاین:
          باید یه کریستال ساعت هم بگیری که فرکانسش 32768 هرتز هست . به پایه T1CKI و T1OSI وصلش کنی( در این مورد به دیتا شیت مراجعه کن)

          این کریستال به ازای هر 2 پانیه 1 بار تایمرو سر ریز میکنه که بای اینکه این موضوع برطرف بشه باید به اضای هر Oweflow مقدار 32768 رو روی رجیستر های تایمرت که همون TMR1H و TMR1L هستن بنویسی که اینطوری هر 1 ثانیه سرریزی رخ میده

          ولی توی پست دومی دیدم که دقتش هم برات مهمه !

          خوب این کارو سخت کرد! پس یه کار کن شما به یا اسیلاتور 1MHz احتیاج داری!

          با ای سی 555 یه اسیلاتور 1000000 هرتز دقیق بساز و بده به تایمر 0 اینطوری به اضای هر تانیه 3906 بار overflow داری
          عد از هر 3906 بار سر ریز شدن شما 3970 تا باید با تایمرت اضافه کنی چون باقیمونده زمان شما تا 1Mhz کسر نیاد و تایمرت دقیق کار کنه با یه محاصبه ساده میتونی با دقت میکرو ثانیه تاخیر ایجاد کنی...

          حالا برامون بگو این پروژه قراره چیکار کنه شاید راه انجامشو درست برات نگفته باشم و راه حل ساده تری هم بشه براش پیدا کرد دنیای میکرو دنیای کلک سروار کردنه :biggrin:



          دیدگاه


            #6
            پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

            با تشکر از کمکتون ... جناب آروین ... بنده همین سیگنال را میخواهم از میکرو بگیرم و کار دیگه ای نمیخوام بکنم . فکر کنم راه آقای احمد بهینه تر باشه . چونکه میکرو تعداد دفعات کمتری به روتین وقفه میره ... :read: .
            راستی یک مشکل اساسی . من دارم اطلاعات رو بایت بایت از یک دستگاه از طریق رابط یوزآرت به میکرو منتقل میکنم ... وقتی که اطلاعات رو هر 100 میلی ثانیه یک بار میفرستم ، بدون ایراد میگیره ... ولی اگر بایت ها رو تند تر ارسال کنم مثلا هر 5 میکرو ثانیه یکبار و کمتر از 5 میکرو ثانیه ، اون وقت میکرو قات میزنه و نمیتونه اطلاعاتو دریافت کنه . حالا این که چیزی نیست ... من چون سرعت برام خیلی مهمه میخوام از کریستال 25 مگا هرتز استفاده کنم ...اونطوری تعداد بیت هایی که احتیاج داره 25 برابر میشه ! :surprised: ولی خوب ... سعی میکنم یک کاریش بکنم ...
            توی همون ارسال 100 میکرو ثانیه یکبار ، اگر دکمه ریست رو بزنم و پایه ریست میکرو را فعال کنم ، مشکلی پیش نمیاد . اما اگه هی تند تند پشت سر هم میکرو را ریست کنم ، گاهی اوقات قات میزنه و نمیتونه اطلاعات رو که داره ارسال میشه درست دریافت کنه . یا مثلا اگه تغذیه را چند بار قطع کنم ، دوباره قات میزنه و تا ریستش نکنی درست نمیشه ... آخه من میخوام مدار را طوری طراحی کنم که با رفتن و آمدن برق و با خاموش روشن شدن ، قاطی نکنه ... بنظر شما ایراد کار از کجاست ؟ میخوام اگر از آسمون سنگ هم بباره مدار پایداری خودشو از دست نده .
            ممکنه مربوط به کیفیت کریستال ، یا مقدار اون دو تا خازن عدسی که از طریق کریستال به زمین وصل میکنیم باشه ؟ من مقدار مناسب اون خازن ها را از تو دیتاشیت خوندم ... برای هر کریستال یک بازه برای انتخاب مقدار خازن داده بود ... مثلا از 1 تا 33 نانو فاراد . ممکنه مقدار دقیقی برای این خازن ها باشه که اگه اون مقدار رو بگذاریم کارکرد میکرو در سرعت های بالا ، و یا هنگام قطع شدن تغذیه و ... پایدار تر بشه ؟
            دلا خوبـــان دل خونيــــن پســـندند
            دلا خون شو که خوبان اين پسندند
            متاع کفر و دين بيآ‌مشتري نيست
            گروهــــي آن گروهي اين پســـندند

            دیدگاه


              #7
              پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

              خوب من فکر کنم این یه ارتباط 1 طرفس آره؟

              با چنتا سیم داری کار میکنی؟

              کلاک داری؟

              دیدگاه


                #8
                پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                سلام
                من تا به حال با pic کار نکردم ولی اگر شما بتونید از تایمر وقفه overflow بگیرید انوقت میتونید تو روتین وقفه مقدار یه شمارنده رو زیاد کنید و مقدار اون شمارنده هر وقت به حد مورد نیاز رسید اونوقت یه کار خاص انجام بشه. به کد زیر دقت کنید:
                کد:
                interrupt routine every 250ms{
                counter++;
                if (counter==4){// 1s completed
                counter=0;
                /*
                your code here
                /*
                }
                }
                اگر کد رو متوجه نمیشید بگید تا بیشتر توضیح بدم.

                موفق باشید
                Work with what you have .Never limit yourself by things you could have had

                دیدگاه


                  #9
                  پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                  دایی جان
                  ارتباط سریال اصلا وقفه نمی خواد!!!
                  زیرا امکان نداره سرعت USART از سرعت میکرو بیشتر باشه.
                  مثلا اگه baud rate رو 115200 بیت بر ثانیه گذاشته باشی و بین دوبایت پشت سر هم یک استوپ بیت فاصله باشه، زمان 1/115200 ثانیه وقت محاسباتی داری. که برای میکرویی که با کلاک 20 مگ کار می کنه میشه 173 کلاک پالس. اگه هر دستورالعمل میکرو 2 کلاک پالس لازم داشته باشه باز هم می تونه 86 دستورالعمل در فاصله بین دوبایت اجرا کنه.
                  پس مشکل جای دیگست.
                  وقتی دستگاه A می خواد به دستگاه Bآ‌ دیتای بیشتر از یک بایت بفرسته باید یک پروتکل پیاده سازی بشه. وگرنه رشته ی کلام از دستشون در میره.
                  انواع پروتکل های استاندارد ایجاد شده تا ارتباط بین دستگاه های مختلف ساده بشه. مثلا همه فلش مموری ها باید با یه استاندارد داده بگیرن و بدن. یا بیشتر PLC ها از پروتکل Modbus استفاده می کنند.
                  تو هم می تونی از یکی از این پروتکل ها استفاده کنی یا اینکه خودت یه پروتکل بسازی.
                  ساده ترین پروتکلی که میشه ساخت از افزودن 2 بایت اضافی به بایت های دیتا بوجود میاد. ایندو بایت بترتیب استارت بایت و استوپ بایت نامیده میشن. اول استارت بایت فرستاده میشه و بعد بایت های دیتا و دست آخر هم بایت استوپ.
                  گیرنده این بایت ها باید ببینه تعداد بایت دریافت شده چندتاست و بایت اول و بایت اخر مطابق پروتکل هست یا نه. اگه بود بایت های میانی یعنی دیتا ها رو قبول می کنه و اگه نیاز به پاسخ باشه با همون پروتکل پاسخ میده.
                  ...
                  این بحث میتونه یه کتاب بشه. پس بهتره سرتونو درد نیارم
                  با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

                  دیدگاه


                    #10
                    پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                    نوشته اصلی توسط arvinfx
                    خوب من فکر کنم این یه ارتباط 1 طرفس آره؟

                    با چنتا سیم داری کار میکنی؟

                    کلاک داری؟
                    با دو تا سیم .....................TX+ و TX- ... چون ارتباطم از طریق RS485 هستش ... اونو میدم به یک max485 ... بعدش خروجی این آی سی رو میدم به RX میکروکنترلرم . اارتباطم بصورت آسنکرون هستش . ...اسیلاتور میکروکنترلرم ، کریستال 10 مگاهرتز خارجی هستش که دو طرفشو با دو تا خازن عدسی 22 نانو فاراد زمین کره ام
                    دلا خوبـــان دل خونيــــن پســـندند
                    دلا خون شو که خوبان اين پسندند
                    متاع کفر و دين بيآ‌مشتري نيست
                    گروهــــي آن گروهي اين پســـندند

                    دیدگاه


                      #11
                      پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                      وقتی به بردت برق وصل می کنی معلوم نیست دیتای سریالی که دریافت می کنه بایت اوله یا دوم یا سوم!!!
                      با یه روش ساده می تونی دو دستگاه رو سنکرون کنی.
                      باید دوتا کار بکنی.
                      اول اینکه اونی که داره دیتا می فرسته 3 بایت داده(یک پاکت) بفرسته و چند میلی ثانیه صبر کنه تا پاکت بعدی.
                      گیرنده هم باید ببینه اگه 3 بایت پشت سرهم دریافت کرد بعنوان داده بپذیره. اگه در یک مدت زمان معین داده نیومد بافر داده رو ریست کنه و منتظر بایت اول باشه.
                      به این روش میگن سنکرون کردن به وسیله timeout
                      تمامی ارتباطات سریالی که من استفاده می کنم timeout دارند و اگه زمان timeout بگذره و داده ای نیاد، شمارنده بافر صفر میشه تا اولین داده ای که میاد بعنوان بایت اول باشه.
                      اینجوری به هیچ وجه خطای دریافت نخواهی داشت...
                      با عرض پوزش خدمت دایی های عزیزم تا اطلاع ثانوی به اینترنت دسترسی ندارم.

                      دیدگاه


                        #12
                        پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                        تایمر های pic18f452 یا بصورت 8 بیتی کار میکنند یا 16 بیتی . ولی من میخواهم زمان صفر تا یک ثانیه را با دقت یک میکرو بسازم . یعنی اینکه بتوانم تاخیر تولید شده را با دقت یک میکرو ثانیه از صفر تا یک ثانیه بسازم . برای اینکار اگر بخواهم از تایمر استفاده کنم ، تایمر من باید 20 بیت داشته باشد . چون یک میلیون حالت میشود و یک میلیون در مبنای دو ، بیست بیت دارد . برای همین با یک تایمر 16 بیتی نمیتوانم کار کنم . به نظر شما استفاده از دستور delay_us معقول است ؟ چون شنیدم که این دستورها خیلی قابل اطمینان نیستند و ممکن است زمانشان دقیق نباشد و هی تغییر کند . میشه delay_us را با یک متغیر بکار برد ؟ مثلا عدد 956384 را در یک متغیر بریزیم و به دستور delay_us بگیم که به اندازه این متغیر صبر کن ؟ غیر از دستور delay و تایمر کسی راه دیگه ای میتونه به این حقیر ؟ :cry2: :cry2: :cry2:پیشنهاد کنه
                        سلام
                        تایمرهای PIC18F452 بعضیاشون فقط 8 بیتی و بعضیاشون هم 8 هم 16 بیتی کار میکنن
                        برای اینکه بتونی با دقت 1us یا حتی دقت بیشتر 1 ثانیه رو اندازه بگیری این کار روبکن
                        اولی برنامت اینارو بنویش:
                        T0CON=0x87
                        TMR0L=0x69
                        TMR0H=0x67
                        INTCON=0xA0

                        خط اول تایمر 0 رو init میکنه و اونو بصورت 16 بیتی با پیش تقسیم 1/256 راه می اندازه
                        خط دوم و سوم مقداری را در بایتهای بالا و پایین تایمر 0 می ریزه
                        خط سوم وقفه تایمر 0 رو فغال میکنه

                        بعد توی روتین وقفه اینو بنویس:
                        sub procedure interrupt
                        INTCON=$20
                        TMR0L=0x69
                        TMR0H=0x67

                        '''''your code'''''''

                        end sub
                        خط اول بیت وقفه رو پاک میکنه
                        خط دوم و سوم هم دوباره میاد بایتهای پایین و بالای تایمر0 رو مقدار دهی اولیه میکنه
                        این کد برای تاخیر یک ثانیه هست.(خیلی دقیق)
                        این کد برای کار با کلاک 40 هست (10 مگ کریستال با 4xpll)در صورت استفاده از کلاکهای دیگه هم باید مقدار اولیه تایمر صفر رو عوض کنی
                        نکته:شما با استفاده از پیش تقسیم تایمر میتونی کلاک اعمالی به تایمر رو از 1/1 تا 1/256 تغییر بدی
                        با استفاده از مقدار اولیه تایمر هم میتونی زمان وقوع وقفه رو کنترل کنی
                        برای اطلاعات دقیقتر T0CON رو در دیتاشیت ای سی قسمت تایمر 0 بخونید
                        با استفاده از این روش و با کلاک 40 حداکثر میتونی تا 2 یا 3 ثانیه رو اندازه بگیری و برای زمانهای بیشتر توی روتین وقفه یه کانتر بزار تا بتونی زمانهای بیشتر رو اندازه بگیری

                        برای خازنهای کریستال هم بهترین عدد 22pf هست
                        موفق باشی





                        [glow=black,2,300]بردی جالب با سیستم عاملی جالب !!![/glow]

                        دیدگاه


                          #13
                          پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                          نوشته اصلی توسط ahmadmn
                          وقتی به بردت برق وصل می کنی معلوم نیست دیتای سریالی که دریافت می کنه بایت اوله یا دوم یا سوم!!!
                          با یه روش ساده می تونی دو دستگاه رو سنکرون کنی.
                          باید دوتا کار بکنی.
                          اول اینکه اونی که داره دیتا می فرسته 3 بایت داده(یک پاکت) بفرسته و چند میلی ثانیه صبر کنه تا پاکت بعدی.
                          گیرنده هم باید ببینه اگه 3 بایت پشت سرهم دریافت کرد بعنوان داده بپذیره. اگه در یک مدت زمان معین داده نیومد بافر داده رو ریست کنه و منتظر بایت اول باشه.
                          به این روش میگن سنکرون کردن به وسیله timeout
                          تمامی ارتباطات سریالی که من استفاده می کنم timeout دارند و اگه زمان timeout بگذره و داده ای نیاد، شمارنده بافر صفر میشه تا اولین داده ای که میاد بعنوان بایت اول باشه.
                          اینجوری به هیچ وجه خطای دریافت نخواهی داشت...
                          سلام عمو جان ............................ببین ... من هم یک جورایی این دو تا رو با هم سنکرون میکنم . به این صورت که 4 بایت میفرستم . اویش عدد 5 هست . میکروی من هر وقت عدد 5 را ببیند میفهمد که بایت بعدی که میرسد ، اولین بایت اطلاعات است ... اینطوری هیچ وقت قاطی نمیشود . هر وقت هم که ریست میکنیم ، دوباره بایت اول را درست تشخیص میدهد . ولی اگه تند تند ریست کنیم یا تند تند تغذیه را قطع و وص کنیم ، از هر5-6 دفعه یک دفعه اش قاطی میکند و اصلا درست کارنمیکند . همچنین اگه فاصله بین پاکت های اطلاعات رو از حدود 20-30 میلی ثانیه کمتر کنیم ، باز هم گیر میکند . علتش را نمیدانید چیست ؟
                          برای من درست کار کردن مدار درشرایط گوناگون خیلی مهم است . وگرنه اینقدر هی تغذیه را قطع و وصل نمیکردم
                          دلا خوبـــان دل خونيــــن پســـندند
                          دلا خون شو که خوبان اين پسندند
                          متاع کفر و دين بيآ‌مشتري نيست
                          گروهــــي آن گروهي اين پســـندند

                          دیدگاه


                            #14
                            پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                            نوشته اصلی توسط jh_topgraph
                            سلام
                            من تا به حال با pic کار نکردم ولی اگر شما بتونید از تایمر وقفه overflow بگیرید انوقت میتونید تو روتین وقفه مقدار یه شمارنده رو زیاد کنید و مقدار اون شمارنده هر وقت به حد مورد نیاز رسید اونوقت یه کار خاص انجام بشه. به کد زیر دقت کنید:
                            کد:
                            interrupt routine every 250ms{
                            counter++;
                            if (counter==4){// 1s completed
                            counter=0;
                            /*
                            your code here
                            /*
                            }
                            }
                            اگر کد رو متوجه نمیشید بگید تا بیشتر توضیح بدم.

                            موفق باشید
                            سلام میشه یک کمبیشتر توضیح بدید ؟
                            دلا خوبـــان دل خونيــــن پســـندند
                            دلا خون شو که خوبان اين پسندند
                            متاع کفر و دين بيآ‌مشتري نيست
                            گروهــــي آن گروهي اين پســـندند

                            دیدگاه


                              #15
                              پاسخ : اگر تعداد بیت های رجیستر تایمر برای ما کم بود چکار کنیم؟

                              سلام
                              جوابی که من دادم مربوط به اولین سوالتون بود که گفته بودید میخواهید زمان بیشتری از تایمر بگیرید.
                              نوشته اصلی توسط sinavahdat
                              تایمر های pic18f452 یا بصورت 8 بیتی کار میکنند یا 16 بیتی . ولی من میخواهم زمان صفر تا یک ثانیه را با دقت یک میکرو بسازم . یعنی اینکه بتوانم تاخیر تولید شده را با دقت یک میکرو ثانیه از صفر تا یک ثانیه بسازم . برای اینکار اگر بخواهم از تایمر استفاده کنم ، تایمر من باید 20 بیت داشته باشد . چون یک میلیون حالت میشود و یک میلیون در مبنای دو ، بیست بیت دارد . برای همین با یک تایمر 16 بیتی نمیتوانم کار کنم . به نظر شما استفاده از دستور delay_us معقول است ؟ چون شنیدم که این دستورها خیلی قابل اطمینان نیستند و ممکن است زمانشان دقیق نباشد و هی تغییر کند . میشه delay_us را با یک متغیر بکار برد ؟ مثلا عدد 956384 را در یک متغیر بریزیم و به دستور delay_us بگیم که به اندازه این متغیر صبر کن ؟ غیر از دستور delay و تایمر کسی راه دیگه ای میتونه به این حقیر ؟ :cry2: :cry2: :cry2:پیشنهاد کنه
                              فرض کنید شما هر پالس تایمرتون ۱ میلی ثانیه طول میکشه. برای بدست آوردن زمان ۲۵۰ میلی ثانیه شما به ۲۵۰ شمارش نیاز دارید.
                              کاری که ما میکنیم اینه که تایمر را در مودی (mode) میزاریم که هر وقت به 250 شمارش رسید تایمر صفر شود و یک وقفه هم تولید شود (مثلا در avr تایمر را در مود ctc قرار میدیم و وقفه مقایسه رو هم فعال میکنیم)

                              حالا در روتین وقفه هم بصورت برنامه نویسی یک شمارنده (counter) قرار میدیم که هر وقت برنامه به روتین وقفه رفت یک واحد به اون اضافه کنه. counter++
                              حالا اگر مقدار counter عدد ۴ شد یعنی ۱ ثانیه سپری شده. و باید مقدار counter دوباره صفر شه.
                              کد:
                              if(counter==4){
                              counter=0;
                              your code
                              }
                              شما میتونید توی روتین این وقفه هر زمانی رو که مضربی صحیح از زمان وقفه هست ایجاد کنید.
                              مثلا من متغییر counter2 رو هر وقت به 40 رسید صفر میکنم تا بتونم زمان ۱۰ ثانیه رو هم بسازم.

                              البته کد بهینه تر اینه که مقدار counter2 در بدنه شرط 1 ثانیه یکی اضافه بشه و زمانی که مقدار counter2 به ۱۰ رسید ۱ ثانیه سپری شده.
                              Work with what you have .Never limit yourself by things you could have had

                              دیدگاه

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