Monday, December 21, 2009

AVR Tutorial 2: Тоолуур

Зарим тохиолдолд микроконтроллер дээр тодорхой хугацааны дараа юм уу эсвэл тодорхой давталтаар ямар нэгэн үйлдэл хийх хэрэгтэй болдог. Үүнд timer/counter буюу тоолуур ашиглана. AVR микроконтроллер төрлөөсөө хамаараад 8 болон 16 битийн хэд хэдэн тоолууртай байдаг. Энэ хичээлд ашиглаж буй Attiny2313 маань 8 битийн нэг (timer/counter дугаар: 0), 16 битийн нэг (timer/counter дугаар: 1), нийтдээ 2 тоолууртай.

Өмнөх хичээлийн оролт гаралт шиг тоолууруудыг мөн регистрүүдээр тохируулдаг. Энэ удаа 0 дугаарын 8 битийн timer/counter -ыг хэрхэн тохируулахыг тайлбарлая.

Тоолуур хэр хурдан тоолохыг timer/counter control register буюу TCCR0B регистрийн баруун захын CS02, CS01, CS00 (CS нь chip select -ийн товчлол) гэсэн гурван битээр тохируулна.
  • CS02=0, CS01=0, CS00=0 бол тоолуур ажиллахгүй байх болно.
  • CS02=0, CS01=0, CS00=1 бол тоолуур микроконтроллерын хурдаар тоолно.
  • CS02=0, CS01=1, CS00=0 бол тоолуур микроконтроллерын хурднаас 8 дахин удаан тоолно.
  • CS02=0, CS01=1, CS00=1 бол тоолуур микроконтроллерын хурднаас 64 дахин удаан тоолно.
  • CS02=1, CS01=0, CS00=0 бол тоолуур микроконтроллерын хурднаас 256 дахин удаан тоолно.
  • CS02=1, CS01=0, CS00=1 бол тоолуур микроконтроллерын хурднаас 1024 дахин удаан тоолно.
  • CS02=1, CS01=1, CS00=0 бол микроконтроллерын T0 хөлийн утга 1 -ээс 0 -руу шилжих мөчид тоолуурын утга нэгээр нэмэгдэнэ. Attiny2313 -ын хувьд T0 хөл бол PD4 хөл юм. Жишээ нь энэ хөлийг ашиглаж товчлуур хэд дахиж дарагдсаныг тоолж болно гэсэн үг.
  • CS02=1, CS01=1, CS00=1 бол микроконтроллерын T0 хөлийн утга 0 -ээс 1 -руу шилжих мөчид тоолуурын утга нэгээр нэмэгдэнэ.
Хэрвээ таны микроконтроллер 1 Mhz -ын хурдтай байвал доорх код 1 миллисекунд (1/(1000000/1024) = 0.001024 секунд) тутамд тоолуурын утгыг нэгээр ихэсгэнэ:

// CS02=1, CS01=0, CS00=1 -> 1/(1000000/1024) = 0.001024 секунд
TCCR0B = (1 << CS02) | (1 << CS00);

0 дугаар тоолуурын утга TCNT0 регистр дээр хадгалагдана.

Одоо энэ хоёр регистрийг ашиглаад PB1 хөл дээр залгасан LED диодоо секунд болгонд асааж унтраадаг болгоё:

#include "avr/io.h"

// 200 миллисекунд хүлээ
void wait_200_milliseconds() {
// Тоолуурыг тэглэнэ
TCNT0 = 0;
// Микроконтроллер 1000000 hertz ийн хурдтай ажиллаж байгаа
// 1/(1000000/1024) = 0,001024 секунд
// Тоолуурын утга 1,024 миллисекунд болгонд нэгээр ихсэнэ
TCCR0B = (1 << CS02) | (1 << CS00);
// Тоолуурын утга 200 болтол хүлээ
while (TCNT0 < 200);
// Тоолуур ажиллуулахын болиул
TCCR0B = 0;
}

int main() {
uint8_t i;

// PB1 хөл дээр LED залгасан
DDRB |= (1 << PB1);
// LED асаа
PORTB |= (1 << PB1);

while(1) {
// 5 удаа 200 миллисекунд хүлээх = нийтдээ нэг секунд
for (i = 0; i < 5; i++) {
wait_200_milliseconds();
}
// LED унтраастай бол асаа, асаалттай бол унтраа
PORTB ^= (1 << PB1);
}
return 0;
}

