მიკროკონტროლერების პროგრამირების წესი avr. avr მიკროკონტროლერის პროგრამირება

კარგი დღე ძვირფასო რადიომოყვარულო!
მოგესალმებათ საიტზე ""

რა არის მიკროკონტროლერი და რატომ არის საჭირო. მოდით შევხედოთ მის განმარტებას:

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

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

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

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

პროგრამა(თარგმანში ეს სიტყვა ნიშნავს "რეცეპტს") - მომავალი მოვლენების ან მოქმედებების წინასწარი აღწერა.

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

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

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

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

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

Პროგრამირების ენა - ეს არის ბრძანებების, ინსტრუქციების გადაცემის გზა, მიკროკონტროლერისთვის მოქმედების მკაფიო გზამკვლევი.

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

01000110
10010011
01010010

ნაკლებად სავარაუდოა, რომ ვინმემ შეძლოს ორი რიცხვის კომბინაციების ასეთი ნაკრების გარკვევა და პირველი პროგრამისტების მუშაობა ძალიან შრომატევადი იყო. მათი ცხოვრების გასაადვილებლად, პროგრამისტებმა დაიწყეს პირველი პროგრამირების ენების შექმნა. ასე რომ, რაც უფრო ახლოს არის პროგრამირების ენა ნულებისა და ერთეულების ასეთ სიმრავლესთან, მით უფრო "დაბალი დონეა" და რაც უფრო შორს არის მათგან, მით უფრო "მაღალი დონე".
მიკროკონტროლერებისთვის ყველაზე გავრცელებული პროგრამირების ენები:
- დაბალი დონის ენა - ასამბლეერი
- მაღალი დონის ენა - C (Ci)
მოდით შევხედოთ მათი განსხვავების მაგალითს (ეს მაგალითები აბსტრაქტულია).
ვთქვათ, უნდა დავამატო ორი რიცხვი: 25 და 35.
მშობლიურ კოდში, ეს ბრძანება შეიძლება ასე გამოიყურებოდეს:
00000101 1101001
დაბალი დონის ენაზე:
ADD Rd, Rr
მაღალი დონის ენაზე:
25+35
განსხვავება დაბალი და მაღალი დონის ენებს შორის შეუიარაღებელი თვალითაც ჩანს, კომენტარები, როგორც ამბობენ, ზედმეტია.
მაგრამ მოდით უფრო ღრმად ჩავუღრმავდეთ ამ მაგალითებს. ჩვენ არ გავაანალიზებთ მანქანის კოდის მაგალითს, რადგან ის იდენტურია ასამბლერის მაგალითის. თავის არსში, ასამბლეის ინსტრუქციები არის იგივე მანქანის კოდები (ბრძანებები), რომლებსაც უბრალოდ ენიჭებათ ასოების აბრევიატურები, რათა არ დაიკარგონ ნულებში და ერთებში. ასამბლერის ინსტრუქციით ADD Rd, Rr ვაყენებთ მიკროკონტროლერს, რომ დავამატოთ ნაპოვნი ორი რიცხვი (და ამისათვის ჯერ იქ უნდა ჩავწეროთ) - პირველი Rd-ში, მეორე Rr-ში და მოვათავსოთ მიმატების შედეგი. რდ-ში როგორც ხედავთ, მიკროკონტროლერს ძალიან სპეციფიკური დავალება დავუსახეთ: სად მივიღოთ, რა ვუყოთ და სად მივიღოთ შედეგი. ამ შემთხვევაში ჩვენ ვმუშაობთ უშუალოდ მიკროკონტროლერთან.
ბრძანება მაღალი დონის ენაზე: 25+35, ჩვენთვის ნაცნობი მათემატიკური აღნიშვნა, ჩვენი თვალისთვის სასიამოვნო. მაგრამ ამ შემთხვევაში, ჩვენ არ ვმუშაობთ უშუალოდ მიკროკონტროლერთან, ჩვენ უბრალოდ დავალება გვაქვს დავამატოთ ორი რიცხვი. შედეგი და მოქმედებების თანმიმდევრობა ამ შემთხვევაში იგივე იქნება, რაც ასამბლერის ბრძანების შესრულებისას: ჯერ ეს ორი რიცხვი სადღაც ჩაიწერება, შემდეგ დაემატება და შედეგი განთავსდება სადმე.
და აქ არის მთავარი განსხვავება მაღალი დონის და დაბალი დონის ენებს შორის. თუ ასამბლერში ჩვენ ვაკონტროლებთ მთელ პროცესს (გვინდა თუ არა): ჩვენ ვიცით სად წერია ეს ორი რიცხვი და ვიცით სად იქნება შედეგი, მაშინ მაღალი დონის ენაზე ჩვენ არ ვაკონტროლებთ პროცესს. პროგრამა თავად წყვეტს, სად ჩაწეროს წინასწარ რიცხვები და სად მოათავსოს შედეგი. უმეტეს შემთხვევაში, ჩვენ არ გვჭირდება ამის ცოდნა, რადგან ჩვენთვის მთავარი შედეგი გამომავალი რიცხვია 60. შედეგად, მაღალი დონის ენებზე პროგრამები უფრო იკითხება, თვალისთვის სასიამოვნო და უფრო მცირე ზომის - ბოლოს და ბოლოს, ჩვენ არ გვჭირდება "ყველა ხვრელში ასვლა" და მიკროკონტროლერის, პროგრამის ყოველი ნაბიჯის დახატვა. ამას მოგვიანებით აკეთებს ჩვენთვის, როდესაც ის ადგენს მას - თარგმნის მას მანქანის კოდებში. მაგრამ ასევე არის უარყოფითი მხარე. ასემბლერში და C-ში დაწერილ ორ იდენტურ ალგორითმს, მანქანურ კოდებში გადაყვანის შემდეგ, განსხვავებული ზომა ექნება: ასემბლერში დაწერილი პროგრამა 20-40%-ით უფრო მოკლე იქნება ვიდრე C-ში დაწერილი პროგრამა - ეშმაკმა იცის, რომელ გზაზე მიდის C. მივაღწიოთ ჩვენთვის საჭირო შედეგს. და არის შემთხვევები, როცა არ არის ნდობა მაღალი დონის ენაზე და C პროგრამაში ათავსებენ ასემბლერში დაწერილ კოდს.
პროფესიონალმა პროგრამისტებმა, როგორც წესი, იციან პროგრამირების რამდენიმე ენა (ან მუშაობენ გუნდში, რომელიც მოიცავს სხვადასხვა ენის სპეციალისტებს), შემოქმედებითად აერთიანებს მათ მახასიათებლებსა და სარგებელს ერთ პროგრამაში. ჰოდა, ჩვენ, მოყვარულებმა, ერთი ენა მაინც უნდა ვიცოდეთ (დაწყებისთვის) და უნდა დავიწყოთ (და მე ამაში მტკიცედ ვარ დარწმუნებული და ვერავინ დამარწმუნებს) დაბალი დონის ენიდან - ასამბლეა.

