Gallery

ტაიმერი მიკროკონტროლერში

მიკროკოტროლერი. დღე 6.  

ტაიმერი მიკროკონტროლერში.

წინა პუბლიკაციაში გახილული იყო წყვეტის გამოყენება ერთი ღილაკის დაჭერის აღმოსაჩენად. ღილაკზე დაჭერისას პროგრამა წყვეტს დაყოვნების ქვეპროგრამის შესრულებას და გადადის ღილაკის მომსახურების პროგრამის შესრულებაზე. თითქოს ყველაფერი კარგად არის, მაგრამ თუ ღილაკების რაოდენობა ორზე მეტია, მაშინ მათს დაჭერაზე შენელებული რეაქციის პრობლემა ისევ იჩენს თავს, რადგან Atmega8 მიკროკონტროლერს გარე წყვეტებისათვის სულ ორი INT0, INT1  გამომყვანი გააჩნია.
იგივე პრობლემას წავაწყდებით იმ შემთხვევაშიც, თუ მიკროკონტროლერს, შუქდიოდების ციმციმის გარდა, კიდევ სხვა ამოცანების შესრულებას დავავალებთ.იმის გამო, რომ ციმციმის ამოცანის შესრულება დაყოვნების ქვეპროგრამასთან არის დაკავშირებული, მიკროკონტროლერი ძირითად დროს  ამ ამოცანის შესრულებას უთმობს და სხვა დავალებების შესრულებას მხოლოდ დაყოვნების ქვეპროგრამის შესრულებებს შორის დროის ინტერვალებში განახორციელებს. გამოსავალი მდგომარეობს იმაში, რომ მიკროკონტროლერის  მიკროპროცესორი გამოვათავისუფლოდ დაყოვნების ქვეპროგრამის შესრულებისაგან. ანუ, დაყოვნება უნდა განვახორციელოდ არა პროგრამული გზით, არამედ რაიმე სხვა ხერხით. ამ ამოცანის შესრულებისათვის მიკროკონტროლერში გათვალისწინებულია სპეციალური მოწყობილობა, რომელსაც ტაიმერი ეწოდება. Atmega8 მიკროკონტროლერში ასეთი მოწყობილობა სამია – Timer0 ,Timer1 და Timer2.
 ნახატზე წითლად მონიშნულია ალგორითმის ის ნაწილები, რომლებიც დაკავშირებულია შუქდიოდების ციმციმის ამოცანის შესრულებასთან. წაშალეთ ეს ნაწილები.
დააყენეთ კურსორი ელემენტზე Ext Int (გააწითლეთ)  და მენიუში აირჩიეთ “Elements”, “Setter”, “Timer/Counter 1”.


 ფანჯარაში დააჭირეთ  “Stopped”.

ახალ ფანჯარაში აირჩიეთ “CK / 64”.
და დახურეთ ფანჯარა “OK”.
ალგორითმის ძირითადი შტო მიიღებს სახეს:

განვმარტოთ ჩვენს მიერ ჩატარებული ოპერაციების არსი. ჩვენ ალგორითმში ჩავამატეთ ტაიმერი Timer1. ეს ტაიმერი შეიცავს ორ ცალ A და B  ორ ბაიტიან (16 ორობით თანრიგიან)  მრიცხველს . თვითოეულ მათგანს შეუძლია იმპულსების დათვლა 0 -დან  65535 – მდე. (2 ხარისხად 16 – უდრის 65536). იმპულსების წყაროს წარმოადგენს შიდა სატაქტო გენერატორი (შესაძლოა გარე გენერატორიც იყოს იმპულსების წყარო) , რომლის სიხშირე, ჩვენს შემთხვევაში შეადგენს 1 მეგაჰერცს, ანუ 1 000 000 ჰერცს (ასე გვაქვს თავიდან მითითებული პროექტში – “Options”, “Project Options”). ანუ, წყაროს იმპულსები შეადგენს 1/1000000 წმ = 1 მიკროწამი = 1000 ნანოწამი (1000ns).  მაგრამ მრიცხველები არ ითვლიან იმპულებს უშუალოდ წყაროდან. წყაროსა და მრიცხველებს შორის ჩართულია იმპულსების სიხშირის გამყოფი, რომლის გაყოფის კოეფიციენტი შესაძლებელია ამორჩეულ იქნას კონფიგურირების პროცესში. სურათზე წითლად მონიშნული სტრიქონი “CK / 64” მიუთითებს, რომ სიხშირის გაყოფის კოეფიციენტია 64. ამ შემთხვევაში  მრიცხველებისათვის მიწოდებული იმპუსების პერიოდი იქნება 64 -ჯერ მეტი – 64 000 ns. ეს გარემოება მითითებულია წითლად მონიშნულ სტრიქონში: “The period is: 64 000 ns;”. ამავე სტრიქონში მითითებულია აგრეთვე, რომ მრიცხველების გადავსების დრო შეადგენს 4 194 304 მიკროწამს. სწორედ ამ დროს მოანდომებენ მრიცხველები 65536 იმპულსის დაფიქსირებას (64 000 X 65 536 = 4 194 304 000). ანუ მრიცხველები გადაივსებიან დაახლოებით 4 წამში და თავიდან დაიწყებენ დათვლას.
ყოველი გადავსების დადგომისას, ტაიმერი გამოიმუშავებს წყვეტის სიგნალს, რომელიც შეიძლება გამოვიყენოთ შუქდიოდების ციმციმის სამართავად.
მაგრამ 4 წამი მეტისმეტად დიდი დროა ციმციმისათვის. შევეცადოთ ციმციმის პერიოდი 1 წამამდე  შევამციროთ. ორჯერ დავაჭიროთ ელემენტზე “Timer 1” და შევცვალოთ „Mode: Normal”.

ფაჯარაში ავირჩიოთ “CTC”, რაც ტაიმერს მიუთითებს, რომ მრიცხველებმა უნდა დაითვალონ იმპულსები არა 65535 -დე, არამედ იმ რიცხვამდე, რომელიც ჩაწერილი იქნება OCR1 რეგისტრში.  Timer1 -ს   გააჩნია ორი OCR1 რეგისტრი – OCR1A, OCR1B რეგისტრები  A და B მრიცხველებისთვის.


ახლა დავაკონფიგურიროთ ტაიმერების წყვეტის პარამეტრები. ავირჩიოთ “Elements”, “Setter” და შემდეგ ისე, როგორც ნახაზზეა.

ახალ ფანჯარაში მოვნიშნოთ “Output compare A match”, რაც მიუთითებს იმაზე, რომ წყვეტის სიგნალი უნადა გამომუშავდეს A მრიცხველის შიგთავსის OCR1A რეგისტრის შიგთავსთან შედარების საფუძველზე.

დავხუროთ ფანჯარა – “OK”  და ალგორითმში ჩავამატოთ OCR1A -ის მნიშვნელობა.  16384->OCR1A (თუ 65536 მნიშვნელობა 4 წამს გვაძლევდა, მაშინ 4-ჯერ ნაკლები მნიშვნელობა 16384 მოგვცემს 1 წამს).

