Агуулгын хүснэгт:

AVR микроконтроллер. Таймер ашиглан LED гэрэлтүүлэгч. Таймер тасалдсан. Таймер CTC горим: 6 алхам
AVR микроконтроллер. Таймер ашиглан LED гэрэлтүүлэгч. Таймер тасалдсан. Таймер CTC горим: 6 алхам

Видео: AVR микроконтроллер. Таймер ашиглан LED гэрэлтүүлэгч. Таймер тасалдсан. Таймер CTC горим: 6 алхам

Видео: AVR микроконтроллер. Таймер ашиглан LED гэрэлтүүлэгч. Таймер тасалдсан. Таймер CTC горим: 6 алхам
Видео: LDmicro 22: платы Arduino с AVRDUDESS (программирование микроконтроллеров с помощью LDmicro) 2024, Долдугаар сарын
Anonim
Image
Image

Бүгдээрээ сайн уу!

Таймер бол электроникийн салбарын чухал ойлголт юм. Цахим эд анги бүр цаг хугацааны үндсэн дээр ажилладаг. Энэ цагийн суурь нь бүх ажлыг синхрончлоход тусалдаг. Бүх микроконтроллерууд урьдчилан тодорхойлсон цагийн давтамжтай ажилладаг бөгөөд бүгд таймер тохируулах боломжтой байдаг. AVR нь маш нарийн, нарийвчлалтай, найдвартай таймертай гэдгээрээ сайрхдаг. Энэ нь олон тооны онцлог шинж чанаруудыг санал болгодог тул үүнийг өргөн хүрээний сэдэв болгодог. Хамгийн сайн тал бол таймер нь CPU -ээс огт хамааралгүй юм. Тиймээс энэ нь CPU -тэй зэрэгцэн ажилладаг бөгөөд CPU -ийн оролцоогүй тул таймерыг маш нарийвчлалтай болгодог. Энэ хэсэгт би AVR таймеруудын үндсэн ойлголтуудыг тайлбарлах болно. Би таймер ашиглан LED анивчдагийг хянахын тулд C кодоор энгийн програм бичиж байна.

Алхам 1: Тодорхойлолт

Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе

ATMega328 дээр гурван төрлийн таймер байдаг:

Таймер/Тоолуур0 (TC0) - ерөнхий зориулалттай 8 битийн таймер/тоолуурын модуль бөгөөд хоёр бие даасан OutputCompare нэгж, ХОУХ -ны дэмжлэгтэй;

Таймер/Тоолуур1 (TC1) - 16 битийн Таймер/Тоолуур нэгж нь програмыг гүйцэтгэх цаг хугацаа (үйл явдлын менежмент), долгион үүсгэх, дохионы цаг хэмжих боломжийг олгодог;

Таймер/Тоолуур2 (TC2) -ерөнхий зориулалттай, суваг, 8 битийн таймер/тоолуур, ХОУХ ба асинхрон ажиллагаатай модуль;

Алхам 2: Асуудлын мэдэгдэл 1: 50 Ms тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе

Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 1: 50 мс тутамд эхлээд LED (ногоон) гэрэлтүүлцгээе

Арга зүй:

- өндөр давтамжийн цахилгаан дохиог бүхэлд нь хуваах замаар бага давтамжтай болгохын тулд Timer0 prescaler ашиглах;

- Timer0 халих бүрт тасалдал ашиглах;

Таймер0 (8 бит) нь 0 -ээс 255 хүртэл тоологддог бөгөөд тэдгээр нь хальж, цагны импульс бүрт энэ утга өөрчлөгддөг.

F_CPU = 16MHz: Цагны цаг = 1000ms / 16000000Hz = 0.0000625ms

Таймерын тоо = (Шаардлагатай саатал / Цагийн хугацаа) -1 = (50ms / 0.0000625ms) = 799999

Цаг нь аль хэдийн 799999 удаа дарагдсан бөгөөд ердөө 50 мс саатал гарсан байна!