კარგი, ვფიქრობ, და აქ ჩვენთვის ყველაფერი ნათელია - თქვენ უნდა ისწავლოთ პროგრამირების ენა, სხვაგვარად - არავითარ შემთხვევაში.

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

არითმეტიკული ლოგიკური ერთეული და მეხსიერების ორგანიზაცია - პროგრამის მეხსიერება, მონაცემთა მეხსიერება, არასტაბილური მეხსიერება



avr-ის ამ გაკვეთილში შევეცადე აღმეწერა ყველა ყველაზე ძირითადი რამ დამწყებთათვის მიკროკონტროლერების დაპროგრამებისთვის. ავრ. ყველა მაგალითი აგებულია მიკროკონტროლერზე atmega8. ეს ნიშნავს, რომ ყველა გაკვეთილის გასამეორებლად დაგჭირდებათ მხოლოდ ერთი MK. როგორც ელექტრონული მიკროსქემის ემულატორი, Proteus გამოიყენება - ჩემი აზრით, საუკეთესო ვარიანტი დამწყებთათვის. პროგრამები ყველა მაგალითში დაწერილია C შემდგენელზე avr CodeVision AVR-ისთვის. რატომ არა ზოგიერთ ასამბლერში? იმის გამო, რომ დამწყები უკვე დატვირთულია ინფორმაციით, და პროგრამა, რომელიც ამრავლებს ორ რიცხვს, იღებს დაახლოებით ას ხაზს ასამბლერში და ისინი იყენებენ C-ს რთულ თამამ პროექტებში. CodeVision AVR შემდგენელი არის გამკაცრებული atmel მიკროკონტროლერებისთვის, აქვს მოსახერხებელი კოდის გენერატორი, კარგი ინტერფეისი და პირდაპირ მისგან შეიძლება მოციმციმე მიკროკონტროლერით.

ეს სახელმძღვანელო აჩვენებს და აგიხსნით მარტივი მაგალითებით, თუ როგორ უნდა:

  • დაიწყეთ მიკროკონტროლერების პროგრამირება, სად უნდა დაიწყოს, რა გჭირდებათ ამისათვის.
  • რა პროგრამები გამოვიყენოთ avr-ისთვის firmware-ის დასაწერად, კომპიუტერზე კოდის სიმულაციისა და გამართვისთვის,
  • რა პერიფერიული მოწყობილობებია MK-ში, როგორ აკონტროლოთ ისინი თქვენი პროგრამის გამოყენებით
  • როგორ ჩავწეროთ მზა პროგრამული უზრუნველყოფა მიკროკონტროლერზე და როგორ გავასწოროთ ის
  • როგორ გააკეთოთ PCB თქვენი მოწყობილობისთვის
იმისათვის, რომ გადადგათ პირველი ნაბიჯები MK პროგრამირებისკენ, გჭირდებათ მხოლოდ ორი პროგრამა:
  • Proteus არის ემულატორის პროგრამა (შეგიძლიათ განავითაროთ მასში ჩართვა რეალური შედუღების გარეშე და შემდეგ შეამოწმოთ ჩვენი პროგრამა ამ წრეზე). ჩვენ ჯერ Proteus-ში დავიწყებთ ყველა პროექტს, შემდეგ კი უკვე შეგვიძლია რეალური მოწყობილობის შედუღება.
  • CodeVisionAVR არის C პროგრამირების ენის შემდგენელი AVR-სთვის. მასში ჩვენ შევიმუშავებთ პროგრამებს მიკროკონტროლერისთვის და შესაძლებელი იქნება მისგან პირდაპირ რეალური MK-ის გამორთვა.
Proteus-ის დაყენების შემდეგ გაუშვით
ის გვთავაზობს ვნახოთ ის პროექტები, რომლებიც მასთან მიდის, ჩვენ თავაზიანად უარს ვამბობთ. ახლა შევქმნათ მასში უმარტივესი წრე. ამისათვის დააწკაპუნეთ ხატულაზე ვიზუალურად არაფერი ხდება. ახლა თქვენ უნდა დააჭიროთ პატარა ასოს R (აირჩიეთ ბიბლიოთეკიდან)კომპონენტების სიის პანელში გაიხსნება კომპონენტების შერჩევის ფანჯარა
ნიღბის ველში შეიყვანეთ კომპონენტის სახელი, რომელიც გვინდა ვიპოვოთ ბიბლიოთეკაში. მაგალითად, ჩვენ უნდა დავამატოთ მეგა8 მიკროკონტროლერი
შედეგების სიაში დააწექით მეგა8 და დააჭირეთ ღილაკს კარგი. კომპონენტების სიაში გვაქვს მეგა8 მიკროკონტროლერი
ამრიგად, ჩვენ ვამატებთ სხვა რეზისტორს კომპონენტების სიაში სიტყვის შეყვანით ნიღბის ველში რეზდა LED ხელმძღვანელობდა

დიაგრამაზე ნაწილების დასაყენებლად დააწკაპუნეთ ნაწილზე, შემდეგ დააწკაპუნეთ დიაგრამის ველზე, აირჩიეთ კომპონენტის მდებარეობა და კვლავ დააწკაპუნეთ. მარცხნივ სქემზე დამიწის ან საერთო მინუსის დასამატებლად დააწკაპუნეთ "ტერმინალზე" და აირჩიეთ Ground. ამრიგად, ყველა კომპონენტის დამატება და მათი დაკავშირება, ჩვენ ვიღებთ ასეთ მარტივ წრეს
ყველაფერი, ახლა ჩვენი პირველი სქემა მზად არის! მაგრამ თქვენ შეიძლება გკითხოთ, რა შეუძლია მას? მაგრამ არაფერი. არაფერი, რადგან იმისთვის, რომ მიკროკონტროლერმა იმუშაოს, თქვენ უნდა დაწეროთ პროგრამა. პროგრამა არის ინსტრუქციების სია, რომელსაც მიკროკონტროლერი შეასრულებს. ჩვენ გვჭირდება მიკროკონტროლერი ფეხზე დასაყენებლად PC0ლოგიკა 0 (0 ვოლტი) და ლოგიკა 1 (5 ვოლტი).

