ტაქტის ღილაკი avr მიკროკონტროლერზე. ღილაკის დაკავშირება - პროგრამირება CV AVR-ში? აპარატურული კონტაქტის გაუქმება


წინა გაკვეთილებზე მე გითხარით, თუ როგორ უნდა აჩვენოთ ინფორმაცია MK-დან: და . და ამ გაკვეთილზე ჩვენ შევიყვანთ ინფორმაციას ღილაკების გამოყენებით. არსებობს რამდენიმე სახის ღილაკი: ჩამკეტი და ტაქტი.ღილაკის სახელწოდებიდან ირკვევა მისი მოქმედების პრინციპი: ტაქტი - დაჭერილია, კონტაქტები დახურულია, შეუფერხებელი - ღია; ფიქსატორები იწერენ თავის მდგომარეობას: დაჭერილი - კონტაქტები დაიხურა, ისევ დაჭერით - კონტაქტები გაიხსნა.

სტანდარტული ღილაკების კავშირის დიაგრამა ძალიან მარტივია, ასე გამოიყურება


მუშაობის იდეა ასეთია: 5 ვოლტის ძაბვა მიეწოდება ფეხს 10k რეზისტორის საშუალებით, ლოგიკური ერთეული გამოიყენება ფეხზე. მაგრამ როცა ღილაკს ვაჭერთ, ფეხს ვამოკლეთ მიწასთან და რეზისტორში გაივლის მცირე დენი და ის ვერ იტევს 5 ვოლტს და ფეხზე ძაბვა დაეცემა 0 ვოლტამდე და ეს ლოგიკურია 0. ამ მომენტებს დავიჭერთ პროგრამაში. მოდით დავწეროთ პროგრამა, რომელიც ღილაკის დაჭერისას ჩართავს LED-ს და დაჭერისას გამორთავს.

#შეიცავს #შეიცავს void main(void) ( // პორტის ინიციალიზაცია D PORTD=0b00000000; DDRD=0b10000000; ხოლო (1) (თუ (PIND & 0b00000100) /*შეამოწმეთ რა ლოგიკური დონე გვაქვს პინზე & - ნიშნავს ბიტალურად „AND“ მაგალითად. PIND-ში გვაქვს 0b00000100, შემდეგ 0b00000100 & 0b00000100 = 0b00000100, ეს მართალია და თუ PIND-ში გვაქვს 0b00000000, მაშინ 0b000000000, მაშინ 0b000000000, მაშინ 0b000000000, მაშინ 0b000000000, მაშინ 0b000000000 და 0b000000000 და 000000000B D=0 b00000000; // ჩაწერეთ ნული მეშვიდე ბიტზე D პორტის სხვა PORTD=0b10000000; // ჩაწერეთ ერთი D პორტის მეშვიდე ბიტზე); delay_ms(100); // დაამატეთ 100 მილიწამის დაყოვნება კონტაქტის გადახრისგან დასაცავად)

თანამედროვე მიკროკონტროლერების უმეტესობას აქვს ჩაშენებული ასაწევი რეზისტორი R1, ასე რომ თქვენ არ გჭირდებათ გარე დაყენება.
შიდა ასაწევი რეზისტორის ჩასართავად, პორტის ინიციალიზაციისას PORTD რეესტრში დააყენეთ შესაბამისი ბიტი, რომელზეც ღილაკი კიდია ერთზე: PORTD=0b00000100;
რა მოხდება, თუ პინი კონფიგურირებულია როგორც გამომავალი:

  • თუ გამომავალი ლოგიკური ნულია, ცუდი არაფერი მოხდება
  • თუ გამომავალზე მოულოდნელად გამოჩნდება ლოგიკური ერთეული, მაშინ როდესაც ღილაკზე დავაჭერთ, ჩვენ უბრალოდ მოკლედ შევაერთებთ გამომავალს მიწასთან და მასში შემოვა დენი, რომელსაც ფეხი ვერ გაუძლებს (ფეხის დენი არ უნდა აღემატებოდეს 40 მილიამპერს. ), და დიდი ალბათობით დაიწვება
ამიტომ, დაცვის მიზნით, მიზანშეწონილია მოათავსოთ 300 ომიანი რეზისტორი მიკროკონტროლერის პინსა და ღილაკს შორის.
ღილაკების მიკროკონტროლერთან დაკავშირების კიდევ მრავალი გზა არსებობს, მაგალითად, დიოდების გამოყენებით ან ADC-ის გამოყენებით, მაგრამ მათ არ აღვწერ, რადგან კურსი განკუთვნილია დამწყებთათვის. თუ დაგჭირდა, შენ თვითონ იპოვი.

აქ მოცემულია სხვადასხვა C პროგრამების მაგალითები Atmel AVR მიკროკონტროლერებისთვის. ყველა მაგალითი დაწერილია ATmega16 მიკროკონტროლერისთვის, ამიტომ ეს გასათვალისწინებელია AVR ოჯახის სხვა MK-ებზე გადაცემისას. მიკროკონტროლერის საათის სიხშირე ყველა მაგალითში არის 8 MHz (გამოიყენება შიდა ოსცილატორიდან დაკვრა). მაგალითის კოდი დაყოფილია ბლოკებად და მოცემულია კომენტარებით. პროექტები იწერება Eclipse() გარემოში და მათი ადვილად იმპორტირება შესაძლებელია Eclipse-ში. თქვენ ასევე შეგიძლიათ გამოიყენოთ ეს პროექტები AVR სტუდიის გარემოში (მხოლოდ პროექტის ფაილების სტრუქტურა შეიცვლება). თუ რაიმე შეცდომებს აღმოაჩენთ, გთხოვთ შეგვატყობინოთ ელექტრონული ფოსტით.

- უმარტივესი მაგალითი. C პორტთან დაკავშირებულია 8 LED. LED-ები განათებულია ლოგიკური ერთით პორტის ხაზზე. პორტის LED-ები ჩართულია და გამორთულია ციკლის დროს. Hello World-ის ერთგვარი ანალოგი ჩაშენებული სისტემების სამყაროში. ჩამოტვირთეთ მაგალითი

IO პორტები - ეს მაგალითი განიხილავს I/O პორტებთან მუშაობას. არის 8 LED-ები, რომლებიც დაკავშირებულია C პორტთან (ხაზები 0-7). ღილაკი დაკავშირებულია D პორტის მე-2 ხაზთან, აწევით მიწაზე. დაჭერისას ღილაკი გამოსცემს ლოგიკურ ერთ დონეს C პორტის 0 ხაზთან. პროგრამის ციკლი ორგანიზებულია შემდეგნაირად: გაშვებისას ირთვება შუქი, ჯერ ანათებს C პორტის 0 ხაზის LED, შემდეგ 1 ხაზზე და ა.შ. მე-7 ხაზამდე მიღწევისთანავე იცვლება გაშვებული ცეცხლის მიმართულება (7-დან 0-მდე). ღილაკზე დაჭერისას ცეცხლი ჩერდება და ყველა LED ნათურა ერთდროულად ანათებს. ღილაკზე ხელახლა დაჭერის შემდეგ, გაშვებული ცეცხლი აგრძელებს მოძრაობას იქიდან, სადაც გაჩერდა.

ჩამოტვირთეთ მაგალითი

დინამიური ჩვენება - ეს მაგალითი განიხილავს 7 სეგმენტიან ინდიკატორთან მუშაობას. ჩემს შემთხვევაში, მას აქვს 4 ციფრი (ციფრი). ვინაიდან დაფაზე მაქვს დაყენებული ტრანზისტორი ბიტების გასაკონტროლებლად, კონტროლი ხორციელდება როგორც ბიტებზე, ასევე სეგმენტებზე ლოგიკური ერთეულის გამოტანით. კავშირის დიაგრამა ასეთია: ინდიკატორის სეგმენტები დაკავშირებულია C პორტის 0-7 ხაზებთან, ხოლო ინდიკატორის ციფრები დაკავშირებულია B პორტის 0-3 ხაზებთან. დაწყებისას ინდიკატორი აჩვენებს ციფრებს 1 2 3 4.

ჩამოტვირთეთ მაგალითი