Дээрх кодын сул тал нь тоолуур ажиллаж байх үед микроконтроллер өөр юу ч хийх боломжгүй. Энэ асуудлыг хоёр янзын тасалдал (англиар interrupt) ашиглаж арилгаж болно. TCNT0 регистрийн утга 255 -аас 0 -руу шилжих мөчид timer/counter overflow interrupt эсвэл TCNT0 -ын утга OCR0A регистрийн утгаас илүү гарсан тохиолдолд timer/counter compare match interrupt тус тус үүсгэн ашиглаж болдог.
Timer/counter overflow тасалдал үүсгэхийн тулд TIMS (timer/counter interrupt mask) регистрийн TOIE0 битэд 1 гэсэн утга олгох хэрэгтэй. Харин timer/counter compare match тасалдал үүсгэе гэвэл TIMS регистрийн OCIE0A битийг 1 болгох ёстой бөгөөд тухайн тасалдлын үед тоолуурын утгыг тэглэе гэвэл TCCR0A регистрийн WGM01 битийг 1 болгоод бусад WGM битүүдийг тэглэнэ.

Дээр бичсэн кодыг одоо timer/counter compare match тасалдал ашигладаг болгож өөрчилье:

#include "avr/io.h"
#include "avr/interrupt.h"

volatile uint8_t i = 0;

ISR (TIMER0_COMPA_vect)
{
i++;
// 5 udaa 200 millisekunden = 1 sekund
if (i == 5) {
// LED g untraastai bol asaa, asaalttai bol untraa
PORTB ^= (1 << PB1);
i = 0;
}
}

int main() {
// PB1 hol deer LED zalgagdsan
DDRB |= (1 << PB1);
// LED g asaa
PORTB |= (1 << PB1);

// Tooluuriin utgiig 0 bolgo
TCNT0 = 0;
// tooluuriin utga OCR0A tai tentsvel tooluuriig tegle
TCCR0A |= (1 << WGM01);
// mikrocontroller 1000000 herz iin hurdtai ajillaj baigaa
// 1/(1000000/1024) = 0,001024 sekund
// tooluuriin utga 1,024 millisekund bolgond 1 eer nemegdene
TCCR0B |= (1 << CS02) | (1 << CS00);
// 200 millisekund tutamt compare match interrupt uusne
OCR0A = 199;
// compare match interrupt iig uusehiig zovshooroh
TIMSK |= (1 << OCIE0A);
// global interrupt zovshooroh
sei();
while(1) {
// end oor uildel hiij bolno
}
return 0;
}

0 дугаар тоолуур OCR0A -аас гадна OCR0B гэж бас нэгэн регистртэй.

Sunday, December 20, 2009

AVR Tutorial 1: Оролт гаралт

Энэ бичлэгтээ микроконтроллерийн оролт гаралтыг яаж ашигладаг болохыг товч тайлбарлая. AVR маань 8 битийн архитектуртай тул оролт гаралт болон бусад бүх тохиргоонуудыг 8 битийн регистрүүдээр хийдэг. Иймд микроконтроллерийн хөлийг найм наймаар нь A, B, C гэх мэтээр хувааж тус тусых нь DDR, PIN, PORT регистрүүдээр удирдана. Жишээ нь B -гийн найман хөлийг удирдъя гэвэл DDRB, PINB, PORTB регистрүүдийг ашиглана.

DDR регистрээр микроконтроллерийн хөлийг оролт уу гаралт уу гэдгийг зарладаг. Регистрийн X дэх бит 0 байвал X дүгээр хөл оролт, харин 1 байвал гаралт болно. Жишээ нь доорх код B -ийн 0 дугаар (PB0) хөлийг оролт харин 1 дүгээр (PB1) хөлийг гаралт болгоно.

// PB0 хөл оролт
DDRB &= ~(1 << PB0);
// PB1 хөл гаралт
DDRB |= (1 << PB1);

Хэрвээ хөлөө гаралт гэж тохируулсан бол PORT регистрээр тэр хөлөөрөө тог гаргах уу (битийн утга 1) үгүй юу (битийн утга 0) гэдгээ тохируулдаг. Доорх жишээ код B -ийн 1 дэх (PB1) хөлөөр эхэлж тэжээл гаргаад дараа нь унтрааж байна.