პროგრამის დაწერა მიკროკონტროლერისთვის

ჩვენ დავწერთ პროგრამას C ენაზე CodeVisionAVR შემდგენელის გამოყენებით. CV-ის გაშვების შემდეგ ის გვეკითხება, რისი შექმნა გვინდა: წყარო თუ პროექტი ვირჩევთ ამ უკანასკნელს და ვაჭერთ OK ღილაკს. შემდეგი, ჩვენ მოგეთხოვებათ გაუშვათ CVAVR CodeWizard (ეს არის ფასდაუდებელი ინსტრუმენტი დამწყებთათვის, რადგან მას შეუძლია პროგრამის მთავარი ჩონჩხის გენერირება) აირჩიე დიახ
ოსტატი იწყება Chip ჩანართი აქტიური, აქ ჩვენ შეგვიძლია შევარჩიოთ ჩვენი MK მოდელი - ეს არის mega8 და სიხშირე, რომლითაც MK იმუშავებს (mega8 დაყენებულია 1 მეგაჰერცზე ნაგულისხმევად), ასე რომ, ჩვენ დავაყენეთ ყველაფერი, როგორც ნაჩვენებია ეკრანის სურათი ზემოთ. გადადით პორტების ჩანართზე
atmega8 მიკროკონტროლერს აქვს 3 პორტი: პორტი C, პორტი D, პორტი B. თითოეულ პორტს აქვს 8 პინი. პორტის პინები შეიძლება იყოს ორ მდგომარეობაში:
  • გასვლა
DDRx.y რეგისტრის დახმარებით ჩვენ შეგვიძლია დავაყენოთ პინი, როგორც შემავალი ან გამომავალი. თუ შიგნით
  • DDRx.y = 0 - გამომავალი მუშაობს ასე INPUT
  • DDRx.y = 1 პინი მუშაობს EXIT
როდესაც პინი კონფიგურირებულია როგორც გამომავალი, ჩვენ შეგვიძლია დავაყენოთ ის ლოგიკა 1 (+5 ვოლტი) და ლოგიკა 0 (0 ვოლტი). ეს კეთდება PORTx.y რეესტრში ჩაწერით. შემდეგ დეტალურად იქნება განხილული შემავალი-გამომავალი პორტების შესახებ. ახლა ჩვენ დავაყენეთ ყველაფერი ისე, როგორც ნაჩვენებია ეკრანის სურათზე და დააჭირეთ ფაილს-> გენერირებას, შენახვას და გამოსვლას. შემდეგი, CodeWizard შემოგთავაზებთ პროექტის შენახვას, ჩვენ შევინახავთ მას და ვუყურებთ კოდს:

#შეიცავს //ბიბლიოთეკა დროის დაყოვნების შესაქმნელად void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // PC0 ფეხის გამომავალი PORTD=0x00; DDRD=0x00; // ტაიმერი/მრიცხველი 0 ინიციალიზაცია TCCR0=0x00; TCNT0=0x00; // ტაიმერი/მრიცხველი 1 ინიციალიზაცია TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x1H0x00; ; OCR1BL=0x00; // ტაიმერი/მრიცხველი 2 ინიციალიზაცია ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // გარე წყვეტ(ებ)ის ინიციალიზაცია MCUCR=0x00; // ტაიმერი(ები)/მრიცხველი(ები) ) შეფერხ(ებ)ის ინიციალიზაცია TIMSK=0x00; // ანალოგური შედარების ინიციალიზაცია ACSR=0x80; SFIOR=0x00; ხოლო (1) ( ); )


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

#შეიცავს //ბიბლიოთეკა მიკროკონტროლერთან მუშაობისთვის mega8 #include // ბიბლიოთეკა დროის შეფერხებების შესაქმნელად void main(void) ( DDRC=0x01; /* გააკეთეთ PC0 ფეხი, რომ გამომავალი ჩანაწერი 0x01 შეიძლება თქვენთვის უცნობი მოგეჩვენოთ, და ეს არის მხოლოდ რიცხვი 1 თექვსმეტობით, ეს ხაზი იქნება 0b00000001-ის ექვივალენტი. ბინარში, მაშინ მე დავწერ ზუსტად ასე. */ ხოლო (1) ( ); )


Ყველაფერი კარგადაა. მაგრამ იმისათვის, რომ LED-მა აციმციმდეს, ჩვენ უნდა შევცვალოთ ლოგიკური დონე PC0 ფეხიზე. ამისათვის დაამატეთ რამდენიმე ხაზი მთავარ მარყუჟს:

#შეიცავს //ბიბლიოთეკა მიკროკონტროლერთან მუშაობისთვის mega8 #include // ბიბლიოთეკა დროის შეფერხებების შესაქმნელად void main(void) ( DDRC=0x01; /* გააკეთეთ PC0 ფეხი გამომავალი ჩანაწერი 0x01 შეიძლება თქვენთვის უცნობი მოგეჩვენოთ, და ეს არის მხოლოდ ნომერი 1 თექვსმეტობით, ეს ხაზი იქნება 0b00000001-ის ექვივალენტი. ბინარში, მაშინ მე დავწერ ზუსტად ასე.*/ ხოლო (1)//პროგრამის მთავარი ციკლი (// პროგრამის მთავარი მარყუჟის ოპერატორის ფრჩხილი ხსნის PORTC.0=1; //C 1-ის პორტს დააყენებს პინზე 0 delay_ms(500); //დაყოვნება 500 მილიწამში PORTC.0=0; // დააყენეთ პორტი C 0 პინზე 0 delay_ms(500); // გააკეთეთ დაყოვნება 500 მილიწამში );// დახურეთ ოპერატორის ფრჩხილი ძირითადი პროგრამის მარყუჟიდან)


ყველაფერი, ახლა კოდი მზად არის. ჩვენ დააწკაპუნეთ Build all Project files-ის ხატულაზე, რათა შევადგინოთ (გადათარგმნოთ MK პროცესორის ინსტრუქციებში) ჩვენი პროგრამა. Exe საქაღალდეში, რომელიც მდებარეობს ჩვენს პროექტში, უნდა გამოჩნდეს ფაილი hex გაფართოებით, ეს არის ჩვენი firmware ფაილი MK-სთვის. იმისათვის, რომ ჩვენი firmware მივაწოდოთ ვირტუალურ მიკროკონტროლერს Proteus-ში, თქვენ უნდა დააწკაპუნოთ ორჯერ Proteus-ის მიკროკონტროლერის სურათზე. გამოჩნდება მსგავსი ფანჯარა
დააწკაპუნეთ საქაღალდის ხატულაზე Program File ველში, აირჩიეთ hex - ჩვენი firmware-ის ფაილი და დააჭირეთ ღილაკს OK. ახლა ჩვენ შეგვიძლია გავატაროთ ჩვენი წრედის სიმულაცია. ამისათვის დააჭირეთ ღილაკს "თამაში" Proteus ფანჯრის ქვედა მარცხენა კუთხეში.

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

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

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

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