UART - ეს მაგალითი განიხილავს UART (უნივერსალური ასინქრონული მიმღები) პერიფერიულ მოდულს. UART მოდულის კონფიგურაცია შესაძლებელია იმუშაოს როგორც შეფერხებით, ასევე შეფერხებების გარეშე (ხელით, დროშებთან მუშაობის გზით). მაგალითი მუშაობს შემდეგნაირად: ბაიტის მიღებისას MK მიდის შეფერხების დამმუშავებელთან (გამოიყენება მხოლოდ მონაცემთა მიღების შეწყვეტა) და ანაწილებს ბაიტის რიცხვით მნიშვნელობას (0-255) რიცხვებად, რომლებიც ნაჩვენებია 7-ზე. სეგმენტის მაჩვენებელი. კავშირის დიაგრამა წინა მაგალითის მსგავსია. გადაცემა ხორციელდება ორი UART ხაზით (პორტი D ხაზი 0-1), რომელზედაც თქვენ უნდა დააკავშიროთ USB-UART კონვერტორის RX და TX ხაზები. შეფერხების გარეშე კონფიგურაციისთვის, თქვენ უნდა გაასუფთაოთ RXCIE ბიტი UCSRB რეესტრში და ხელით გამოკითხოთ ინტერფეისი პროგრამის მთავარ ციკლში.

ჩამოტვირთეთ მაგალითი

საათი - ეს მაგალითი განიხილავს მარტივი საათის განხორციელებას 7 სეგმენტიანი ინდიკატორით და წყვილი ღილაკებით. მხოლოდ აქ 6 ციფრია უკვე საჭირო, თუმცა წამების გამოტოვება შეიძლება. ღილაკები მიწაზე აწევით. დაჭერისას ღილაკი ხაზს უსვამს მაღალ ლოგიკურ დონეს. ინდიკატორი დაკავშირებულია როგორც წინა მაგალითებში (სეგმენტები C პორტში, ციფრები პორტში B) და ღილაკები D პორტის 2-3 ხაზებთან. ღილაკს იყენებს PD2 წუთების დასაყენებლად, ხოლო PD3 საათების დასაყენებლად. თითოეული ღილაკის დაჭერით, შესაბამისი ციფრის (წუთები ან საათები) მნიშვნელობა იზრდება.

ჩამოტვირთეთ მაგალითი

DS18B20 - ეს მაგალითი განიხილავს DS18B20 ციფრული ტემპერატურის სენსორთან მუშაობას. ტემპერატურის მაჩვენებლები ნაჩვენებია 7 სეგმენტიან ინდიკატორზე. სენსორის DQ პინი დაკავშირებულია PD5 ფეხთან (პინი). ხაზი უნდა იყოს მიერთებული ელექტრომომარაგების პოზიტიურთან 4,7-10 kOhm რეზისტორით (დოკუმენტაციის მიხედვით). სენსორის გამოკითხვა ხდება ყოველ 5 წამში. ტემპერატურა ნაჩვენებია 4-ციფრიან ინდიკატორზე: ნიშანი, ორი ციფრი მთელი რიცხვისთვის და ერთი რეალური ნაწილისთვის. დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

DHT11 - ეს მაგალითი განიხილავს DHT11 ტემპერატურისა და ტენიანობის სენსორთან მუშაობას. ტემპერატურის მაჩვენებლები ნაჩვენებია 7 სეგმენტიან ინდიკატორზე. სენსორის DATA პინი (ასევე SDA) დაკავშირებულია PD5 ფეხთან (პინი). ხაზი უნდა იყოს მიერთებული ელექტრომომარაგების პოზიტიურთან 4,7-10 kOhm რეზისტორით (დოკუმენტაციის მიხედვით). სენსორის გამოკითხვა ხდება ყოველ 5 წამში. ტემპერატურა და ტენიანობა იზომება, მაგრამ ნაჩვენებია მხოლოდ ტენიანობა (ორნიშნა მთელი რიცხვი). დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

DHT22 - ეს მაგალითი განიხილავს DHT22 ტემპერატურისა და ტენიანობის სენსორთან მუშაობას. DHT11-თან შედარებით, ამ სენსორს აქვს უფრო დიდი სიზუსტე და უფრო ფართო გაზომვის დიაპაზონი. ტემპერატურის მაჩვენებლები ნაჩვენებია 7 სეგმენტიან ინდიკატორზე. სენსორის DATA პინი (ასევე SDA) დაკავშირებულია PD5 ფეხთან (პინი). ხაზი უნდა გაიყვანოს ელექტრომომარაგებამდე პოზიტიური 4.7-10 kOhm რეზისტორით (თუმცა დოკუმენტაციის მიხედვით ეს არ არის საჭირო). სენსორის გამოკითხვა ხდება ყოველ 5 წამში. ტემპერატურა და ტენიანობა იზომება, მაგრამ ნაჩვენებია მხოლოდ ტენიანობა (ორნიშნა რეალური რიცხვი ერთი ათობითი ადგილით). დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

BMP180 - ეს მაგალითი განიხილავს მუშაობას BMP180 ციფრული ტემპერატურისა და ატმოსფერული წნევის სენსორთან. ატმოსფერული წნევის მაჩვენებლები ნაჩვენებია 7 სეგმენტიან ინდიკატორზე. სენსორი დაკავშირებულია I2C ინტერფეისით. SDA და SCL ხაზები უნდა იყოს დაკავშირებული ელექტრომომარაგების პოზიტიურთან 4.7-10 kOhm რეზისტორებით. სენსორის გამოკითხვა ხდება ყოველ 10 წამში. ტემპერატურა და წნევა იზომება, მაგრამ ნაჩვენებია მხოლოდ ატმოსფერული წნევა მმ-ში. ვერცხლისწყლის სვეტი (მთლიანი). დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

BH1750 - ეს მაგალითი განიხილავს მუშაობას BH1750 ციფრული სინათლის სენსორთან. სინათლის მაჩვენებლები ნაჩვენებია 7 სეგმენტიან ინდიკატორზე. სენსორი დაკავშირებულია I2C ინტერფეისით. SDA და SCL ხაზები უნდა იყოს დაკავშირებული ელექტრომომარაგების პოზიტიურთან 4.7-10 kOhm რეზისტორებით. სენსორის გამოკითხვა ხდება ყოველ 5 წამში. დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

ADC ჩვენება - ეს მაგალითი მსგავსია UART-ის მაგალითის. განსხვავება ისაა, რომ ბაიტი აღებულია A პორტის 0 ხაზიდან (ADC-ის 0 ხაზი, ADC0). მიკროკონტროლერი იყენებს ტაიმერს, რათა განახორციელოს ძაბვის ანალოგური ციფრული კონვერტაცია A პორტის 0 ხაზზე (ქვედა 2 ბიტი უგულვებელყოფილია როგორც ხმაური). გაზომვისას გამოიყენება შიდა 5 ვ მითითება. D პორტის PD2 ხაზთან დაკავშირებულია ღილაკი, რომელიც განსაზღვრავს წაკითხვის გამომავალი რეჟიმს. ღილაკზე დაჭერისას გაზომვის შედეგი გამოჩნდება რიცხვის სახით 0-დან 255-მდე. თუ ღილაკზე არ არის დაჭერილი, გაზომვის შედეგი გარდაიქმნება ვოლტად და ნაჩვენებია ინდიკატორზე (ზუსტი მეათედამდე).

ჩამოტვირთეთ მაგალითი

სწრაფი PWM - ეს მაგალითი გვიჩვენებს, თუ როგორ უნდა დააკონფიგურიროთ აპარატურა PWM (პულსის სიგანის მოდულაცია, ინგლისური PWM). LED-ები დაკავშირებულია D პორტის 4 და 5 ხაზებთან, ხოლო A და B არხების ღილაკები დაკავშირებულია D პორტის 2-3 და 6-7 ხაზებთან, შესაბამისად. ღილაკები მიწაზე აწევით (დაჭერისას ღილაკზე გამოდის ლოგიკური ერთი დონე პორტის ხაზთან) ღილაკები 2 და 3 ხაზებზე შესაბამისად ზრდის და ამცირებს A არხის PWM სამუშაო ციკლს (ცვლის LED-ის სიკაშკაშეს). ღილაკები მე-6 და მე-7 ხაზებზე შესაბამისად გაზრდის და ამცირებს სამუშაო ციკლის PWM არხს B. შედარების რიცხვი თითოეული არხისთვის მერყეობს 0-დან 255-მდე დიაპაზონში. A არხისთვის ცვლილების საფეხური არის 10, B არხისთვის ნაბიჯი არის 5.

ჩამოტვირთეთ მაგალითი

HCSR04 - ეს მაგალითი განიხილავს მუშაობას ულტრაბგერითი მანძილის სენსორთან HCSR04. სენსორის ტრიგერის პინი დაკავშირებულია PD3 ხაზთან, ხოლო Echo პინი დაკავშირებულია PD2 ხაზთან. 7-სეგმენტიანი ინდიკატორის კავშირი წინა მაგალითების მსგავსია. MK პერიოდულად ატარებს სენსორს და ადგენს მანძილს დაბრკოლებამდე სანტიმეტრებში. ამის შემდეგ, ნომერი იყოფა ციფრებად და ნაჩვენებია ეკრანზე. დოკუმენტაცია სენსორისთვის.