// PB1 хөлөөр тэжээл тараана
PORTB |= (1 << PB1);
// PB1 хөлөөр тог гарахгүй
PORTB &= ~(1 << PB1);

Хэрвээ та хөлөө оролтын хөл гэж зарласан бол PIN регистрээр тухайн хөл дээр тэжээл очсон эсэхийг шалгаж болдог. PIN регистрийн X дэх битийн утга 1 байвал тухайн хөл дээр тог очсон байна харин 0 байвал үгүй гэсэн үг. Доорх код PB0 хөл дээр тэжээл байгаа үгүйг шалгана.

if(PINB & (1 << PB0)) {
// PB0 хөл дээр тог очиж байна
} else {
// PB0 хөл дээр тог очихгүй байна
}

За ингээд өмнөх бичлэгийнхээ үндсэн хэлхээ дээр диод болон товчлуур нэмье. Товчлуур болон гэрэлт диод яаж залгадаг болохыг mncontroller -ын бичлэгүүдээс хараарай. Attiny2313 -ын PB0 хөл дээр товчлуур (энэ хөл оролт) харин PB1 дээр диод (гаралт) залгав.


Одоо товчлуур дээр дарвал диод асдаг харин боливол диод унтардаг болгох программ бичье:

#include "avr/io.h"

int main() {
// PB0 хөл дээр товчлуур залгагдсан -> оролт
DDRB &= ~(1 << PB0);
// PB1 хөл дээр гэрэлт диод залгагдсан -> гаралт
DDRB |= (1 << PB1);

while(1) {
if (PINB & (1 << PB0)) {
// товчлуур дарагдсан байна -> диод асаа
PORTB |= (1 << PB1);
} else {
// товчлуур дарагдаагүй байна -> диод унтраа
PORTB &= ~(1 << PB1);
}
}

return 0;
}

Дээрх программыг WinAVR ашиглаж хөрвүүлээд AVRStudio -оор микроконтроллер уруу хуулав. Үр дүн нь нэг иймэрхүү харагдаж байна. Товчлуур дараагүй байхад:


Товчлуур дарахад диод асаж байгаа байдал:

Thursday, December 17, 2009

AVR Tutorial 0: Үндсэн хэлхээ

AVR микроконтроллер ажиллуулах маш хялбар. Хамгийн энгийн аргаар залгая гэвэл ердөө нэг конденсатор болон нэг эсэргүүцэл нэмж залгаад л болоо.

Дээрх схем дээр Attiny2313 -ын үндсэн холболтыг үзүүлэв (бусад AVR -ууд яаг адилхан холбогдоно). 10KΩ -ын эсэргүүцэл R1 нь AVR -ыг reset хийхэд хэрэг болно (mncontroller яаж Sanguino хавтандаа товчлуур залгасантай харьцуулж үзээрэй). 100 нанофарадын конденсатор C1 нь гүйдлийн хүч тогтворжуулах үүрэгтэй. Дижитал техникт ийм конденсаторыг бүх чипний VCC болон GND хөлүүдийн хооронд тавьдаг. JP1 бол 2 эгнээтэй, эгнээ бүрдээ 3 хөлтэй залгуур. ISP дэмждэг AVR программчлагч төхөөрөмжөө энэ залгууртай холбоно. Өөр юу ч залгах хэрэггүй (Мэдээж та яаг юу хийхээсээ хамаарч өөр эд анги залгах хэрэгтэй).

Доорх зураг схем дээр зурж үзүүлсэн үндсэн хэлхээг breadboard дээр зоож байрлуулсныг харуулж байна. Зүүн талд байгаа төхөөрөмж нь Atmel -ийн STK500 гэдэг программатор.

Tuesday, December 8, 2009

AVR Микроконтроллер: mini FAQ

AVR гэж ямар микроконтроллер байдаг юм бэ?
Atmel компани 8051, ARM гэх мэт микроконтроллер лицензээр үйлдвэрлэхээс гадна өөрийн AVR хэмээх 8 битийн микроконтроллер үйлдвэрлэж зардаг. Европ тивд өргөн дэлгэрсэн, хямд үнэтэй микроконтроллер. Хүчин чадлаас нь хамаараад аttiny (tiny = бичил), аtmega (mega = том), аtxmega (xmega = маш том) гэж ерөнхийд нь гурав хуваана. (Мөн AT90USB, AT90CAN гэх мэт ховор хэрэглэгддэг тусгай төрлүүд байдаг)