პირველი C პროგრამა AVR-სთვის

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

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

Ასევე მაქვს CodeVision AVR Cარის ძალიან პოპულარული შემდგენელი. იგი პოპულარული გახდა თავისი სიმარტივის გამო. თქვენ შეგიძლიათ მიიღოთ მასში სამუშაო პროგრამა რამდენიმე წუთში - ამაში დიდად უწყობს ხელს დაწყების კოდის ოსტატი, რომელიც ასახავს სტანდარტებს ნებისმიერი არტის ინიციალიზაციისთვის. მართალი გითხრათ, მას რატომღაც ეჭვის თვალით ვეპყრობი - ერთხელ ამ კომპილერის მიერ დაწერილი პროგრამის დაშლა მომიწია, რაღაც ფაფა და არა კოდი გამოვიდა. არასაჭირო ჟესტებისა და ოპერაციების საშინელი რაოდენობა, რამაც გამოიწვია საკმაოდ დიდი რაოდენობით კოდი და ნელი შესრულება. თუმცა, შესაძლოა, იყო შეცდომა ორიგინალური firmware დამწერის დნმ-ში. გარდა ამისა, მას ფული უნდა. არა იმდენად, რამდენადაც IAR, მაგრამ შესამჩნევი. და დემო რეჟიმში ის საშუალებას გაძლევთ დაწეროთ არაუმეტეს 2 კბ კოდი.
რა თქმა უნდა, არის ბზარი, მაგრამ თუ მოიპარე, მაშინ მილიონი, IAR-ის გაგებით :)

Არსებობს ასევე Image Craft AVR Cდა MicroCმიკროელექტრონიკისგან. არცერთის გამოყენება არ დამჭირვებია, მაგრამ... SWGძალიან დიდება მიკროპასკალიამბობენ, საშინლად მოსახერხებელი პროგრამირების გარემო და ბიბლიოთეკები. ვფიქრობ, MicroC არ იქნება უარესი, მაგრამ ასევე ფასიანი.

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

ასე რომ, ჩამოტვირთეთ WinAVR და AVR Studio. შემდეგი, სტუდია ჯერ დაინსტალირებულია, შემდეგ, ზემოდან, WinAVR ტრიალებს და სტუდიას ეკვრის დანამატის სახით. კატეგორიულად გირჩევთ WinAVR დააყენოთ მოკლე გზაზე, რაღაც C:\WinAVR-ზე, ამგვარად თავიდან აიცილებთ უამრავ პრობლემას ბილიკებთან დაკავშირებით.

პროექტის შექმნა
ასე რომ, სტუდია აწყობილია, C ხრახნიანია, დროა სცადოთ რაღაცის დაპროგრამება. დავიწყოთ მარტივი, უმარტივესი. გაუშვით სტუდია, აირჩიეთ ახალი პროექტი, როგორც AVR GCC შემდგენელი და შეიყვანეთ პროექტის სახელი.

სამუშაო სივრცე იხსნება ცარიელი *.c ფაილით.

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

პროექტის დაყენება
ზოგადად, კლასიკურად ითვლება make ფაილის შექმნა, რომელშიც ყველა დამოკიდებულება იქნება აღწერილი. და ეს ალბათ სწორია. მაგრამ ჩემთვის, რომელიც გავიზარდე სრულად ინტეგრირებული IDE-ებით, როგორიცაა uVisionან AVR Studioეს მიდგომა ღრმად უცხოა. ამიტომ, ამას ჩემი გზით, სტუდიის ყველა საშუალებით გავაკეთებ.

დააჭირეთ გადაცემათა კოლოფის ღილაკს.


ეს არის თქვენი პროექტის პარამეტრები, უფრო სწორად, make ფაილის ავტომატური წარმოქმნის პარამეტრები. პირველ გვერდზე, თქვენ უბრალოდ უნდა შეიყვანოთ სიხშირე, რომლითაც თქვენი MK იმუშავებს. ეს დამოკიდებულია დაუკრავენ ბიტებზე, ამიტომ ვივარაუდოთ, რომ სიხშირე არის 8000000 ჰც.
ასევე ყურადღება მიაქციეთ ოპტიმიზაციის ხაზს. ახლა არის -Os არის ზომის ოპტიმიზაცია. დატოვეთ როგორც არის ახლა, შემდეგ შეგიძლიათ სცადოთ ამ პარამეტრით თამაში. -O0 საერთოდ არ არის ოპტიმიზაცია.

შემდეგი ნაბიჯი არის ბილიკების დაყენება. უპირველეს ყოვლისა, დაამატეთ თქვენი პროექტის დირექტორია იქ - თქვენ განათავსებთ მესამე მხარის ბიბლიოთეკებს. ბილიკი ".\" გამოჩნდება სიაში

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


ჯერჯერობით სულ ესაა. ყველგან დააწკაპუნეთ OK და გადადით წყაროზე.

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

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

სქემის აწყობა
ჩვენ უნდა დავუკავშიროთ USB-USART გადამყვანის მოდული მიკროკონტროლერის USART პინებს. ამისათვის ვიღებთ ორი მავთულის ჯემპერს და ჯვარედინად ვათავსებთ ქინძისთავებს. ანუ კონტროლერის Rx-ს ვაკავშირებთ გადამყვანის Tx-ს, ხოლო გადამყვანის Tx-ს კონტროლერის Rx-თან.

გამოდის, საბოლოო ჯამში, ეს არის სქემა:


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

ჩვენ ვწერთ კოდს

მე მაშინვე გავაკეთებ დათქმას, რომ კონკრეტულად არ ჩავუღრმავდები თავად C ენის აღწერას. ამისათვის უბრალოდ არის უზარმაზარი მასალის უზარმაზარი რაოდენობა, დაწყებული კლასიკური "C პროგრამირების ენიდან" დაწყებული K&R სხვადასხვა სახელმძღვანელოებით დამთავრებული.

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