ჩამოტვირთეთ მაგალითი

მატრიცული კლავიატურა - ეს მაგალითი გვიჩვენებს, თუ როგორ გამოიყენოთ მატრიცული კლავიატურა. მიკროკონტროლერი დინამიურად გამოკითხავს კლავიატურას და შემდეგ განსაზღვრავს დაჭერილი კლავიატურის რაოდენობას. ველის ზომა არის 3 3-ზე - ვიღებთ 9 ღილაკს. პირველი 8-ის დაჭერით ანათებს LED A პორტის შესაბამის ხაზზე, მე-9 ღილაკზე დაჭერით ანათებს A პორტის ყველა LED-ს. მატრიცული კლავიატურა დაკავშირებულია C პორტის 0-5 ხაზებთან (სამი სვეტი და სამი მწკრივი). არქივი შეიცავს მატრიცული კლავიატურის დიაგრამას და დაბეჭდილ მიკროსქემას (Diptrace).

ჩამოტვირთეთ მაგალითი

Shift Register - ეს მაგალითი განიხილავს SPI მოდულთან მუშაობას 74HC595 ცვლის რეგისტრის მაგალითად. LED-ები დაკავშირებულია რეესტრთან, B პორტის მე-4 ხაზი (არა SS პინი) გამოიყენება როგორც CS ხაზი. რეესტრის DS ხაზი (14 ფეხი) მიდის MOSI-ზე (PB5), SHCP ხაზი (11 ფეხი) SCK ხაზზე (PB7), STCP ხაზი (12 ფეხი) SS ხაზზე (PB4). ხაზები MR (მე-10 ფეხი) და OE (მე-13 ფეხი) უნდა იყოს გაყვანილი მაღალ და დაბალ ლოგიკურ დონეზე, შესაბამისად. ტაიმერის გამოყენებით მიკროკონტროლერი ცვლის LED-ების მდგომარეობას: ლუწი და კენტი LED-ები მონაცვლეობით ანათებენ. თუ თქვენ გაგზავნით ბაიტს UART-ით, ის გამოვა პორტში LED-ებზე. მოციმციმე რეჟიმზე გადასასვლელად, თქვენ უნდა გაგზავნოთ 0x00 (ნული) UART-ით. დოკუმენტაცია 74HC595 ჩიპისთვის.

ჩამოტვირთეთ მაგალითი

SG-90 Servo - ეს მაგალითი განიხილავს SG-90 სერვო დისკთან მუშაობას. აპარატურა PWM გამოიყენება. სერვო PWM ხაზი დაკავშირებულია ტექნიკის PWM A არხთან. შემობრუნების ღილაკები დაკავშირებულია PD2 და PD3 ხაზებთან. ღილაკი ხაზი PD2 ზრდის პულსის ხანგრძლივობას, ღილაკი ხაზის PD3 ამცირებს პულსის ხანგრძლივობას. პულსის ხანგრძლივობა მერყეობს 1-დან 2 ms-მდე. სერვოძრავის აღწერა.

ჩამოტვირთეთ მაგალითი

RGB ნათურა - ეს მაგალითი განიხილავს სამფეროვან RGB LED-თან მუშაობას. განხორციელდა გლუვი ფერის გადასვლა PWM პროგრამული უზრუნველყოფის გამოყენებით. წითელი, მწვანე და ლურჯი ხაზები დაკავშირებულია პორტის D ხაზებთან 2, 3 და 4, შესაბამისად.

ჩამოტვირთეთ მაგალითი

TSOP4836 NEC - ეს მაგალითი აჩვენებს მუშაობას TSOP4836 ფოტოდეტექტორთან და NEC გადაცემის პროტოკოლთან, რომელიც ფართოდ გამოიყენება ინფრაწითელი დისტანციური მართვის პულტებში. როდესაც ბრძანება მიიღება, მისი კოდი გამოჩნდება. 7-სეგმენტიანი ინდიკატორის კავშირი წინა მაგალითების მსგავსია. ფოტოდეტექტორის აღწერა.

ჩამოტვირთეთ მაგალითი

WS2812 Ring – ეს მაგალითი განიხილავს WS2812 LED-ებთან მუშაობას ჩაშენებული PWM კონტროლერით. 16 LED-იანი რგოლი დაკავშირებულია კონტროლერთან (რინგზე LED-ების რაოდენობა შეიძლება მითითებული იყოს კოდში). WS2812-თან მუშაობის ბიბლიოთეკა ჩემი არ არის (აღებულია GitHub-დან და ოდნავ შეცვლილია, საავტორო უფლებები დაცულია). პროგრამა ჯერ განსაზღვრავს ფერების მასივს (წითელი, მწვანე, ლურჯი), შემდეგ კი ციკლში ისინი იცვლებიან და შეუფერხებლად ცვლიან ინტენსივობას. პირველი LED-ის IN ხაზი უკავშირდება D პორტის PD2 ხაზს. LED-ების აღწერა.

ჩამოტვირთეთ მაგალითი

MFRC522 RFID - ეს მაგალითი განიხილავს MFRC522 RFID ბარათის წამკითხველთან მუშაობას. მკითხველი დაკავშირებულია კონტროლერთან სტანდარტული სქემის მიხედვით. MFRC522-თან მუშაობის ბიბლიოთეკა ჩემი არ არის (აღებულია GitHub-დან და ოდნავ შეცვლილია, საავტორო უფლებები დაცულია). გაშვებისას, კონტროლერი განსაზღვრავს წამკითხველის ტიპს და აგზავნის მონაცემებს UART-ში. ამას მოჰყვება RFID მოწყობილობის გამოვლენის უწყვეტი ტესტირება. როდესაც წარადგენთ ბარათს ან გასაღებს, მისი მისამართი იკითხება და იგზავნება UART-ში (მისამართი 32 ბიტი, 4 ბაიტი). მკითხველის აღწერა.




ATMega16 MCU-ს აქვს სამი ტაიმერი/მრიცხველი - ორი 8-ბიტიანი (Timer/Counter0, Timer/Counter2) და ერთი 16-bit (Timer/Counter1). ყოველი მათგანი შეიცავს სპეციალურ რეგისტრებს, რომელთაგან ერთ-ერთია მთვლელი რეგისტრი TCNTn (n არის რიცხვი 0, 1 ან 2). ყოველ ჯერზე, როცა პროცესორი ასრულებს ერთ ინსტრუქციას, ამ რეესტრის შიგთავსი იზრდება ერთით (ყოველ 8, 64, 256 ან 1024 საათის ციკლში). ამიტომ მას თვლადი ეწოდება. გარდა ამისა, არსებობს შედარების რეგისტრი OCRn (Output Compare Register), რომელშიც ჩვენ თვითონ შეგვიძლია ჩავწეროთ ნებისმიერი რიცხვი. 8-ბიტიან მრიცხველს აქვს 8-ბიტიანი რეგისტრები. პროგრამის შესრულებისას TCNTn-ის შინაარსი იზრდება და რაღაც მომენტში ის დაემთხვევა OCRn-ის შინაარსს. შემდეგ (თუ მითითებულია სპეციალური პარამეტრები) TIFR შეფერხების დროშის რეესტრში (Timer/Counter Interrupt Flag Register), ერთ-ერთი ბიტი ხდება ერთის ტოლი და პროცესორი, როდესაც ხედავს შეფერხების მოთხოვნას, მაშინვე შორდება გაუთავებელი მარყუჟის შესრულებას და მიდის. ტაიმერის შეწყვეტის სერვისისთვის. ამის შემდეგ პროცედურა მეორდება.

ქვემოთ მოცემულია CTC (Clear Timer on Compare) რეჟიმის დროის დიაგრამა. ამ რეჟიმში, დათვლის რეგისტრი იშლება, როდესაც TCNTn და OCRn შიგთავსი ემთხვევა და შესაბამისად იცვლება ზარის შეწყვეტის პერიოდი.

ეს შორს არის ტაიმერის/მრიცხველის მუშაობის ერთადერთი რეჟიმისგან. თქვენ არ გჭირდებათ დათვლის რეგისტრის გასუფთავება მატჩის მომენტში, მაშინ ეს იქნება პულსის სიგანის მოდულაციის რეჟიმი, რომელსაც განვიხილავთ შემდეგ სტატიაში. თქვენ შეგიძლიათ შეცვალოთ დათვლის მიმართულება, ანუ პროგრამის გაშვებისას შემცირდება დათვლის რეგისტრის შინაარსი. ასევე შესაძლებელია დათვლა არა პროცესორის მიერ შესრულებული ბრძანებების რაოდენობით, არამედ ძაბვის დონის ცვლილებების რაოდენობით "ფეხზე" T0 ან T1 (მრიცხველის რეჟიმი); შეგიძლიათ ავტომატურად, პროცესორის მონაწილეობის გარეშე. , შეცვალეთ OCn ფეხების მდგომარეობა ტაიმერის მდგომარეობის მიხედვით. Timer/Counter1-ს შეუძლია შედარების გაკეთება ერთდროულად ორ არხზე - A ან B.