16384->OCR1A გამუქებულია (R2 – კლავიშზე დაჭერით), იმის აღსანიშნავად, რომ საქმე გვაქვს ორ ბაიტიან ოპერაციასთან. ტაიმერის წყვეტებს შორის დროის ინტერვალების უფრო ზუსტი გამოთვლისათვის შევადგინოთ განტოლება n / 65536 = t / Toverflow  სადაც n – OCR1 რეგისტრში ჩასაწერი რიცხვია, t  – დროის ინტერვალი, რომელიც გვინდა რომ მივიღოთ,  Toverflow – მრიცხველის გადავსების დრო.
წითლად გამოყოფილი NOP , რა თქმა უნდა საჭირო სულაც არ არის. ის ჩავამატე იმის აღსანიშნავად, რომ მის ადგილზე შეიძლება ჩამატებულ იქნას ნაბისმიერი სხვა კოდი (სხვა დავალებებისთვის), რომელიც მიკროკონტროლერმა უნდა შეასრულოს.
ახლა საჭიროა შევადგინოთ იმ ქვეპროგრამის ალგორითმი, რომელიც უნდა შეასრულოს მიკროკონტროლერმა ტაიმერის მიერ წყვეტის სიგნალის გამომუშავებისას.
დააჭირეთ ერთდროულად კალვიშებს “Alt”, “Ctrl”, “Shift” , მიიყვანეთ კუსორი სამუშაო ფურცლის თავისუფალ ადგილზე და დააჭირეთ მაუსის მარცხენა ღილაკს. ფურცელზე გაჩნდება ახალი ვეტრექსი. მენიუში აირჩიეთ „Elements”, “Interrupts”, “Timer_1_Compare_Math_A”. დავამატოთ ალგორითმში შუქდიოდების მართვის ბრძანებები. PORTB->R16  – წავიკითხოთ, რა გვაქვს პორტში (თავიდან გვქონდა $AA) ; შევამოწმოთ, ხომ არ უდრის ის $AA-ს; თუ არ უდრის, მაშინ  ჩავწეროთ პორტში $AA:   $AA->R16, R16->PORTB. თუ შემოწმებისას აღმოჩნდა, რომ პორტში არის $AA, მაშინ ჩავწეროთ პორტში $55:  $55->R16, R16->PORTB. წყვეტის ქვეპროგრამის ორივე შტო სრულდება ბრძანებით  RETI.

საბოლოო ალგორითმს აქვს სახე:
მოახდინეთ საბოლოო ალგორითმის კომპილაცია “Program”, “Compile”. გახსენით Proteus -ში ადრე შენახული პროექტი. გაუშვით სიმულაცია და დარწმუნდით, ალგორითმის მუშაობის სისწორეში. სცადეთ OCR1A რეგისტრში ორჯერ მეტი და ორჯერ ნაკლები რიცხვების ჩაწერა. შუქდიოდების ციმციმის სიხშირე შესაბამისად ორჯერ შემცირდება და ორჯერ გაიზრდება.
ამით ტაიმერის შეძლებლობები არ ამოიწურება. მას გაცილებით მეტი ფუნქციების შესრულება შეუძლია. ერთ-ერთ მნიშვნელოვან ფუნქციას წარმოადგენს PWM (Pulse Width Modulation)- ფუნქცია, რომელიც მდგომარეობს პროგრამულად ცვლადი სიგანის იმპულსების ფორმირებაში, რაც მუდმივი დენის ელექტროძრავების სიმძლავრის მართვის საშუალებას იძლება. ამ ფუქციის რეალიზების მეთოდები განხილული იქნება მომდევნო პუბლიკაციებში.
Timer0 და Timer2 ტაიმერები Timer1-გან იმით განსხვავდებიან, რომ მათი მრიცხველები ერთ ბაიტიანია (8 ორობითი თანრიგი), ამიტომ მათი საშუალებით დროის დიდი ინტერვალების მიღება შეუძლებელია.

2 responses to “ტაიმერი მიკროკონტროლერში

  1. ყველა დღე წავიკითხე მარა R რეგისტრის დანიშნულებას ვერ მივხვდი რა ნიშნავს რა ფუნქიას ასრულბს? ან რატო R16 R17 R18 რას ნიშნავს ეს მიკროკონტროლერისთვის?

დატოვეთ კომენტარი

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / შეცვლა )

Twitter picture

You are commenting using your Twitter account. Log Out / შეცვლა )

Facebook photo

You are commenting using your Facebook account. Log Out / შეცვლა )

Google+ photo

You are commenting using your Google+ account. Log Out / შეცვლა )

Connecting to %s