მართალია, აქ ჯერ ყველა თავი არ არის გადატანილი, მაგრამ ვფიქრობ, დიდი ხანი არ არის.

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

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

1 #შეიცავს

#შეიცავს

ეს ფაილი მდებარეობს საქაღალდეში WinAVRდა ის შეიცავს კონტროლერის ყველა რეგისტრისა და პორტის აღწერას. და იქ ყველაფერი სახიფათოა, კონკრეტულ კონტროლერზე მითითებით, რომელსაც კომპილატორი გადასცემს გააკეთოსფაილი პარამეტრში MCUდა ამ ცვლადის საფუძველზე, თქვენს პროექტს უკავშირდება სათაურის ფაილი ყველა პორტისა და რეგისტრის მისამართების აღწერით ამ კონკრეტული კონტროლერისთვის. Როგორ! ამის გარეშე, თქვენც შეგიძლიათ, მაგრამ მაშინ ვერ შეძლებთ გამოიყენოთ სიმბოლური რეგისტრის სახელები, როგორიცაა SREG ან UDR, და მოგიწევთ დაიმახსოვროთ თითოეულის მისამართი, როგორიცაა "0xC1", და ეს გატეხავს თქვენს თავს.

იგივე გუნდი #შეიცავს<имя файла> საშუალებას გაძლევთ დაამატოთ ნებისმიერი ტექსტური ფაილის შინაარსი თქვენს პროექტში, მაგალითად, ფაილი ფუნქციების აღწერით ან სხვა კოდის ნაწილი. და ისე, რომ დირექტივამ შეძლო ამ ფაილის პოვნა, ჩვენ მივუთითეთ ჩვენი პროექტის ბილიკები (WinAVR დირექტორია უკვე რეგისტრირებულია იქ ნაგულისხმევად).

მთავარი ფუნქცია.
C პროგრამა არის ყველაფერი ფუნქციებზე. მათი ბუდირება და ერთმანეთისგან გამოძახება შესაძლებელია ნებისმიერი თანმიმდევრობით და სხვადასხვა გზით. თითოეულ ფუნქციას აქვს სამი საჭირო პარამეტრი:

  • დაბრუნების ღირებულება, მაგალითად, sin(x)აბრუნებს x-ის სინუსის მნიშვნელობას. როგორც მათემატიკაში, მოკლედ.
  • გადაცემული პარამეტრები, იგივე x.
  • ფუნქციის სხეული.

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

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

1 2 3 4 5 int main(void) (return 0 ;)

int main(void) ( return 0; )

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

ვნახოთ რა გავაკეთეთ.
ინტარის მონაცემთა ტიპი, რომელსაც აბრუნებს მთავარი ფუნქცია.

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

ეს შეცდომა არ არის, გამოდგება, მაგრამ გაფრთხილებები არ მიყვარს.

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

აი ესენი { } curly brackets არის პროგრამის ბლოკი, ამ შემთხვევაში ფუნქციის სხეული მთავარი, კოდი იქ განთავსდება.

დაბრუნების- ეს არის დაბრუნების მნიშვნელობა, რომელსაც მთავარი ფუნქცია მისცემს დასრულების შემდეგ, რადგან გვაქვს int, ანუ რიცხვი, მაშინ უნდა დავაბრუნოთ ნომერი. მიუხედავად იმისა, რომ ჯერ კიდევ არ აქვს აზრი, რადგან. მიკროკონტროლერზე მთავარი, ჩვენ მხოლოდ არსად შეგვიძლია წასვლა. ნული ვბრუნდები. ნეფიგისთვის. და შემდგენელი ჩვეულებრივ ჭკვიანია და არ ქმნის კოდს ამ შემთხვევისთვის.
თუმცა, თუ გარყვნილი, მაშინ მთავარიშეგიძლიათ გადახვიდეთ MK-ზე - მაგალითად, ჩავარდეთ ჩამტვირთველის განყოფილებაში და შეასრულეთ იგი, მაგრამ აქ უკვე დაგჭირდებათ პროგრამული უზრუნველყოფის დაბალი დონის არჩევა გადასვლის მისამართების გამოსასწორებლად. ქვემოთ ნახავთ და გაიგებთ როგორ გააკეთოთ ეს. Რისთვის? ახლა ეს სხვა კითხვაა, 99,999% შემთხვევაში ეს არ არის საჭირო :)

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

1 2 3 4 5 6 int main(void) (ხელმოუწერელი char i; დაბრუნება 0 ;)

int main(void) ( ხელმოუწერელი char i; დაბრუნება 0; )

ხელმოუწერელინიშნავს ხელმოუწერელს. ფაქტია, რომ ბინარულ წარმოდგენაში ყველაზე მნიშვნელოვანი ბიტი ენიჭება ნიშანს, რაც ნიშნავს, რომ რიცხვი +127/-128 ჯდება ერთ ბაიტში (char), მაგრამ თუ ნიშანი გაუქმებულია, ის ჯდება 0-დან. 255. ჩვეულებრივ ნიშანი არ არის საჭირო. Ასე რომ ხელმოუწერელი.
მეუბრალოდ ცვლადის სახელია. Მეტი აღარ.

ახლა ჩვენ გვჭირდება პორტების ინიციალიზაცია და UART. რა თქმა უნდა, შეგიძლიათ აიღოთ და დააკავშიროთ ბიბლიოთეკა და დარეკოთ რაიმე სახის UartInit (9600); მაგრამ მაშინ ვერ გაიგებ რა მოხდა სინამდვილეში.