Таймерын тоог багасгахын тулд бид давтамж хуваах аргыг prescaling гэж нэрлэдэг. AVR нь бидэнд урьдчилан тооцоолох дараах утгыг санал болгодог: 8, 64, 256 ба 1024. Хүснэгтийг янз бүрийн урьдчилан тооцоолуур ашигласан үр дүнг нэгтгэн харуулав.

Тоолуурын утга нь үргэлж бүхэл тоо байх ёстой. Урьдчилан тооцоолох машин 256 -г сонгоё!

Ихэнх микроконтроллеруудад тасалдал гэж нэрлэгддэг зүйл байдаг. Тодорхой нөхцөл хангагдсан тохиолдолд энэ тасалдлыг халж болно. Одоо тасалдал гарах бүрт AVR үндсэн горимын гүйцэтгэлийг зогсоож, хадгалж, тасалдлын дуудлагад оролцдог (тасалдлын үйлчилгээний горим, ISR гэж нэрлэдэг тусгай горимыг хэрэгжүүлснээр), үүнийг хийсний дараа буцаана. үндсэн ажил бөгөөд үүнийг үргэлжлүүлэн хийдэг.

Шаардлагатай саатал (50ms) нь байж болох хамгийн их саатал: 4, 096ms = 1000ms / 62500Hz * 256 -аас их тул таймер халих нь ойлгомжтой. Цаг хэмжигч халих бүрт тасалдал гардаг.

Тасалдсан хүнийг хэдэн удаа халах ёстой вэ?

50ms / 4.096ms = 3125 /256 = 12.207 Хэрэв таймер 12 удаа давсан бол 12 * 4.096ms = 49.152ms өнгөрөх байсан. 13 дахь давталтад бидэнд 50ms - 49.152ms = 0.848ms -ийн саатал хэрэгтэй байна.

62500Гц давтамжтай (prescaler = 256) үед хачиг тус бүр 0.016ms авдаг. Тиймээс 0.848 м -ийн саатал гаргахын тулд 0.848ms / 0.016ms = 53 хачиг шаардлагатай болно. Тиймээс, 13 дахь давталтад бид зөвхөн таймерыг 53 хүртэл тоолж, дараа нь дахин тохируулахыг зөвшөөрдөг.

Timer0/Counter -ийг эхлүүлэх (зургийг үз):

TCCR0B | = (1 << CS02) // цаг хэмжигчийг prescaler ашиглан тохируулах = 256 TCNT0 = 0 // тоолуурыг эхлүүлэх // халих тоолуурын хувьсагчийг эхлүүлэх

Алхам 3: Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED (цэнхэр) гэрэлтүүлцгээе

Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED -ийг (цэнхэр) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED -ийг (цэнхэр) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED -ийг (цэнхэр) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED -ийг (цэнхэр) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED (цэнхэр) гэрэлтүүлцгээе
Асуудлын мэдэгдэл 2: 1 секунд тутамд хоёр дахь LED (цэнхэр) гэрэлтүүлцгээе

Арга зүй:

- Timer1 prescaler ашиглан өндөр давтамжийн цахилгаан дохиог бүхэл тоогоор бага давтамжтайгаар бууруулах;

Харьцуулах (CTC) горимд Clear Timer ашиглах;

- CTC горимтой тасалдал ашиглах;

Таймер1 (16 бит) нь 0 -ээс 65534 хүртэл тоологддог бөгөөд тэдгээр нь хальж дүүрдэг. Энэ утга нь цагны импульс бүрт өөрчлөгддөг.

F_CPU = 16MHz: Цагны цаг = 1000ms / 16000000Hz = 0.0000625msTimeer count = (Шаардлагатай саатал / Цагийн цагийн хугацаа) -1 = (1000ms / 0.0000625ms) = 15999999

Цаг аль хэдийн 15999999 удаа дарж 1 секундын саатал гаргажээ!