ტაიმერის დასაწყებად, თქვენ უნდა დააყენოთ შესაბამისი ბიტები ტაიმერის საკონტროლო რეესტრში TCCRn (Timer/Counter Control Register), რის შემდეგაც იგი დაუყოვნებლივ იწყებს მუშაობას.

ჩვენ განვიხილავთ ტაიმერის მუშაობის მხოლოდ ზოგიერთ რეჟიმს. თუ გჭირდებათ სხვა რეჟიმში მუშაობა, მაშინ წაიკითხეთ მონაცემთა ცხრილი ATMega16-ისთვის - იქ ყველაფერი დაწვრილებით წერია ინგლისურად, C-ში და ასამბლერში პროგრამების მაგალითებიც კი არის მოყვანილი (ტყუილად არ არის დაბეჭდილი 357 გვერდი. ტექსტი!).

ახლა მოდით გადავიდეთ ღილაკებზე.

თუ ვაპირებთ ღილაკების მცირე რაოდენობას (9 ცალამდე) გამოყენებას, მაშინ ისინი უნდა იყოს დაკავშირებული გრუნტსა და ნებისმიერი მიკროკონტროლერის პორტის ქინძისთავებს შორის. ამ შემთხვევაში, თქვენ უნდა შეასრულოთ ეს ქინძისთავები DDRx რეესტრში შესაბამისი ბიტების დაყენებით და შიდა ასაწევი რეზისტორის ჩართვით PORTx რეესტრში ბიტების დაყენებით. ამ შემთხვევაში, ამ „ფეხებზე“ ძაბვა იქნება 5 ვ. ღილაკზე დაჭერისას, MK შეყვანა იკეტება GND-ზე და მასზე ძაბვა ეცემა ნულამდე (ან შეიძლება პირიქით იყოს - MK გამომავალი. დეპრესიულ მდგომარეობაშია მიწასთან მოკლე). ეს ცვლის PINx რეგისტრს, რომელიც ინახავს პორტის ამჟამინდელ მდგომარეობას (განსხვავებით PORTx-ისგან, რომელიც ადგენს პორტის მდგომარეობას, როდესაც დატვირთვა არ არის, ანუ ღილაკების დაჭერამდე). PINx სტატუსის პერიოდული წაკითხვით, შეგიძლიათ განსაზღვროთ, რომ ღილაკი დაჭერილია.

ყურადღება!თუ თქვენი ღილაკისთვის DDRx რეესტრში შესაბამისი ბიტი დაყენებულია 1-ზე, მაშინ ღილაკზე კარგად დაჭერით შეიძლება გამოიწვიოს მცირე პიროტექნიკური ეფექტი - კვამლის გამოჩენა MCU-ის გარშემო. ბუნებრივია, ამის შემდეგ MK-ს სანაგვეში გადაყრა მოუწევს...

მოდით გადავიდეთ პრაქტიკულ ნაწილზე. შექმენით ახალი სამუშაო სივრცე და ახალი პროექტი IAR-ში სახელით, როგორიცაა TimerButton. დააყენეთ პროექტის პარამეტრები, როგორც ეს აღწერილია წინა სტატიაში. ახლა მოდით აკრიფოთ შემდეგი პატარა კოდი.

#შეიცავს"iom16.h" ბათილად init_timer0( ბათილად) //ტაიმერის/მთვლელის ინიციალიზაცია( OCR0 = 255; //შედარების რეგისტრის შიგთავსი //დააყენეთ ტაიმერის მუშაობის რეჟიმი TCCR0 = (1 void init_timer2( ბათილად) //ტაიმერის/მთვლელის ინიციალიზაცია2( OCR2 = 255; TCCR2 = (1 //დააყენეთ მისთვის მატჩის შეწყვეტა) ბათილადმთავარი ( ბათილად) (DDRB = 255; init_timer0(); init_timer2(); ხოლო(1) { } } #პრაგმავექტორი = TIMER2_COMP_vect //ტაიმერის შეწყვეტა 2 __შეწყვეტა ბათილადმოციმციმე () ( თუ((PORTB & 3) == 1) ( PORTB &= (0xFF // PB0, PB1 PORTB |= 2; // ჩართეთ PB1 } სხვა( PORTB &= (0xFF // PB0, PB1 PORTB |= 1; // ჩართეთ PB0 } }