ჩვენ ამას ვაკეთებთ:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void ) ( ხელმოუწერელი char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRRH = HI (bauddivider) ; UCSRA = 0; UCSRB=1<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int main(void) ( unsigned char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO (bauddivider); UBRRH = HI (bauddivider); UCSRA = 0; UCSRB = 1<

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

ისინი ხელს შეუწყობენ თქვენს რუტინულ ოპერაციებს საჭირო კოეფიციენტების გამოსათვლელად. პირველ სტრიქონში ჩვენ ვამბობთ, რომ ნაცვლად XTALშეგიძლიათ უსაფრთხოდ ჩაანაცვლოთ 8000000 და - ტიპის მითითება, ამბობენ, რომ გრძელი არის პროცესორის საათის სიხშირე. იგივე ბაუდრატი- UART-ის საშუალებით მონაცემთა გადაცემის სიხშირე.

ბაუდდივიდერიუკვე უფრო რთული, მის ნაცვლად ჩანაცვლდება წინა ორი ფორმულით გამოთვლილი გამოხატულება.
კარგად და LOდა გამარჯობაამ შედეგიდან მიიღება დაბალი და მაღალი ბაიტი, რადგან აშკარად ვერ ჯდება ერთ ბაიტში. AT გამარჯობა x გადატანილია (მაკროს შეყვანის პარამეტრი) რვაჯერ მარჯვნივ, რის შედეგადაც მისგან მხოლოდ მაღალი ბაიტი დარჩება. Და ში LOჩვენ ვაკეთებთ AND-ს 00FF რიცხვით, შედეგად ვტოვებთ მხოლოდ დაბალ ბაიტს.

ასე რომ, ყველაფერი, რაც გაკეთდა, მსგავსია #განსაზღვრაშეგიძლიათ უსაფრთხოდ გადააგდოთ იგი და გამოთვალოთ საჭირო რიცხვები კალკულატორზე და დაუყოვნებლივ შეიყვანოთ ისინი ხაზებში UBBRL = .... და UBBRH=…..

შეუძლია. მაგრამ! გააკეთე ეს კატეგორიულად შეუძლებელია!

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

მაშინ ყველაფერი მარტივია:
ყველა ეს "UBRLL და Co" არის UART გადამცემის კონფიგურაციის რეგისტრები, რომლითაც ჩვენ ვუკავშირდებით სამყაროს. ახლა კი მათ მივუნიშნეთ საჭირო მნიშვნელობები, დავაყენეთ ისინი სასურველ სიჩქარეზე და სასურველ რეჟიმზე.

ჩანაწერის ნახვა 1<ნიშნავს შემდეგს: აიღეთ 1 და დადეთ თავის ადგილზე RXENბაიტში. RXENეს არის რეესტრის მე-4 ბიტი UCSRB, ისე 1<ქმნის ორობით რიცხვს 00010000, TXENარის მე-3 ბიტი და 1<მისცემს 00001000. ერთი "|" ეს არის ბიტალურად ან, ასე რომ 00010000 | 00001000 = 00011000. ანალოგიურად, დარჩენილი საჭირო კონფიგურაციის ბიტები დაყენებულია და ემატება საერთო გროვას. შედეგად, შეგროვებული ნომერი იწერება UCSRB-ში. ეს უფრო დეტალურად არის აღწერილი MK-ის მონაცემთა ფურცელში USART განყოფილებაში. ასე რომ, ტექნიკური დეტალები არ შეგაწუხოთ.

დასრულდა, დროა ვნახოთ რა მოხდება. დააწკაპუნეთ კომპილაციაზე და დაიწყეთ ემულაცია (Ctrl+F7).

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

ფაქტია, რომ თავდაპირველად, ფაქტობრივად, ის იყო UBRRL = LO (bauddivider) ხაზზე; ყოველივე ამის შემდეგ, ის, რაც ჩვენ განვსაზღვრავთ, არ არის კოდი, არამედ უბრალოდ წინასწარი გამოთვლები, ამიტომ სიმულატორი ცოტა მოსაწყენია. მაგრამ ახლა მიხვდა, რომ პირველი ინსტრუქცია შესრულდა და თუ ხეზე აძვრები I/O ხედი, გადადით USART განყოფილებაში და გადახედეთ იქ UBBRL ბაიტს, ნახავთ, რომ იქ უკვე არის მნიშვნელობა! 0x33.

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

გახსნა
ახლა აღადგინეთ სიმულაცია ნულამდე. დააწკაპუნეთ იქ გადატვირთვა (Shift+F5). გახსენით დაშლილი სია, ახლა ნახავთ რა ხდება რეალურად კონტროლერში. ხედი -> დემონტაჟი. და არა YYAAAAA!!! ასამბლეერი!!! საშინელება!!! მაგრამ თქვენ უნდა. ისე, რომ მოგვიანებით, როცა რამე არასწორედ მიდის, კოდში არ გაგიჟდეთ და ფორუმებზე ლამის კითხვები არ დაისვათ, არამედ მაშინვე შეხვიდეთ ღრძილებში და ნახეთ სად გაქვთ შტეფსელი. იქ არაფერია საშინელი.

პირველ რიგში იქნება ტოპები სერიიდან:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump +00000004: 940C0034 JMP 0x00000034 Jump +00000006: 940C0034 JMP 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C0034 JMP 0x00000034 Jump + 0000000E: 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +00000014: 940C0034 JMP 0x00000034 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C0034 JMP 0x00000034 Jump +0000001C : 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +00000022: 940C0034 JMP 0x00000034 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

00000000: 940C002A JMP 0x0000002A Jump +00000002: 940C0034 JMP 0x00000034 Jump +00000004: 940C0034 JMP 0x00000034 Jump +00000006: 940C0034 JMP 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x00000034 Jump +0000000C: 940C0034 JMP 0x00000034 Jump +0000000E : 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x00000034 Jump +00000014: 940C0034 JMP 0x00000034 Jump +00000016: 940C0034 JMP 0x00000034 Jump +00000018: 940C0034 JMP 0x00000034 Jump +0000001A: 940C0034 JMP 0x00000034 Jump +0000001C: 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x00000034 Jump +00000022: 940C0034 JMP 0x00000034 Jump +00000024: 940C0034 JMP 0x00000034 Jump +00000026: 940C0034 JMP 0x00000034 Jump +00000028: 940C0034 JMP 0x00000034 Jump

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

0000002B: BE1F OUT 0x3F, R1 გასვლა I/O მდებარეობაზე

ჩაწერეთ ეს ნული მისამართზე 0x3F. თუ გადახედავთ I/O ხედის სვეტს, ნახავთ, რომ მისამართი 0x3F არის SREG რეგისტრის მისამართი - კონტროლერის დროშის რეგისტრი. იმათ. ჩვენ გადავაყენეთ SREG პროგრამის გასაშვებად ნულოვან პირობებში.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F ჩატვირთვა დაუყოვნებლივ +0000002D: E0D4 LDI R29,0x04 ჩატვირთვა დაუყოვნებლივ +0000002E: BFDE OUT 0x3E,R29 გასვლა I/O მდებარეობაზე +000000002F

0000002C: E5CF LDI R28,0x5F ჩატვირთვა დაუყოვნებლივ +0000002D: E0D4 LDI R29,0x04 ჩატვირთვა დაუყოვნებლივ +0000002E: BFDE OUT 0x3E,R29 გასვლა I/O მდებარეობაზე +000000002F

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

00000032: 940C0041 JMP 0x00000041 გადასვლა

გადახტომა პროგრამის დასასრულისკენ, და იქ ჩვენ გვაქვს შეფერხებები გამორთული და მჭიდროდ მიბმული თავის თავზე:

1 2 +00000041: 94F8 CLI გლობალური შეფერხების გამორთვა +00000042: CFFF RJMP PC-0x0000 შედარებითი ნახტომი

00000041: 94F8 CLI გლობალური შეფერხების გამორთვა +00000042: CFFF RJMP PC-0x0000 შედარებითი ნახტომი

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

1 +00000034: 940C0000 JMP 0x00000000 ნახტომი

00000034: 940C0000 JMP 0x00000000 ნახტომი

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

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

1 2 3 4 5 6 7 8 9 10 11 12 <

00000036: E383 LDI R24,0x33 ჩატვირთვა დაუყოვნებლივ +00000037: B989 OUT 0x09,R24 გასვლა I/O მდებარეობა 15: UBRRH = HI(bauddivider); +00000038: BC10 OUT 0x20,R1 გასვლა I/O მდებარეობა 16: UCSRA = 0; +00000039: B81B OUT 0x0B, R1 გასვლა I/O მდებარეობა 17: UCSRB = 1<

და აქ არის ჯამი:

1 2 3 +0000003E: E080 LDI R24,0x00 ჩატვირთვა დაუყოვნებლივ +0000003F: E090 LDI R25,0x00 ჩატვირთვა დაუყოვნებლივ +00000040: 9508 RET ქვეპროგრამის დაბრუნება

0000003E: E080 LDI R24,0x00 ჩატვირთვა დაუყოვნებლივ +0000003F: E090 LDI R25,0x00 ჩატვირთვა დაუყოვნებლივ +00000040: 9508 RET ქვეპროგრამის დაბრუნება

საკითხავია, რატომ ამატებს შემდგენელი ასეთ ტოპებს? და ეს სხვა არაფერია თუ არა Return 0, შემდეგ ჩვენ განვსაზღვრეთ ფუნქცია, როგორც int main (void), ასე რომ, კიდევ ოთხი ბაიტი გავაფუჭეთ, არ მესმის რა :) და თუ თქვენ გააკეთებთ void main (void) მაშინ მხოლოდ RET დარჩება. მაგრამ გამოჩნდება გაფრთხილება, რომ ამბობენ, რომ ჩვენი მთავარი ფუნქცია არაფერს აბრუნებს. ზოგადად აკეთე რაც გინდა :)

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