Таймерын тоог багасгахын тулд бид давтамж хуваах аргыг prescaling гэж нэрлэдэг. AVR нь бидэнд урьдчилан тооцоолох дараах утгыг санал болгодог: 8, 64, 256 ба 1024. Хүснэгтийг янз бүрийн урьдчилан тооцоолуур ашигласан үр дүнг нэгтгэн харуулав. Тоолуурын утга нь үргэлж бүхэл тоо байх ёстой. Урьдчилан тооцоолох машин 256 -г сонгоё!

Clear timer on Compare (CTC) горимд OCR1A эсвэл ICR1 бүртгэлийг тоолуурын нарийвчлалыг өөрчлөхөд ашигладаг. CTC горимд тоолуурын утга (TCNT1) нь OCR1A эсвэл ICR1 -тэй тохирч байвал тоолуур тэг болж цэвэрлэгддэг. OCR1A эсвэл ICR1 нь тоолуурын хамгийн дээд утгыг тодорхойлдог тул нарийвчлалыг нь тодорхойлдог. Энэ горим нь харьцуулах гаралтын давтамжийг илүү хянах боломжийг олгодог бөгөөд энэ нь гадны үйл явдлыг тоолох ажиллагааг хялбаршуулдаг. Бид AVR -д Timer1/Counter -ийн утгыг 62500 утгад хүрмэгц анхны байдалд нь оруулж, 1 секундын хоцрогдолд хүрэх ёстой гэж хэлэх ёстой.

Timer1/Counter -ийг эхлүүлэх (зургийг үз):

TCCR1B | = (1 << WGM12) | (1 << CS12) // таймерыг prescaler = 256 ба CTC горимоор тохируулах TCNT1 = 0 // тоолуурыг эхлүүлэх TIMSK1 | = (1 << OCIE1A) // тасалдлын OCR1A = 62500 // харьцуулах утгыг эхлүүлэх

Алхам 4: Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд гэрэлтүүлцгээе

Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя
Асуудлын мэдэгдэл 3: Гурав дахь LED (улаан) -ыг 16 м тутамд анивчуулъя

Арга зүй:

- Timer2 prescaler ашиглан өндөр давтамжийн цахилгаан дохиог бүхэл тоогоор бага давтамжтайгаар бууруулах;

Харьцуулах (CTC) горимд Clear Timer ашиглах;

- Тоног төхөөрөмжийн CTC горимыг тасалдалгүйгээр ашиглах;

Таймер2 (8 бит) нь 0 -ээс 255 хүртэл тоологддог бөгөөд тэдгээр нь хальж дүүрдэг. Энэ утга нь цагны импульс бүрт өөрчлөгддөг.

F_CPU = 16MHz: Цагны цаг = 1000ms / 16000000Hz = 0.0000625ms

Таймерын тоо = (Шаардлагатай хоцролт / Цагийн хугацаа) -1 = (16ms / 0.0000625ms) = 255999

Цаг нь аль хэдийн 255999 удаа дарагдсан тул 16 мс хоцорчээ!

Төрөл бүрийн урьдчилан тооцоолуур ашигласан үр дүнг нэгтгэн харуулсан хүснэгтийг үзнэ үү. Тоолуурын утга нь үргэлж бүхэл тоо байх ёстой. Урьдчилан цэнэглэгч 1024 -ийг сонгоё!

CTC горимд тоолуурын утга (TCNT2) нь OCR2A эсвэл ICR2 -тэй тохирч байвал тоолуур тэг болж цэвэрлэгддэг. PB3 зүү нь TIMER2 - OC2A -ийн гаралтын харьцуулах зүү юм (диаграмыг үзнэ үү).

Таймер/Тоолуур2 Хяналтын регистр A - TCCR2A Бит 7: 6 - COM2A1: 0 - А -г харьцуулах гаралтын горимыг харьцуулах. Бид LED -ийг асаах шаардлагатай байгаа тул харьцуулах тохиргоо хийх үед OC2A -ийг асаах. OC2A зүү автоматаар солигддог. Тугны битийг шалгах шаардлагагүй, тасалдалд оролцох шаардлагагүй.