ვნახოთ, როგორ მუშაობს. init_timern ფუნქციები ადგენს ბიტებს TCCRn, OCRn და TIMSK რეგისტრებში და ეს მეთოდი შეიძლება უცნაურად ან უცნობი ჩანდეს ზოგიერთისთვის. ჯერ უნდა ავხსნათ, რა არის ჩანაწერი „(1

სადაც a არის რიცხვი, რომლის ორობითი გამოსახულება უნდა გადავიდეს, და b მიუთითებს რამდენი ბიტით უნდა გადაიტანოს. ამ შემთხვევაში, a-ში შენახული მნიშვნელობის დაკარგვა შესაძლებელია (ანუ, ყოველთვის არ არის შესაძლებელი C-დან იმის აღდგენა, რაც იყო a-ში). მოდით შევხედოთ მაგალითს:

რა დასრულდება C-ში C = (22) ხაზის შესრულების შემდეგ

ბინარულ კოდში 2 გამოიყურება 00010110, ხოლო მარცხნივ 3 ბიტით გადასვლის შემდეგ მივიღებთ C = 10110000.

ანალოგიურად, არის ცვლა მარჯვნივ. Სხვა მაგალითი:

char C; … C = ((0xFF > 2);

ჯერ შესრულდება მოქმედება შიდა ფრჩხილებში (0xFF არის 255 თექვსმეტობით კოდში), 11111111-დან შედეგი იქნება 11111100, შემდეგ მოხდება ცვლა მარჯვნივ და მივიღებთ C = 00111111. როგორც ვხედავთ, აქ არის ორი. ურთიერთშებრუნებულმა ოპერაციებმა სხვა რიცხვამდე მიგვიყვანა, რადგან ორი ბიტი დავკარგეთ. ეს არ მოხდებოდა, C ცვლადი რომ იყოს int ტიპის, რადგან int იკავებს 16 ბიტს.

ახლა მოდით შევხედოთ კიდევ ორ ბიტ ოპერატორს, რომლებიც ფართოდ გამოიყენება MK პროგრამირებაში. ეს არის bitwise და (&) და bitwise ან (|) ოპერატორები. როგორ მუშაობენ ისინი, ვფიქრობ, ნათელი იქნება მაგალითებიდან:

მოქმედება: შედეგი (ორობითად): C = 0; // C = 00000000 C = (1 // C = 00100101 C |= (1 // C = 00101101 C &= (0xF0 >> 2); // C = 00101100 C = (C & 4) | 3; // C = 00000111

Თითქმის დამავიწყდა! ასევე არსებობს „ბიტიური ექსკლუზიური ან“ (^). ის ადარებს შესაბამის ბიტებს რიცხვში და თუ ისინი ერთნაირია, აბრუნებს 0-ს, წინააღმდეგ შემთხვევაში ერთს.

დავუბრუნდეთ ჩვენს პროგრამას. ნათქვამია "(1

/* ტაიმერი/მრიცხველი 0 სამართავი რეგისტრაცია */ #განსაზღვრა FOC0 7 #განსაზღვრა WGM00 6 #განსაზღვრა COM01 5 #განსაზღვრა COM00 4 #განსაზღვრა WGM01 3 #განსაზღვრა CS02 2 #განსაზღვრა CS01 1 #განსაზღვრა CS00 0

პროგრამის შედგენისას WGM01 ჩანაწერი უბრალოდ იცვლება ნომრით 3 და შედეგი არის სწორი ჩანაწერი. WGM01 ეწოდება მაკრო და, ცვლადისგან განსხვავებით, ის არ იკავებს ადგილს მეხსიერებაში (გარდა პროგრამისტის მეხსიერებისა :-).

თუ ახლა გადახედავთ მონაცემთა ცხრილს, ადვილი იქნება იმის დანახვა, რომ WGM01 არის მესამე ბიტის სახელი TCCR0 რეესტრში. იგივე ეხება ამ რეგისტრის დარჩენილ ბიტებს. ეს დამთხვევა არ არის შემთხვევითი და ეხება ყველა MK რეგისტრს (ან თითქმის ყველა). ანუ „(1

სულ, ხაზი

ნიშნავს, რომ CTC რეჟიმი ჩართულია, როდესაც ტაიმერი 0 ჩაირთვება, იცვლება "ფეხის" OS0 (aka PB3) მდგომარეობა, მრიცხველის შინაარსი იზრდება ყოველ 1024 საათის ციკლში.

ანალოგიურად ტაიმერი 2-ისთვის: TCCR2 = (1

TIMSK რეგისტრი (Timer/counter Interrupt MaSK register) ადგენს შეწყვეტის რეჟიმს. Ჩვენ დავწერეთ

რაც ნიშნავს ტაიმერის 2-ის შეწყვეტას, როდესაც TCNT2 და OCR2 ემთხვევა. ბოლო ფუნქცია არის Timer2 Match Interrupt ფუნქცია. შეფერხებები გამოცხადებულია შემდეგნაირად:

#პრაგმის ვექტორი= ვექტორი __გააწყვეტინეთ TYPE NAME()

სადაც VECTOR არის შეწყვეტის ვექტორული მაკრო (იგულისხმება უბრალოდ რიცხვი, რომელიც ახასიათებს ამ შეწყვეტას); ეს მაკრო ჩამოთვლილია iom16.h ფაილში პრიორიტეტის შემცირების მიხედვით. TYPE არის ფუნქციის მიერ დაბრუნებული მნიშვნელობის ტიპი, ჩვენს შემთხვევაში void (არაფერი). NAME – მორგებული სახელი ამ ფუნქციისთვის. შეფერხებებით, ჩვენ კიდევ გვექნება დრო, რომ ვიმუშაოთ მომავალში.

ჩვენი ფუნქციის შესრულებისას რიგრიგობით უნდა ციმციმდეს PB0 და PB1-თან დაკავშირებული LED-ები. როგორც ჩანს, სიხშირე არის 11059200/(256*1024) = 42 ჰც. ის სწრაფია, მაგრამ შესამჩნევი იქნება შეუიარაღებელი თვალით. სხვათა შორის, ტაიმერების გამოყენება შესაძლებელს ხდის ზუსტი დროის ინტერვალების დათვლას, რომლებიც არ არის დამოკიდებული თქვენი პროგრამის სირთულეზე და მისი შესრულების თანმიმდევრობაზე (მაგრამ თუ თქვენ გაქვთ არაუმეტეს ერთი შეფერხება).

ასე რომ, შეინახეთ ფაილი როგორც "TimerDebug.c", დაამატეთ იგი პროექტში, შეადგინეთ იგი, გამოანათეთ MK. რას ვხედავთ? პინ PB3-თან დაკავშირებული LED აქტიურად ციმციმებს, მაგრამ PB0 და PB1-ზე ცვლილებები არ იქნება. Რა მოხდა? მართლა რამე არასწორია?

ამის გასარკვევად, ჩვენ მოგვიწევს ჩვენი პროგრამის გამართვა. ვინაიდან IAR-ს არ აქვს Debugger, თქვენ მოგიწევთ გამოიყენოთ AVR Studio. განვითარების ამ გარემოს ჩამოტვირთვა შესაძლებელია მწარმოებლის ვებსაიტიდან http://atmel.com. არამგონია მის ინსტალაციას რაიმე პრობლემა ჰქონდეს. AVR Studio-ს დაწყებამდე აირჩიეთ გამართვის რეჟიმი IAR-ში და შექმენით გამართვის cof ფაილი (პროექტის ყველა ვარიანტი უნდა იყოს დაყენებული, როგორც აღწერილია წინა სტატიაში).

AVR Studio-ს გახსნის შემდეგ, ჩვენ ვნახავთ მისასალმებელ ფანჯარას, რომელშიც ვირჩევთ "გახსნას". ახლა ჩვენ შევდივართ პროექტის საქაღალდეში, იქ Debug\Exe-ში, აირჩიეთ "TimerDebug.cof", ვქმნით პროექტს, სადაც ისინი გვთავაზობენ, აირჩიეთ ATMega16 მოწყობილობა და Simulator გამართვის რეჟიმი. ამის შემდეგ, თუ ყველაფერი სწორად გაკეთდა, მაშინვე იწყება გამართვის პროცესი

გამართვის გარემო აქ ძალიან მოსახერხებელია, რადგან... საშუალებას გაძლევთ ნახოთ ყველა MK რეგისტრის შინაარსი, ასევე ხელით დააყენოთ მათთვის მნიშვნელობები მაუსის დაწკაპუნებით. მაგალითად, თუ თქვენ დააყენეთ შეფერხების დროშა TIFR რეესტრში მე-7 ბიტში (TIMSK შავი კვადრატის ქვეშ), მაშინ პროგრამის შემდეგი ნაბიჯი (F10 ან F11 დაჭერით) უნდა იყოს შეფერხების დამუშავება (დროშა ავტომატურად დაყენდება, როდესაც TCNT2 და OCR2 რეგისტრები ემთხვევა). მაგრამ ჩვენდა გასაკვირად, შეფერხება არ იქნება!

ჩნდება კითხვა: რატომ?

მოდით გავხსნათ CPU რეგისტრი, SREG. ეს რეესტრი განსაზღვრავს პროცესორის მუშაობას და კონკრეტულად მისი მეშვიდე ბიტი (I-bit, Interrupt bit) პასუხისმგებელია MK-ში ყველა შეფერხების დამუშავებაზე. ჩვენ არ გვაქვს დაყენებული. როგორც კი დააყენებთ, შეწყვეტა მაშინვე შესრულდება (თუ TIFR-ში მეშვიდე ბიტი ერთდროულად არის დაყენებული).

თქვენ შეგიძლიათ შეამჩნიოთ ერთი საინტერესო თვისება: როგორც კი პროცესორი გადადის შეფერხების დამუშავებაში, ეს ბიტი (შეწყვეტის დამუშავების ჩართვის დროშა) იშლება და შეფერხების ფუნქციიდან გასვლისას ის ავტომატურად დაყენებულია ხელახლა. ეს არ აძლევს საშუალებას პროცესორს, ერთი შეფერხების შესრულების გარეშე, აითვისოს მეორე (ბოლოს და ბოლოს, პროგრამაში ნავიგაცია ხდება ზუსტად ამ გზით - დროშებით).

ეს ნიშნავს, რომ თქვენ უნდა დაამატოთ კოდის ხაზი ამ ბიტის ერთზე დასაყენებლად. ჩვენ მას დავამატებთ init_timer2 ფუნქციას. თქვენ მიიღებთ შემდეგს:

ბათილად init_timer2( ბათილად) ( SREG |= (1 //დაამატა ეს ხაზი OCR2 = 255; TCCR2 = (1

ახლა, როდესაც შევარჩიეთ გამოშვების კონფიგურაცია და გავანათეთ MK F7 დაჭერით და AVReal32.exe-ის გაშვებით, მოხარული ვიქნებით დავინახოთ, რომ ყველაფერი მუშაობს ისე, როგორც უნდა.

კომენტარი:პროგრამის გამართვისას, თქვენ უნდა შეამციროთ ტაიმერის ინტერვალები, თუ ისინი ძალიან გრძელია, რადგან AVR Studio-ში გამართვისას პროგრამა მუშაობს ათასობით ჯერ უფრო ნელა, ვიდრე MK-ში და თქვენ არ დაელოდებით ტაიმერის გააქტიურებას. ზოგადად, გამართვა სრულიად მსგავსია პროგრამირების სხვა სისტემებში, როგორიცაა Visual C++.

ახლა, როდესაც ვისწავლეთ პროგრამების გამართვა, შევქმნათ ახალი ფაილი IAR-ში (და შეინახოთ ძველი და წავშალოთ იგი პროექტიდან) და ჩაწერეთ შემდეგი კოდი:

#შეიცავს"iom16.h" დიდხანს ხელმოუწერელი ინტმრიცხველი = 0; //დროის ინტერვალების ფორმირების მრიცხველი ხელმოუწერელი სიმბოლო B0Pressed = 0; //ღილაკ0-ის მდგომარეობა ინახება აქ (0 - არ არის დაჭერილი, 1 - დაჭერილი) ხელმოუწერელი სიმბოლო B1Pressed = 0; //ღილაკის 1 მდგომარეობა ინახება აქ (0 - არ არის დაჭერილი, 1 - დაჭერილი) //ტაიმერის ინიციალიზაცია2 //აუცილებელია მრიცხველის გაზრდა ყოველ 11059 საათის ციკლში (1 ms). ჩვენ ვიღებთ მას ყოველ 1.001175 ms ბათილად init_timer2() ( OCR2 = 173; TCCR2 = (1 // I/O პორტების ინიციალიზაცია init_io_ports() ( DDRA =(1//დაყოვნების ფორმირება პაუზა_მმ მილიწამში ბათილადდაგვიანებით ( დიდხანს ხელმოუწერელი ინტპაუზა_მმ) ( მრიცხველი = 0; ხოლო(counter void main() ( SREG |= (1 //init_timer2(); //ჩართეთ ტაიმერი2 ყოველ 64 ტკიპზე, დაითვალეთ 173-მდე init_io_ports(); //I/O პორტების ჩართვა ხოლო(1) { //დამუშავების ღილაკი 0 თუ(B0დაჭერილი == 1) { //ზრდის PORTB-ს, ელოდება გამოშვებას PORTB++; B0Pressed = 0; ხოლო((PINC და (1 სხვა ( თუ((PINC & (1 //ასწორებს დაჭერას ( დაგვიანებით(50); თუ((PINC & (1 //ამოწმებს დაჭერით ( B0Pressed = 1; } } } //დამუშავების ღილაკი 1 თუ(B1დაჭერილი == 1) //თუ დააჭირეთ ღილაკს, { //ამცირებს PORTB-ს, ელოდება გამოშვებას PORTB--; B1Pressed = 0; ხოლო((PINC და (1 სხვა ( თუ((PINC & (1 //ასწორებს დაჭერას ( დაგვიანებით(200); //გასაღების აღმოფხვრა თუ((PINC & (1 //ამოწმებს დაჭერით ( B1Pressed = 1; //აყენებს „ღილაკზე დაჭერის“ დროშას } } } } } //შეწყვეტა ტაიმერით 2, ასე რომ მრიცხველი იზრდება #პრაგმის ვექტორი= TIMER2_COMP_vect __გააწყვეტინეთ void inc_delay_counter() (counter++;)

პირველ რიგში, მე გთავაზობთ აიღოთ მზა firmware ფაილი (ფაილები სტატიისთვის, Release საქაღალდე, TimerButton.hex ფაილი ან ამ ტექსტის შედგენა) და ჩაწეროთ იგი MK-ში. შემდეგ ამოიღეთ პროგრამული უზრუნველყოფის კაბელი, შეაერთეთ ღილაკები PC0 და PC1 და სცადეთ დააჭიროთ მათ. ჩვენ დავინახავთ, რომ ერთ-ერთ ღილაკზე დაჭერისას PORTB რეგისტრი იზრდება (LED-ები ანათებენ), ხოლო მეორეზე დაჭერისას ის მცირდება. თუ ეს არ მუშაობს, სცადეთ ერთი ღილაკის დაჭერა მეორეზე - იმუშავებს. ფაქტია, რომ ღილაკები შემდეგნაირად შევაერთე: ღილაკზე დაჭერისას MK გამომავალი ჰაერში „იკიდება“ და გაშვებისას შორტები მიწაზე. თუ ღილაკები სხვაგვარად დააკავშირეთ, პროგრამის ოდნავ მოდერნიზაცია მოგიწევთ.

მოდით შევხედოთ კოდს. აქ ტაიმერთან მუშაობა გარკვეულწილად განსხვავებულად არის ორგანიზებული. ის მუშაობს ყოველ 11072 საათის ციკლში (ანუ ყოველ 1.001175 ms) და ზრდის მრიცხველის ცვლადს. ასევე არსებობს ფუნქციის დაყოვნება (გრძელვადიანი ხელმოუწერელი int Pause_ms), რომელიც პარამეტრად იღებს მილიწამების რაოდენობას Pause_ms, აღადგენს მრიცხველს და ელოდება მრიცხველის Pause_ms მნიშვნელობის მიღწევას, რის შემდეგაც MK აგრძელებს მუშაობას. ამრიგად, დაგვიანებით(1500) ჩაწერით ჩვენ შევქმნით პროგრამაში 1,5 წამის შეფერხებას. ეს ძალიან მოსახერხებელია დროის ინტერვალების ფორმირებისთვის.

როგორც ჩანს, ტაიმერით ყველაფერი ნათელია. მაგრამ რისთვის გამოიყენება? განვიხილოთ უსასრულო მარყუჟი while(1) main(). ეს ციკლი ამოწმებს ღილაკების მდგომარეობას PINB რეგისტრის შინაარსის ანალიზით. რატომ არის იქ 50 ms დაგვიანება? ეს არის აღმოფხვრა ე.წ. "გასაღების საუბარი" ფაქტია, რომ ღილაკზე დაჭერისას ერთი კონტაქტი ხვდება მეორეს და რადგან კონტაქტები ლითონისაა, ეს ზემოქმედება ელასტიურია. კონტაქტები, გაზაფხულზე, რამდენჯერმე იხურება და იხსნება, მიუხედავად იმისა, რომ თითმა მხოლოდ ერთი დაჭერა გააკეთა. ეს იწვევს MK ჩაწერას რამდენიმე დაწკაპუნებით. მოდით შევხედოთ ძაბვის გრაფიკს PC0 გამომავალზე დროის წინააღმდეგ. ეს შეიძლება ასე გამოიყურებოდეს:

წერტილი A არის ღილაკის დაჭერის მომენტი. ეს შეიძლება დაფიქსირდეს MK-ით. შემდეგ არის რამდენიმე მოკლე ჩართვა და ღია სქემები (შეიძლება არ იყოს არცერთი, ან შეიძლება იყოს 12 მათგანი - ეს ფენომენი შეიძლება შემთხვევით ჩაითვალოს). B წერტილში კონტაქტი უკვე უსაფრთხოდ არის დაფიქსირებული. A-სა და B-ს შორის საშუალოდ არის დაახლოებით 10 ms. საბოლოოდ, D წერტილში ხდება გახსნა. როგორ დავაღწიოთ თავი ამ უსიამოვნო ფენომენს? გამოდის, რომ ძალიან მარტივია. აუცილებელია ჩაწეროთ ღილაკის დაჭერის მომენტი (პუნქტი A), გარკვეული დროის შემდეგ, მაგალითად, 50 ms (წერტილი C), შეამოწმოთ, რომ ღილაკი ნამდვილად დაჭერილია, განახორციელოთ ამ ღილაკის შესაბამისი მოქმედება და დაელოდოთ მომენტს. ის გათავისუფლდება (დ წერტილი). ანუ, თქვენ უნდა გააკეთოთ პაუზა A-დან C-მდე, ისე, რომ ყველა "მოციმციმე" იყოს ამ პაუზის შიგნით. ახლა სცადეთ ამოიღოთ ხაზი, რომელიც ქმნის შეფერხებას, შეადგინეთ პროგრამა და შეაერთეთ იგი MK-ში. ღილაკების უბრალოდ დაჭერით შეგიძლიათ დარწმუნდეთ, რომ მთელი ეს „ტანჯვა“ უშედეგო არ იყო.

მაგრამ რა უნდა გააკეთოთ, თუ გჭირდებათ, ვთქვათ, 40 ღილაკის დაკავშირება MK-ზე? ყოველივე ამის შემდეგ, მას მხოლოდ 32 ქინძისთავები აქვს. როგორც ჩანს, გზა არ არის. რეალურად შესაძლებელია. ამ შემთხვევაში გამოიყენება ალგორითმი, რომელსაც ეწოდება კარიბჭე. ამისათვის თქვენ უნდა დააკავშიროთ ღილაკები მატრიცის სახით, როგორც ეს ნაჩვენებია ფიგურაში (ფიგურა აღებულია მორტონის წიგნიდან "MK AVR, შესავალი კურსი", სადაც წერია AVR პროგრამირების შესახებ ასამბლერში).

როდესაც მიმართა გამომავალ PB0 ჟურნალს. 1 (+5V) და PB1 და PB2 ჟურნალის დასამაგრებლად. 0 იძლევა 1, 4 და 7 ღილაკების დამუშავებას. ამის შემდეგ, თითოეული მათგანის სტატუსის გარკვევა შესაძლებელია ერთ-ერთ PB3..PB5 პინზე ძაბვის შემოწმებით. ამრიგად, თანმიმდევრულად გამოყენება PB0..PB2 ლოგინზე. 1, ყველა ღილაკის სტატუსის დადგენა შესაძლებელია. გასაგებია, რომ PB0..PB2 ქინძისთავები უნდა იყოს გამოსავალი, ხოლო PB0..PB2 შეყვანები. იმის დასადგენად, თუ რამდენი ქინძისთავია საჭირო X ღილაკების მასივისთვის, თქვენ უნდა იპოვოთ X ფაქტორების წყვილი, რომელთა ჯამი ყველაზე მცირეა (ჩვენს შემთხვევაში 40 ღილაკით, ეს იქნება რიცხვები 5 და 8). ეს ნიშნავს, რომ 256-მდე ღილაკი შეიძლება დაერთოს ერთ MK-ს (და კიდევ უფრო მეტი დეკოდერების გამოყენებით, მაგრამ უფრო მოგვიანებით დეკოდერებზე). უმჯობესია გააკეთოთ ნაკლები ქინძისთავები და მეტი ქინძისთავები. ამ შემთხვევაში, მატრიცის ყველა მწკრივის სკანირებას ნაკლები დრო დასჭირდება. კავშირის ეს მეთოდი (strobe) არ არის უნიკალური ღილაკებისთვის. აქ შეგიძლიათ დააკავშიროთ სხვადასხვა მოწყობილობები, LED მატრიცებიდან ფლეშ მეხსიერების ჩიპებამდე.

© Kiselev Roman
2007 წლის ივნისი

ასე რომ, ჩვენ მივედით მიკროკონტროლერების უმეტესი პროექტების განუყოფელ ნაწილთან - ღილაკებთან. ღილაკი საკმაოდ მარტივი მოწყობილობაა, რომელსაც, როგორც წესი, აქვს მხოლოდ ორი მდგომარეობა; პროგრამირების ენაში ეს არის ლოგიკური 1 (კონტაქტები დახურული) და ლოგიკური 0 (კონტაქტები ღიაა). მოდით შევხედოთ დიაგრამას.

ჩვენ ჯერ კიდევ გვაქვს იგივე სქემა შვიდსეგმენტიანი ინდიკატორებით, მაგრამ დამატებულია 4 ღილაკი. A ჯგუფის ღილაკების გამოყენებით ჩვენ გავზრდით ან ვამცირებთ გამოჩენილ მნიშვნელობას პირველ სამ ინდიკატორზე, ხოლო B ჯგუფის ღილაკების გამოყენებით შევცვლით მნიშვნელობას ბოლო ორ ინდიკატორზე.

ჯერ მოკლედ ვისაუბროთ ღილაკებზე. ღილაკები შეიძლება გამოყენებულ იქნას ჩვეულებრივ ღია კონტაქტებით, ჩაკეტვის გარეშე. ჩვენ ვაკავშირებთ ერთ კონტაქტს მიწასთან, ხოლო მეორეს მიკროკონტროლერის ცალკეულ ქინძისთავებთან. ჩვენ არ დავაყენებთ ასაწევ რეზისტორს პოზიტიურზე, რადგან ის მოწოდებულია თავად მიკროკონტროლერში. რჩება მხოლოდ პროგრამის დაწერა ღილაკების გამოკითხვისთვის (მიკროკონტროლერის ქინძისთავების მდგომარეობა) და შედეგის ჩვენება ინდიკატორებზე. სქემის სიმარტივისა და მკითხველების სირთულეების გამო C პროგრამის გაგებაში,ამ განყოფილებაში ძირითადი აქცენტი გაკეთდება პროგრამის ანალიზზე.

ასე რომ, პროგრამა.

#შეიცავს //include ბიბლიოთეკები #include #define SPI_SS PB2 //SS output #define SPI_MOSI PB3 //MOSI output #define SPI_MISO PB4 //MISO output #define SPI_SCK PB5 //SCK output #define BUTTON_AP PD4 //A+ ღილაკი გამომავალი #define BUTTONA //_ - #define BUTTON_BP PD6 //B+ ღილაკის გამომავალი #define BUTTON_BM PD7 //B- ღილაკის გამომავალი char di; void spi(char cmd,char მონაცემები) //ფუნქცია SPI პროტოკოლით ორი 8-ბიტიანი პაკეტის გადაცემისათვის ( PORTB &= ~(1<999)a=999; //შეამოწმეთ მიაღწია თუ არა a ცვლადმა მაქსიმალურ მნიშვნელობას, თუ(a<0)a=0; //проверка достижения минимального значения переменной a if(b>99)b=99; //შეამოწმეთ მიღწეულია თუ არა b ცვლადის მაქსიმალური მნიშვნელობა, თუ(b<0)b=0; //проверка достижения минимального значения переменной b } return 0; }

Დავიწყოთ. C პროგრამაჩვეულებრივ, ისინი იწყებენ გარე ბიბლიოთეკების შეერთებით. პროგრამის ორი ხაზი პასუხისმგებელია ამაზე:

#შეიცავს #შეიცავს

ავრ/იო.ჰეს არის I/O ბიბლიოთეკა, რომელიც აუხსნის შემდგენელს, თუ რა I/O პორტები აქვს მიკროკონტროლერს, როგორ არის მათი მარკირება და რა შეუძლიათ. და ყველაზე საინტერესო ის არის, რომ ეს ბიბლიოთეკა თავად ირჩევს პროექტის პარამეტრებიდან, თუ რომელ მიკროკონტროლერს სჭირდება აღწერილობების გამოყენება, რაც საშუალებას გაძლევთ გამოიყენოთ ეს ბიბლიოთეკა სხვადასხვა მიკროკონტროლერებისთვის. ეს ბიბლიოთეკა ჯერ უნდა იყოს ჩართული.

მეორე ხშირად გამოყენებული ბიბლიოთეკა არის util/delay.hეხმარება პროგრამის შესრულებაში შეფერხებების შექმნას, რაც საკმაოდ მოსახერხებელია.

#define BUTTON_AP PD4

მიუთითებს რა არის გამოსავალზეPD4 (4 პორტის რეგისტრიბ)ჩვენ დავაკავშირებთ ღილაკსA+ (იხილეთ დიაგრამა). ეს აუცილებელია იმისთვის, რომ თუ მოულოდნელად გადავწყვიტეთ ღილაკის სხვა გამოსავალზე გადართვა, არ დაგვჭირდეს ძიება მთელ პროგრამაში, უბრალოდ შეცვალოთ იგიგანსაზღვრაგამომავალი სახელიPD4სასურველს და ის დარჩება პროგრამაშიBUTTON_AP.მაგრამ დასკვნების შემთხვევაში ამისთვისSPIვერაფერი შეიცვლება მხარდაჭერის გამოSPIაპარატურა და მჭიდროდ არის მიბმული მწარმოებლის მიერ მიკროკონტროლერის ქინძისთავებზე.

პროგრამის შემდეგი საინტერესო ნაწილი არის პორტების აღწერა.

DDRB |= (1<

ასე გადავიდა პორტის ჩამოთვლილი ბიტები გამოსავალზე(ნაგულისხმევად ყველა პორტის ყველა ბიტი დაყენებულია შეყვანად). ეს სტრიქონი შეიძლება ჩაიწეროს შემდეგნაირად მაკრო განსაზღვრების გამოყენების გარეშეგანსაზღვრა

DDRB |= (1<

ეს ჩანაწერები ექვივალენტურია და გამიზნულია 1-ის ჩანაცვლებისთვის რეესტრშიDDRBშესაბამის კატეგორიაშიBR3 (წოდება 3), BR5 (წოდება 5) დაBR2 (წოდება 2). რეესტრის სხვა ნაწილებიDDRBრჩება უცვლელი. თქვენ ასევე შეგიძლიათ დაწეროთ ეს ხაზი ასე

DDRB |= (1<<3)|(1<<5)|(1<<2);

რაც, რა თქმა უნდა, უფრო დამაბნეველია.

შესვლა 1<<3 ნიშნავს, რომ ორობითი ერთეული უნდა გადავიდეს მარცხნივ 3 პოზიციით,პოზიციები მარჯვნივ ივსება ნულებით.

1 <<3 ნიშნავს 1000 (ერთი ნული ნულოვანი ნული) ბინარში. ხოლო ოპერაციის ჩატარებისას(1<<3)|(1<<5) ორობითში ვიღებთ 101000-ს.

პროგრამის შემდეგ სტრიქონში ჩვენ ვაკავშირებთ ღილაკების ასაწევ რეზისტორებს. მოდით ჩავწეროთ ერთეულები რეესტრის შესაბამის ბიტებშიპორტდი

PORTD |= (1<

ეს რეზისტორები ჩაშენებულია მიკროკონტროლერში. მათი დაკავშირება შესაძლებელია პორტის ბიტებთან, იმ პირობით, რომ ეს ბიტები განისაზღვრება, როგორც შემავალი. რეზისტორები უბიძგებენ მიკროკონტროლერის სასურველ პინს ლოგიკა 1-ზე.

დანარჩენი პარამეტრები კეთდება ანალოგიურად მიკროკონტროლერის შესაბამისი რეგისტრების გამოყენებით.

ახლა მოდით გადავხედოთ პროგრამის ძირითად ნაწილს, რომელსაც მიკროკონტროლერი, ძირითადი პარამეტრების შემდეგ, უსასრულოდ ახორციელებს. პროგრამის ეს ნაწილი ჩართულია გაუთავებელ ციკლში.

ხოლო (1) ( );

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

დაგვიანებით_ms(100);

ღილაკების კონტაქტების „ჩამობრუნებისგან“ ცრუ გამოწვევის თავიდან ასაცილებლად. და მეორედ ვამოწმებთ ღილაკებს მათი დაჭერის შესახებ და ვამოწმებთ ადრე დაყენებულ დროშებს დაჭერის შესახებ. თუ პირობები დაკმაყოფილებულია, ჩვენ ვცვლით ინდიკატორებზე გამოსახულ მნიშვნელობებს. შემდეგ ჩვენ აღვადგენთ ღილაკის დაჭერის დროშებს 0-ზე.რის შემდეგაც ციკლი მეორდება.

შემდეგ - დასკვნით ნაწილში - განიხილება ADC (ანალოგური ციფრული გადამყვანი) და ყველა ადრე შესწავლილი პრაქტიკაში გამოყენება.

წინა გაკვეთილებზე განიხილეს მიკროკონტროლერიდან ინფორმაციის გამოტანის მეთოდები: LED-ის და LCD ინდიკატორის დაკავშირება. მაგრამ როგორ შეიტანთ ინფორმაციას მიკროკონტროლერში? ამისათვის ბევრი ვარიანტი და მოწყობილობაა. მაგრამ ახლა, მოდით განვიხილოთ უმარტივესი ვარიანტი, ეს არის ჩვეულებრივი ღილაკი. არსებობს ორი სახის ღილაკი: ტაქტიკა და ჩაკეტვა. ტაქტის ღილაკები მუშაობს შემდეგი პრინციპით: დაჭერით - კონტაქტები იხურება, იხსნება - იხსნება კონტაქტები. აღსანიშნავია, რომ არის ტაქტიანი ღილაკები, რომლებიც თავიდან დახურულია, მაგრამ დაჭერისას იხსნება. ჩამკეტი ღილაკები (მათ ზოგჯერ უწოდებენ: გადართვის გადამრთველებს, ჩამრთველებს, ჩამრთველებს), ტაქტის ღილაკებისგან განსხვავებით, დაჭერისას აფიქსირებენ თავიანთ პოზიციას, ანუ: დაჭერით - კონტაქტები დახურულია, ისევ დაჭერით - კონტაქტები ღიაა. ზოგადად, ჩვენ დავახარისხეთ ღილაკები, ახლა ჩვენ გავარკვევთ, თუ როგორ დავაკავშიროთ ეს ღილაკები მიკროკონტროლერთან. და რეალურად ძალიან მარტივია დაკავშირება! მოდით შევხედოთ დიაგრამას:

შეიძლება იკითხოთ: რატომ რეზისტორი R1? შემდეგ კი, R1 რეზისტორის გარეშე, როდესაც S1 ღილაკი ღიაა, მიკროკონტროლერი პორტზე, რომელსაც ეს ყველაფერი უკავშირდება, დაინახავს ან ლოგიკურ 1-ს ან ლოგიკურ 0-ს, რითაც გამოიწვევს ღილაკის ცრუ სიგნალიზაციას. ამის თავიდან ასაცილებლად, აუცილებელია ამ პორტის „აწევა“ ელექტროენერგიის მიწოდების პოზიტიურ წინააღმდეგობის გაწევით. რეზისტორი R1-ის წინააღმდეგობა შეიძლება იყოს 4.7 kOhm-დან 10 kOhm-მდე. რეზისტორით მიიღება შემდეგი სურათი: დაჭერილია S1 ღილაკი - MK პორტში გამოჩნდება ლოგიკური 0, S1 ღილაკი არ არის დაჭერილი - ლოგიკური 1 ჩნდება MK პორტში R1 წინააღმდეგობის გამო. რა თქმა უნდა, თქვენ უნდა იცოდეთ, რომ ზოგიერთ AVR მიკროკონტროლერს აქვს ჩაშენებული ასაწევი რეზისტორები, რომელთა წინააღმდეგობაა დაახლოებით 50 kOhm; ისინი სტანდარტულად გამორთულია. BASCOM-AVR-ში ამ რეზისტორების ჩართვა შესაძლებელია საჭირო პორტზე ლოგიკური 1-ის ჩაწერით, მაგრამ მე კატეგორიულად არ გირჩევთ ამ ჩაშენებულის გამოყენებას, ბევრად უფრო საიმედოა გარე რეზისტორების გამოყენება, როგორც ზემოთ მოცემულ დიაგრამაზეა ნაჩვენები. კარგად, ჩვენ გავარკვიეთ სქემატური გადაწყვეტა, ახლა ჩვენ გავარკვევთ მას პროგრამულად. ღილაკთან მუშაობისთვის, ჯერ უნდა დააკონფიგურიროთ მიკროკონტროლერის პორტი, როგორც შეყვანა; BASCOM-AVR-ში ეს ასე კეთდება:
კონფიგურაცია(მიკროკონტროლერის პორტი) = შეყვანა
მაგალითი:
კონფიგურაცია PINB.3 = შეყვანა

გთხოვთ გაითვალისწინოთ, რომ შეყვანის პორტის მუშაობისთვის, პორტის სახელი უნდა იწყებოდეს PIN-ით და არა PORT-ით, როგორც გამომავალი პორტის კონფიგურაციისთვის!

შეყვანის პორტის კონფიგურაციის შემდეგ, მისგან შეგვიძლია წავიკითხოთ მნიშვნელობა 1 ან 0, ჩვენს შემთხვევაში 0 - ღილაკი დაჭერილია, 1 - ღილაკი არ არის დაჭერილი. და ჩვენ შეგვიძლია შევამოწმოთ, რომ ღილაკი დაჭერილია ასე:
თუ(მიკროკონტროლერის პორტი) = 0 მაშინ
(თუ დააჭირეთ ღილაკს, შეასრულეთ აქ აღწერილი მოქმედებები)
Დაასრულე თუ
ალტერნატიულად, შეგიძლიათ შეამოწმოთ დაჭერილია თუ არა ღილაკი:
თუ(მიკროკონტროლერის პორტი) = 1 მაშინ
(თუ ღილაკი არ არის დაჭერილი, შეასრულეთ აქ აღწერილი მოქმედებები)
Დაასრულე თუ
მაგალითი:
თუ PINB.3 = 0 მაშინ
PORTB.2 = 1 "თუ ღილაკზეა დაჭერილი, მაშინ ჩართეთ PB.2-თან დაკავშირებული LED
Დაასრულე თუ

მარტივია, არა? ასე რომ, ახლა ვცადოთ მიკროკონტროლერთან ღილაკის დაკავშირება აპარატურაში. საფუძვლად ავიღოთ Attiny13 მიკროკონტროლერი და მისთვის ცოტა ადრე შექმნილი. მათთვის, ვისაც არ გაუკეთებია გამართვის დაფა, აქ არის დიაგრამა:

პროგრამის ალგორითმი ასეთია: S1 ღილაკი დაჭერილია - LED გამორთულია, S1 ღილაკი არ არის დაჭერილი - LED ჩართულია. და აი, თავად პროგრამა BASCOM-AVR-ზე:

$regfile = "attiny13.dat" $crystal = 8000000 Config Pinb.3 = Input Config Portb.2 = გამომავალი გააკეთე თუ Pinb.3 = 0 შემდეგ Portb.2 = 0 თუ Pinb.3 = 1 შემდეგ Portb.2 = 1 მარყუჟი Დასასრული

ეს ისეთი მარტივი პროგრამაა. შედგენილი firmware არის არქივში ქვემოთ. დაუკრავენ ბიტების დაყენება არ არის საჭირო, რადგან ასეთ მარტივ პროგრამაში საათის სიხშირე არ არის განსაკუთრებით მნიშვნელოვანი. ვისაც ეზარება ტექნიკის შეგროვება, არის ჩვენი საყვარელი პროექტი, შეგიძლიათ ჩამოტვირთოთ ქვემოთ მოცემულ არქივში. სქემებთან მუშაობა Proteus სიმულატორში:

ფაილების ჩამოტვირთვა გაკვეთილისთვის (პროექტი ქ , წყაროს კოდი, firmware) შეგიძლიათ ქვემოთ

რადიოელემენტების სია

Დანიშნულება ტიპი დასახელება რაოდენობა შენიშვნაᲛაღაზიაჩემი ბლოკნოტი
IC1 MK AVR 8 ბიტიანი

ATtiny13

1 რვეულში
R1, R2 რეზისტორი

4.7 kOhm

2 რვეულში
R3 რეზისტორი

150 Ohm

1 რვეულში
HL1 სინათლის დიოდი 1