გაგრძელდება რამდენიმე დღეში...

ზემოდან:
ალექსეი78მე შევქმენი დანამატი firefox-ისთვის, რომელიც აადვილებს ჩემს საიტზე და ფორუმზე ნავიგაციას.
განხილვა და ჩამოტვირთვა,

არსებობს სხვადასხვა პროგრამირების ენები AVR მიკროკონტროლერებისთვის, მაგრამ ასამბლერი და C, ალბათ, ყველაზე შესაფერისია, რადგან ეს ენები უზრუნველყოფს ყველა საჭირო შესაძლებლობის საუკეთესო განხორციელებას მიკროკონტროლერის აპარატურის კონტროლისთვის.

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

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

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

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

ერთი სიტყვით, C არის ყველაზე მოსახერხებელი ენა როგორც დამწყებთათვის, რათა გაეცნონ AVR მიკროკონტროლერებს და სერიოზულ დეველოპერებს.

შემდგენელები გამოიყენება პროგრამის წყაროს კოდის მიკროკონტროლერის firmware ფაილად გადასაყვანად.

Atmel უზრუნველყოფს მძლავრ ასამბლერის შემდგენელს, რომელიც შედის Windows-ზე დაფუძნებულ Atmel Studio განვითარების გარემოში. შემდგენელთან ერთად, განვითარების გარემო შეიცავს გამართვას და ემულატორს.
Atmel Studio სრულიად უფასოა და ხელმისაწვდომია Atmel ვებსაიტიდან.

ამჟამად AVR-ისთვის საკმაოდ ბევრი C შემდგენელია. მათგან ყველაზე ძლიერია IAR Systems-ის შემდგენელი სტოკჰოლმიდან. სწორედ მისი თანამშრომლები მონაწილეობდნენ 90-იანი წლების შუა ხანებში AVR ბრძანების სისტემის შემუშავებაში. IAR C შემდგენელს აქვს კოდის ოპტიმიზაციის ფართო შესაძლებლობები და შედის IAR Embedded Workbench (EWB) ინტეგრირებული განვითარების გარემოში, რომელიც ასევე მოიცავს ასამბლერის შემდგენელს, ლინკერს, პროექტისა და ბიბლიოთეკის მენეჯერს და გამართვას. პაკეტის სრული ვერსიის ფასია 2820 ევრო. კომპანიის ვებსაიტზე შეგიძლიათ ჩამოტვირთოთ უფასო შეფასების ვერსია 30 დღის განმავლობაში ან შეუზღუდავი ვერსია კოდის ზომის ლიმიტით 4 KB.

ამერიკული კომპანია Image Craft პალო ალტოდან, კალიფორნია, აწარმოებს C ენის შემდგენელს, რომელმაც საკმაოდ ფართო პოპულარობა მოიპოვა. JumpStart C-ს AVR-ისთვის აქვს მისაღები კოდის ოპტიმიზაცია და არც ისე ძვირი ღირს (50$-დან $499-მდე ვერსიის მიხედვით). JumpStart C-ის დემო ვერსია AVR-ისთვის სრულად ფუნქციონირებს 45 დღის განმავლობაში.

არანაკლებ პოპულარობა მოიპოვა რუმინულმა Code Vision AVR C Compiler-მა, ამ კომპილერის სრული ვერსიის ფასი შედარებით დაბალია და შეადგენს 150 ევროს. კომპილერს გააჩნია განვითარების ინტეგრირებული გარემო, რომელიც სტანდარტული ფუნქციების გარდა, მოიცავს საკმაოდ საინტერესო ფუნქციას - CodeWizardAVR Automatic Program Generator. სერიული ტერმინალის არსებობა განვითარების გარემოში იძლევა პროგრამების გამართვის საშუალებას მიკროკონტროლერის სერიული პორტის გამოყენებით. დეველოპერებს შეუძლიათ ჩამოტვირთოთ შეფასების უფასო ვერსია, კოდის ზომის ლიმიტით 4 KB და გამორთულია გენერირებული C წყაროს კოდის შენახვა.

MikroElektronika, რომელიც მდებარეობს სერბეთის ქალაქ ბელგრადში, აწარმოებს კომპილატორების მთელ ოჯახს AVR მიკროკონტროლერებისთვის. C კომპილერი სახელად mikroC PRO AVR-ისთვის 249$ ღირს. ასევე არის mikroBasic და mikroPascal იმავე ფასად. დეველოპერის საიტზე არის დემო ვერსიები კოდის ზომის ლიმიტით 4096 ბაიტი. შემდგენლების ამ ოჯახის უპირატესობა არის ერთიანი პლატფორმა და ერთი იდეოლოგია, რომელსაც შეუძლია უზრუნველყოს მარტივი გადასვლა არა მხოლოდ ენებს შორის, არამედ მიკროკონტროლერებს შორის (არსებობს კომპილერის ვერსიები PIC, STM32, 8051 ...).

ინტეგრირებული განვითარების გარემო გახდა ნამდვილად საკულტო. მასში შედის ძლიერი C და ასამბლერის შემდგენელები, AVRDUDE პროგრამისტი, გამართვა, სიმულატორი და მრავალი სხვა დამხმარე პროგრამა და კომუნალური პროგრამა. WinAVR შესანიშნავად აერთიანებს Atmel-ის AVR Studio-ს განვითარების გარემოს. ასამბლერი შეყვანის კოდით იდენტურია AVR Studio ასამბლერის. C და ასამბლერის შემდგენელებს აქვთ შესაძლებლობა შექმნან გამართვის ფაილები COFF ფორმატში, რაც საშუალებას გაძლევთ გამოიყენოთ არა მხოლოდ ჩაშენებული ხელსაწყოები, არამედ გამოიყენოთ ძლიერი AVR Studio სიმულატორი. კიდევ ერთი მნიშვნელოვანი პლიუსი არის ის, რომ WinAVR ნაწილდება უფასოდ, შეზღუდვების გარეშე (მწარმოებლები მხარს უჭერენ GNU General Public License).

როგორც შეჯამება, WinAVR იდეალური არჩევანია მათთვის, ვინც იწყებს AVR მიკროკონტროლერების დაუფლებას. სწორედ განვითარების ეს გარემო განიხილება, როგორც მთავარი ამ კურსში.

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

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

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

ბიტიური ოპერაციები

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

PORTD = 0b00001000;

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

პორტი |= (1<<3);

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

თუ (პინდი == 0b00000000)

(ნებისმიერი კოდი)

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

თუ (~ PIND & (1<<3))

(ნებისმიერი კოდი)

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

ერთი ბიტის დაყენება

ერთი ბიტის დასაყენებლად, როგორიცაა D პორტი, გამოიყენება OR ოპერაცია. ეს არის ის, რაც ჩვენ გამოვიყენეთ სტატიის დასაწყისში.

PORTD = 0b00011100; // საწყისი ღირებულება

PORTD = PORTD | (ერთი<<0); применяем побитовую ИЛИ

პორტი |= (1<<0); // сокращенная форма записи

PORTD == 0b00011101; // შედეგი

ეს ბრძანება აყენებს ბიტს ნულზე და დანარჩენს უცვლელად ტოვებს.

მაგალითად, დავაყენოთ D პორტის მე-6 ბიტი.

PORTD = 0b00011100; // საწყისი პორტის მდგომარეობა

პორტი |= (1<<6); //

PORTD == 0b01011100; // შედეგი

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

PORTB = 0b00011100; // საწყისი ღირებულება

PORTB |= (1<<0) | (1<<6) | (1<<7); //

PORTB == 0b1011101; // შედეგი

ცალკეული ბიტების გადატვირთვა (ნულოვანი).

ერთი ბიტის გადატვირთვისთვის გამოიყენება სამი ადრე განხილული ბრძანება ერთდროულად: .

მოდით გადავაყენოთ PORTC რეგისტრის მე-3 ბიტი და დავტოვოთ უცვლელი.

PORTC = 0b00011100;

PORTC &= ~(1<<3);

PORTC == 0b00010100;

შევასრულოთ მსგავსი მოქმედებები მე-2 და მე-4 ციფრისთვის:

PORTC = 0b00111110;

PORTC &= ~((1<<2) | (1<<4));

PORTC == 0b00101010;

დარტყმის შეცვლა

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

PORTA = 0b00011111;

PORTA ^= (1<<2);

PORTA == 0b00011011;

შეცვალეთ ნულოვანი, მეორე და მეექვსე ბიტების მდგომარეობა:

PORTA = 0b00011111;

PORTA ^= (1<<0) | (1<<2) | (1<<6);

PORTA == 0b01011010;

ინდივიდუალური ბიტის სტატუსის შემოწმება. შეგახსენებთ, რომ I/O პორტის შემოწმება (ჩაწერისგან განსხვავებით) ხორციელდება PIN რეესტრიდან მონაცემების წაკითხვით.

ყველაზე გავრცელებული ტესტი შესრულებულია ორი მარყუჟის დებულებიდან ერთ-ერთით: if და while. ჩვენ უკვე ვიცნობთ ამ ოპერატორებს ადრე.

გამონადენის შემოწმება ლოგიკური ნულის არსებობისთვის (გადატვირთვის). თუ

თუ (0==(PIND & (1<<3)))

თუ D პორტის მესამე ბიტი გასუფთავებულია, Code1 შესრულდება. წინააღმდეგ შემთხვევაში, Code2 შესრულდება.

მსგავსი მოქმედებები ხორციელდება ჩაწერის ამ ფორმით:

თუ (~ PIND & (1<<3))

გამონადენის შემოწმება ლოგიკური ერთეულის (პარამეტრის) არსებობისთვის თუ

თუ (0 != (PIND & (1<<3)))

თუ (PIND & (1<<3))

ზემოაღნიშნული ორი მარყუჟი მუშაობს ანალოგიურად, მაგრამ C პროგრამირების ენის მოქნილობის გამო, ისინი შეიძლება განსხვავებულად დაიწეროს. ოპერაცია != ნიშნავს არა ტოლს. თუ PD I/O პორტის მესამე ბიტი დაყენებულია (ერთი), მაშინ Code1 სრულდება, თუ არა, Code2.

ცოტა გადატვირთვის მოლოდინში ხოლო

ხოლო (PIND & (1<<5))

Code1 შესრულდება მანამ, სანამ დაყენებულია PIND რეგისტრის მე-5 ბიტი. მისი გადატვირთვა დაიწყებს Code2-ის შესრულებას.

ველოდები ბიტის დაყენებას ხოლო

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