Таймер2/Тоолуурыг эхлүүлэх

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // таймер OC2A зүүг сэлгэх горим болон CTC горимд тохируулна TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // таймерыг prescaler = 1024 TCNT2 = 0 ашиглан тохируулах // тоолуурыг эхлүүлэх OCR2A = 250 // харьцуулах утгыг эхлүүлэх

Алхам 5: C програм дээр код бичих. HEX файлыг микроконтроллерийн флаш санах ойд байршуулах

C хэл дээр програмын код бичих. HEX файлыг микроконтроллерийн флаш санах ойд байршуулах
C хэл дээр програмын код бичих. HEX файлыг микроконтроллерийн флаш санах ойд байршуулах
C хэл дээр програмын код бичих. HEX файлыг микроконтроллерийн флаш санах ойд байршуулах
C хэл дээр програмын код бичих. HEX файлыг микроконтроллерийн флаш санах ойд байршуулах

Хөгжлийн нэгдсэн платформыг ашиглан C Code дээр AVR микроконтроллер програмыг бичиж, бүтээх - Atmel Studio.

F_CPU нь Герц дэх цагийн давтамжийг тодорхойлдог бөгөөд avr-libc номын санг ашигладаг програмуудад түгээмэл байдаг. Энэ тохиолдолд цаг хугацааны хоцролтыг тооцоолохдоо хоцролтын горимд ашигладаг.

#ifndef F_CPU

#тодорхойлох F_CPU 16000000UL // хянагчийн болор давтамжийг хэлэх (16 MHz AVR ATMega328P) #endif

Зүү дээр өгөгдлийн урсгалын хяналтыг идэвхжүүлэхийн тулд #толгойг оруулна уу. Зүү, порт гэх мэтийг тодорхойлдог.

Эхний оруулах файл нь avr-libc-ийн нэг хэсэг бөгөөд таны ажиллаж буй AVR төсөлд ашиглагдах болно. io.h нь таны ашиглаж буй CPU -ийг тодорхойлох болно (тиймээс та үүнийг эмхэтгэхдээ хэсгийг зааж өгдөг) бөгөөд эргээд бидний ашиглаж буй чипт тохирох IO тодорхойлолтын толгойг оруулна. Энэ нь таны бүх зүү, порт, тусгай бүртгэл гэх мэт тогтмол байдлыг тодорхойлдог.

Тасалдлыг идэвхжүүлэхийн тулд #толгойг оруулна уу

дэгдэмхий uint8_t tot_overflow; // халих тоог тоолох дэлхийн хувьсагч

Асуудлыг тодорхойлох аргачлал: 50 мс тутамд LED эхлээд асдаг (Ногоон)

- өндөр давтамжийн цахилгаан дохиог бүхэлд нь хуваах замаар бага давтамжтай болгохын тулд Timer0 prescaler ашиглах;

- Timer0 халих бүрт тасалдал ашиглах;

void timer0_init () // timer0 эхлүүлэх, таслах ба хувьсах