Ямаршуухан техникийн үзүүлэлттэй юм бэ?
  • 32 Mhz хүртэл хурдан
  • 0.5 -аас 384 килобайт хүртэл ROM
  • 0 -оос 16 килобайт хүртэл RAM
  • 0 -оос 4 килобайт хүртэл EEPROM
  • 6 -аас 100 хүртэл хөлтэй
  • ADC, PWM, SPI, I2C, UART, Watchdog
  • 1,7 -оос 5V -ын хүчдэлээр ажиллана.
Хамгийн өргөн хэрэглэгддэг Atmega8 гэдэг хувилбар нь 8 килобайт flash ROM, 1 килобайт RAM, 512 килобайт EEPROM, 28 ширхэг хөл, 20 Mhz -ийн хурдтай.

Ямар программын хэл ашиглах ёстой вэ?
Та ассемблер, C, Pascal, Basic гэх мэт дуртай хэлээ ашиглаж программ бичиж болно.

Ямар программын хэл ашиглавал зүгээр вэ?
Atmel жишээ программуудаа C хэл дээр хөгжүүлдэг учир энэ программын хэлийг ашиглавал амар байдаг. Үнэгүй open source GNU C compiler -ын портууд ашиглаж болно. Та Windows үйлдлийн системийн хэрэглэгч бол WinAVR toolchain ашиглаарай.

Ямар IDE ашиглаж программ бичих вэ?
Atmel ын AVR Studio -г ашиглаж болно. Мөн Eclipse CDT IDE г AVR-Eclipse plugin -тай хамт ашиглах боломжтой.

Хөгжүүлсэн программаа микроконтроллеруугаа яаж хуулах вэ?
In-System-Programming (ISP), High-Voltage-Programming (HVI) эсвэл JTAG дэмждэг STK500, AVR dragon гэх мэт төхөөрөмж ашиглан хуулна.

Тийм төхөөрөмжгүй бол яах вэ?
Хэрвээ таны AVR bootloader -тай бол компьютерын USB болон COM порт ашиглан шууд хуулж бас болдог.

AVR микроконтроллероо ажиллуулахын тулд юу нэмж залгах ёстой вэ?
Хамгийн энгийнээр залгая гэвэл нэг батарей нэмж залгаад л болоо.

Thursday, December 3, 2009

Work No.1-1 Button нэмж залгах

Товчлуур залгаж зөвхөн дарсан тохиолдолд диодоо анивчуулдаг болгон тохируулъя.

Товчлуурыг микроконтроллерд хоёр янзаар залгаж болно.

Товчлуур дарагдсан тохиолдолд микроконтроллерын хөл дээр тог очиж байвал тухайн холболтыг active high гэж нэрлэнэ. Доорх схемийг хараарай. Гүйдлийн хүч хязгаарлах эсэргүүцлээр ихэвчлэн 10 KΩ ын эсэргүүцэл ашигладаг.


Доорх схем дээр товчлуур дараагүй тохиолдолд 5V, харин дарсан тохиолдолд 0V очно. Ийм учир энэ холболтыг active low гэж нэрлэдэг.


Товчлуур дарсан эсэхийг AVR микроконтроллер дээр тун амархан шалгаж болно. Эхлээд DDR хэмээх регистр ашиглан товчлуур залгасан хөлөө оролтын хөл гэж зарлаж өгөх хэрэгтэй. Товчлуур PB1 хөл дээр залгагдсан тул

DDRB &= ~(1 << PB1); // 8 бит DDRB регистрийн баруунаас 2 дахь битийг 0 болгоно, үлдсэн долоон битний утга өөрлөгдөхгүй

гэхэд хангалттай.
Active High аар товчлуураа залгасан бол доорх байдлаар PIN регистр ашиглан товчлуур дарсан үгүйг мэдэрнэ:

if (PINB & (1 << PB1)) {
// товчлуур дарагдсан байна
} else {
// товчлуур дарагдаагүй байна
}

PS: edited by Ajaxmaa 2009/12/07