{TCCR0B | = (1 << CS02); // таймерыг prescaler ашиглан тохируулах = 256 TCNT0 = 0; // тоолуурыг эхлүүлэх TIMSK0 | = (1 << TOIE0); // халалтыг идэвхжүүлэх nterrupt sei (); // дэлхийн тасалдлыг идэвхжүүлэх tot_overflow = 0; // халих тоолуурын хувьсагчийг эхлүүлэх}

Асуудлыг тодорхойлох аргачлал: 1 секунд тутамд хоёр дахь LED (цэнхэр) гэрэлтдэг

- Timer1 prescaler ашиглан өндөр давтамжийн цахилгаан дохиог бүхэл тоогоор бага давтамжтайгаар бууруулах;

Харьцуулах (CTC) горимд Clear Timer ашиглах;

- CTC горимтой тасалдал ашиглах;

void timer1_init () // timer1 -ийг эхлүүлэх, таслах ба хувьсах {TCCR1B | = (1 << WGM12) | (1 << CS12); // таймерыг prescaler = 256 ба CTC горимоор тохируулах TCNT1 = 0; // тоолуурыг эхлүүлэх OCR1A = 62500; // харьцуулах утгыг эхлүүлэх TIMSK1 | = (1 << OCIE1A); // харьцуулах тасалдлыг идэвхжүүлэх}

Асуудлын мэдэгдэх аргачлал: 16 м тутамд гурав дахь LED (улаан) анивчдаг

- Timer2 prescaler ашиглан өндөр давтамжийн цахилгаан дохиог бүхэл тоогоор бага давтамжтайгаар бууруулах;

Харьцуулах (CTC) горимд Clear Timer ашиглах;

- Тоног төхөөрөмжийн CTC горимыг тасалдалгүйгээр ашиглах;

void timer2_init () // timer2 -г эхлүүлэх {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // таймер OC2A зүүг сэлгэх горим болон CTC горимд тохируулах TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // таймерыг prescaler ашиглан тохируулах = 1024 TCNT2 = 0; // тоолуурыг эхлүүлэх OCR2A = 250; // харьцуулах утгыг эхлүүлэх}

TCER0 халих бүрт TIMER0 халих тасалдлын үйлчилгээний горим:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // халих тоог хянах.

Тоглолт болох үед энэхүү ISR -ийг ажиллуулдаг.

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // энд дарж сэлгэх}

int main (хүчингүй)

{DDRB | = (1 << 0); // холбох 1 (ногоон) зүү PB0 DDRC | = (1 << 1); // холбох 2 (цэнхэр) зүү PC1 DDRB | = (1 << 3); // холбох 3 (улаан) зүү PB3 (OC2A) timer0_init (); // timer0 timer1_init () -ийг эхлүүлэх; // timer1 timer2_init () -ийг эхлүүлэх; // timer2 -ийг эхлүүлэх (1) // үүрд давтах {

Хэрэв Timer0 12 удаа давсан бол 12 * 4.096ms = 49.152ms өнгөрөх байсан. 13 дахь давталтад бидэнд 50ms - 49.152ms = 0.848ms -ийн саатал хэрэгтэй байна. Тиймээс, 13 дахь давталтад бид таймерыг зөвхөн 53 хүртэл тоолж, дараа нь дахин тохируулахыг зөвшөөрдөг.

if (tot_overflow> = 12) // үгүй эсэхийг шалгана уу. of overflows = 12 ТАЙЛБАР: '> =' ашиглаж байна

{if (TCNT0> = 53) // таймерын тоо 53 хүрсэн эсэхийг шалгана уу {PORTB ^= (1 << 0); // удирдсан TCNT0 = 0 -ийг сэлгэнэ; // тоолуурыг дахин тохируулах tot_overflow = 0; // халих тоолуурыг дахин тохируулах}}}}

HEX файлыг микроконтроллерийн флаш санах ойд байршуулж байна

DOS хүлээх цонхонд дараах тушаалыг бичнэ үү:

avrdude –c [програмистын нэр] –p m328p –u –U флаш: w: [таны зургаан өнцөгт файлын нэр] Миний хувьд энэ нь: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

Энэ тушаал нь hex файлыг микроконтроллерийн санах ойд бичдэг. Микроконтроллерийн флаш санах ойг шатаах тухай дэлгэрэнгүй тайлбар бүхий видеог үзээрэй.

Микроконтроллерийн флаш санах ой шатаж байна …

Болж байна уу! Одоо микроконтроллер нь манай програмын зааврын дагуу ажиллаж байна. Үүнийг шалгаж үзье!

Алхам 6: Цахилгаан хэлхээ хийх

Цахилгаан хэлхээ хийх
Цахилгаан хэлхээ хийх
Цахилгаан хэлхээ хийх
Цахилгаан хэлхээ хийх
Цахилгаан хэлхээ хийх
Цахилгаан хэлхээ хийх

Схемийн дагуу бүрэлдэхүүн хэсгүүдийг холбоно уу.

Зөвлөмж болгож буй: