Проектирование удаленного устройства индикации

СОДЕРЖАНИЕ: Проектирование принципиальной схемы устройства индикации на основе 8-битного AVR микроконтроллера типа ATmega16 с питанием от источника питания на 10 V и отображением данных на графическом LCD-дисплее. Разработка программного обеспечения микроконтроллера.

Содержание

Введение

1. Анализпоставленнойзадачи

1.1 Обоснованиедостаточностиаппаратныхипрограмма ресурсов

1.2 Доопределениенаборааппаратныхсредствдляреализации устройства

1.3 Распределениефункцийустройствамеждуузламимикроконтроллера

2. Проектированиепринципиальнойсхемыустройства

2.1 Схемавключениямикроконтроллера

2.2 Формированиетактовыхимпульсов

2.3 Схемасброса

2.4 Схемавходныхивыходныхустройств

2.5 Схемастабилизаторанапряжения

3. Проектированиепрограммногообеспечениямикроконтроллера

3.1 Проектирование функцииинициализациимикроконтроллера

3.2 Проектирование процедуробработкипрерываний

3.3 Проектирование процедурвводаинформации

3.4 Проектирование процедурвыводаинформации

3.5 Проектирование процедуруправленияпериферийны! устройствами

3.6 Проектирование процедурыmain()

4. Листингпрограммы

Приложение 1. Схемаэлектрическаяпринципиальная

Приложение 2. Чертежпечатнойплаты (видсверху)

Приложение 3. Чертежпечатнойплаты (видснизу)


Ведение

Широкораспространенноесемейство микроконтроллеровMCS51, выпускаемоецелымрядомфирм-производителей (Intel, Philips, Temic, OKI, Siemensидр.), уже являлосьде-фактопромышленнымстандартомдля 8-разрядныхсистем ипрекрасноподходилодляиспользованиявширокомклассезадач, особенноесливыбиралиськристаллысдополнительнымивстроенными периферийнымиустройствамииповышеннойтактовойчастотой. Но этимикроконтроллерыобладализначительнымэнергопотреблением. Тогда, еслинеобходимобылополучитьвысокуюпроизводительность кристаллапрификсированномэнергопотребленииили, наоборот, снизитьпоследнеенетеряяпроизводительности, внимание разработчика, какправило, останавливалосьнамикросхемахDallasSemiconductor, MicrochipилиHitachi. ШирокоразвитыелинииPIC-контроллеровфирмыMicrochipимикроконтроллеровН8/300 фирмы Hitachiобеспечиваютдостаточновысокуюпроизводительностьпри небольшомэнергопотреблении. Эффективностьработы микроконтроллеровDallasSemiconductor, имеющихбазовую архитектуруMCS51, всреднемпревышаетстандартнуюв 2,5 - 3 раза. Появившиесявпоследнеевремяновыепроцессорныеплатформы MSP430 фирмыTexasInstrumentsиХЕ8000 фирмыXeraicsтакже заслуживаютсамогопристальноговнимания, особенноеслиосновным критериемдляконечногоприложенияявляетсяминимальное энергопотребление.

Окончательныйвыборразработчикомтойилииной микропроцессорнойплатформыдляреализациисвоейзадачизависит отбольшогочисларазнообразныхфакторов, включаяэкономические. Нообычнопервостепеннымусловиемостаетсяполучениемаксимально выгодногосоотношения цена - производительность энергопотребление, определяемогосложностьюрешаемойзадачи. Видимо, этообстоятельствоипослужилотолчкомкразработкев середине 1990-хнового 8-разрядногомикроконтроллера.

AVRодноизсамыхинтересныхнаправлений, развиваемых корпорациейAtmel. Онипредставляютсобоймощныйинструментдля созданиясовременныхвысокопроизводительныхиэкономичных многоцелевыхконтроллеров. Нанастоящиймоментсоотношение цена - производительность - энергопотребление дляAVRявляетсяодним излучшихнамировомрынке 8-разрядныхмикроконтроллеров. Объемы продажAVRвмиреудваиваютсяежегодно. Вгеометрической прогрессиирастетчислостороннихфирм, разрабатывающихи выпускающихразнообразныепрограммныеиаппаратныесредства поддержкиразработокдляних. Можносчитать, чтоAVRпостепенно становитсяещеодниминдустриальнымстандартомсреди 8-разрядных микроконтроллеровобщегоназначения.

ОбластипримененияAVRоченьшироки. Длясемейства tiny -этоинтеллектуальныеавтомобильныедатчикиразличного назначения, игрушки, игровыеприставки, материнскиеплаты персональныхкомпьютеров, контроллерызащитыдоступавмобильных телефонах, зарядныеустройства, детекторыдымаипламени, бытоваятехника, разнообразныеинфракрасныепульты дистанционногоуправления. Длясемейства classic - этомодемы различныхтипов, современныезарядныеустройства, изделиякласса SmartCardsиустройствачтениядляних, спутниковые навигационныесистемыдляопределенияместоположенияавтомобилей натрассе, сложнаябытоваятехника, пультыдистанционного управления, сетевыекарты, материнскиеплатыкомпьютеров, сотовыетелефоныновогопоколенияатакжеразличныеи разнообразныепромышленныесистемыконтроляиуправления. Для mega AVR - этоаналоговые (NMT, ETACS, AMPS) ицифровые (GSM, CDMA) мобильныетелефоны, принтерыиключевыеконтроллерыдля них, контроллерыаппаратовфаксимильнойсвязииксероксов, контроллерысовременныхдисковыхнакопителей, CD-ROMит.д.

ВданнойработеприводитсяпримериспользованияAVRтипа ATmega16 дляпостроенияустройстваудаленнойиндикации, принимающеесигналыпопротоколусвязиRS-485 иотображающее соответствующуюинформациюнаграфическомЖКИдисплеефирмы Bolyrain.


1. Анализпоставленнойзадачи

Постановказадачи; спроектироватьудаленноеустройство индикациинаоснове 8-битногоAVRмикроконтроллератипаATmega16 спитаниемданногоустройстваотисточникапитанияна 10 V. ТребуетсяобеспечитьприемданныхпопротоколуRS-485 на скорости 9600 битвсекунду, сразмеромпосылкиданных 8 бит, проверкойначетностьиоднимстоповымбитом. Данныедолжны отображатьсянаграфическомLCD-дисплеефирмыBolymin.

1.1 Обоснованиедостаточностиаппаратныхсредствипрограммных ресурсов

ПредложенныйдлярешениязадачимикроконтроллерATmegal6 обладаетследующимихарактеристиками:

• напряжениепитания+5 V

• размерпамятипрограмм 16 К

• размерEEPROM512 В

• размервнутреннейSRAM 1 К

• портыввода/вывода4x8 bit

• четыретаймерасчетчика

• программируемыйпоследовательныйУСАПП

Этихсвойствмикроконтроллеравполнедостаточнодля обеспечениявзаимодействиясграфическимLCD-дисплееми протоколомобменаданнымиRS-485, посколькубольшойобъемпамяти программпозволяетобеспечитьлогикуработывсехаппаратных средствмикроконтроллераиуправлениеLCD-дисплеем. Крометого, подключениевнешнегоисточникатактовыхимпульсовпозволяет обеспечитьскоростьобменаданнымидо 1 миллионабитвсекунду.


1.2 Доопределениенаборааппаратныхсредств

ДляорганизацииканаласвязипопротоколуRS-485 необходимо использованиеустройств, отвечающихтребованиямэтогопротокола. Возможноерешение - использованиесхемыМАХ485, котораяработает отодногоисточникапитания +5 V, иеговыходноесопротивление становитсявысокимвдиапазонесинфазногосигналаот -7 до +12 Vприподачеипривыключениипитания. Передатчикимеет максимальноевремязадержки 50 пзивремянарастанияиспада менее 80 ns. Этопозволяетполучитьскоростьпередачиданныхдо 4 Mbaud.

Посколькуразрабатываемоеустройствопитаетсяотисточника напряжения +10 V, тодляобеспеченияпитаниямикросхем устройстванеобходимоиспользованиестабилизаторанапряжения, которыйможнореализоватьнамикросхемеLM2574 (понижающий импульсныйстабилизаторнапряжения).

1.3 Распределениефункцийустройствамеждуузлами микроконтроллера

Разрабатываемоеудаленноеустройствоиндикациидолжно выполнятьследующиедвеглавныефункции: обеспечениеприема данныхпоканалусвязиииндикацияобработанныхданныхнаLCD-дисплей.

Вполнелогичновкачествеприемникаиспользоватьвстроенныйв контроллерпрограммируемыйпоследовательныйуниверсальный синхронно-асинхронныйприеме-передатчик (УСАПП). Приэтомбудут задействованывыводыPDO (RxD) иPD1 (TxD), которыеподключаются ксоответствующимвыводаммикросхемыМАХ485. Крометого, для управлениямикросхемойМАХ485 необходимоподключитьтакже сигналыразрешенияприемаипередачиданных (сигналразрешения приема - инверсный), Нопосколькувнашемустройствене предусмотренавозможностьодновременноприниматьипередавать данные, представляетсяудобнымиспользованиеобщегосигналас одногоизвыводовконтроллерадляуправленияприемомипередачей (выводпортаСРС5). Болеетого, вчастномслучаенаше устройствонебудетпередаватьданныенавнешниеустройства, поэтомукакодинизвариантовможетбытьиспользованопросто подключениеразрешающихвыводовмикросхемыМАХ485 кобщему постоянномусигналунизкогоуровня, чтозапретитмикросхеме передачуданныхионабудетвсевремяиспользоватьсякак приемник.

УправлениеLCD-дисплеемосуществляетсяспомощьювосьми линий, покоторымпередаютсяданные, ипятилиний, покоторым передаютсясигналыуправления (чтение/записьданных, запись командыит.п.}. Поэтомудляуправлениядисплееммывыделимпорт АконтроллерадляпередачисигналовданныхилинииРСО - РС4 портаСдляпередачисигналовуправления.

Всеостальныеустройстваконтроллеравнашем (простейшем) случаеостаютсянезадействованными.


2. Проектированиепринципиальнойсхемыустройства

2.1 Схемавключениямикроконтроллера

МикроконтроллерAVRтипаATmegal6 имеетнапряжениепитания +5 V, котороеподводитсяквыводуVCC. Таккакпитаниевсегонашего устройства +10 V, топитаниекмикроконтроллерудолжно подводитсячерезпонижающийимпульсныйстабилизатор. Кроме этого, микроконтроллеримеетещедвавыводадляпитанияпортаА (илиАЦП), одинизкоторых (AVCC) долженбытьподключенк напряжениюпитаниядажееслипортАнеиспользуется. Приесли используетсяАЦП, тоэтопитаниедолжноподключатсячерезфильтр низкихчастот. Второйвывод (AREF) используетсядляподачи напряжениясмещениянаАЦП.

ВнашемустройствеАЦПнеиспользуется, поэтомуквыводамVCCиAVCCможноподключитьпредварительностабилизированноепитание +5 Vотстабилизатора, авыводAREFподключитькобщейшине земли.

Рис.1 Схемавключениямикроконтроллера


2.2 Формированиетактовыхимпульсов

Тактовыеимпульсыдляработымикроконтроллераможно формироватьспомощьюлибовстроенногогенератораимпульсов, либоподключаявнешнийгенераторнакварцевомрезонаторе. Внутреннийгенератортактовыхимпульсоввнашемслучаене обеспечитнеобходимуюстабильностьдляработысинтерфейсомRS-485, поэтомумыбудемиспользоватьвнешнийкварцевыйгенератор на 7.3728 MHz. Дляработынатакойчастотеразработчикифирмы ATMELсоветуютиспользоватьдвадополнительныхконденсатора емкостью 22 pF, включенныепоследующейсхеме:

2.3 Схемасброса

Схемасбросадолжнаформироватьимпульслогическогонулядля подачиегонаинверсныйвыводсбросамикроконтроллераRESET. Это импульсдолженформироватьсяпри, например, нажатиинакнопку сбросаустройстваилиприпереключенииключа. Кромеэтого, этот сигналсбросадолженподаватьсяинавыводсбросаLCD - дисплея.

Длятакойсхемыподходитвключениетранзистора, показанноена рис.3. Когдаключоткрыт, транзисторнаходитсявзакрытом состоянииинавходыRESETAVRиRSTLCD-дисплеяпоступает сигналлогическойединицы. Когдаключзамыкается, транзистор открываетсяинавходысбросаустройствпоступаетсигнал логическогонуля.


Рис.3 Схемаформированиясигналасброса

2.4 Схемывходныхивыходныхустройств

Входнымустройствомвнашемпроектеявляетсямикросхема обеспечениясвязипопротоколупередачиданныхRS-485 МАХ 485 со следующимиэлектрическимихарактеристиками:

Изэтихпараметроввидно, чтомикросхемаМАХ485 согласуетсяс микроконтроллеромATmegal6.

Рис. 4 ПодключениемикросхемыMAX4S5

Выходноеустройствожидкокристаллическийграфический дисплейBG12864DфирмыBolyminсовстроеннымконтроллером Т6963С. Этотдисплейобладаетследующимихарактеристиками:

•Механическиехарактеристики

•Назначениевыводов

ВсоответствиисэтимипараметрамисхемаподключенияLCD-дисплеякмикроконтроллерубудетследующей:

2.5 Схемастабилизаторанапряжения

Вкачествестабилизаторанапряжениявнашемустройстве используетсяимпульсныйпонижающийстабилизаторLM2574, который обладаетследующимихарактеристиками:

• входноенапряжение - до 60 V {дляHVверсий)

• выходноенапряжение - 3.3 V, 5 V, 12 V, 15V

• выходнойток - 0.5 А

Схемавключениястабилизаторадляпреобразования +10 V - +5 Vприведенанарис.6:


Рис. 6 (Схема стабилизатора напряжения


3. Проектированиепрограммногообеспечения микроконтроллера

3.1 Проектированиефункцииинициализациимикроконтроллера

Процедураинициализациимикроконтроллерадолжнасостоятьиз процедурилиоператоровинициализациивсехузловсамого микроконтроллераивсехпериферийныхустройств, иустановитьвсе начальныезначениядляихрегистров. Такимобразом, мыдолжны проинициализироватьследующиеузлыустройства - портА, портС, УСАПП, таймер 0 иLCD-дисплей.

ПортыАиСвначалеработыустройстваработаюттолькона выводданных, поэтомуприихнастройкенеобходимов соответствующиерегистрыDDRxзаписатьзначение 0, темсамым настроив все их выводы на передачу данных. Для этого используются две процедуры;

voidInitPortAWrite(void){

DDRA = Oxff; }

void InitPortCWrite(void){ DDRC = Oxff; PORTC = 0x30;

ИнициализациятаймераОпроходитпоследующемуалгоритму - устанавливаетсяделительчастотына 1024 записьюзначения 5 в регистрTCCRO. Затемразрешаетсяпрерываниеэтоготаймераи устанавливаетсяегоначальноезначение:

void InitTimer(void)

i

_disable_interrupt() ;

TCCRO = 5;// установитьделительчастоты 1024

TIMSK |= (1 «TOIEO); // разрешитьпрерываниятаймера

TCNTO = TmrO_Reload;

enable_interrupt{);

]

ИнициализацияУСАППработаетследующимобразом - врегистр

UBRRзаписываетсязначение, котороесоответствуетзаданной скоростипередачиданныхдлясоответствующейчастотыработы микроконтроллера.

УСАПП и параметры кадра данных. Кроме этого, т.к. прием и обработка данных в программе происходит через кольцевой буфер, то в процедуре инициализации необходимо провести начальные установки для головы и хвост буфера - обнулить их.

void USART_Init( unsigned int baudrate )

i

unsigned char x;

UBRROH = (unsigned char) (baudrate»8) ; UBRROL = (unsigned char) baudrate;

UCSRB = ({1 « RXCIE) j 1«ЮСН) ) ;

UCSRC = (1«URSEL) | (3«UCSZO) | (1«UPM1);

x = 0;

USART_RxTail = x; USARTJRxHead = x;

}

3.2 Проектирование процедур обработки прерываний

В процессе работы нашего устройства могут возникнуть два прерывания - от таймера 0 и от УСАПП. Прерывание от таймера О обрабатывается очень просто: перезагружается начальное значение и флаг его срабатывания устанавливается в 1.


pragma vector=TIMERO_OVF_vect

interrupt void TIMERO_OVF_interrupt(void)

{

TCNT0=TmrO_Reload; TmrOFlag = 1;

}

ПрерываниеотУСАППговоритотом, чтоприемпакетаданных былзаконченипринятвбуферныйрегистрUDR. Обработчикэтого прерываниядолженпринятьэтиданныеипоместитьвкольцевой буфер. Дляэтогодолженбытьрассчитанновыйиндексбуфера (указательголовы) иеслиэтотиндексвдругсталравенуказателю хвоста, этоговоритотом, чтопроизошлаошибкаибуфер приемникапереполнился.

^pragma vector=USART_RXC__vect

^interrupt void USART_RX_interrupt{ void )

{

unsigned char data; unsigned char tmphead;

data = UDR;

tmphead = ( USART_RxHead + 1 );

USART_RxHead = tmphead; /* СохранитьновыйиндексV

if tmphead == USART_RxTail )

(

/* Ошибка! Буфферприемникапереполнен */

)

USART_RxBuf[tmphead] = data; /* Сохранитьполученныеданныевбуффере */

}


3.3 Проектированиепроцедурвводаинформации

Вводинформациивразрабатываемоеустройствоосуществляется черезУСАППпопротоколуRS-4 85. Какужеотмечалось, прием данныхвпрограммепроисходитпопрерываниюотУСАПП, обработчик которогопомещаетпринятыйбайтвОуферприемника. Вглавной программе, длятого, чтобыможнобылоанализироватьэтотбуфери читатьданныеуженепосредственноизнего, необходимапроцедура, котораябудетдоставатьданныеизбуфератакимобразом, чтобы первымипоступалибайты, попавшиевбуферраньшевсех. Это делаетпроцедураUSART_Receive(), котораясначалаждет поступленияданныхвбуфер, азатемпоодномубайтудостаетих оттуда.

BYTE USART_Receive( void )

1

unsigned char tmptail;

while ( USARTJixHead == USART_RxTail )

;

tmptail = USART_RxTail + 1; USART_RxTail = tmptail; return USART_RxBuf[tmptail];

f

3.4 Проектированиепроцедурвыводаинформации

ВыводинформациивнашемустройствеосуществляетсянаLCD-дисплей. Основнойпроцедурой, котораяотображаетстроки поступившихданныхнадисплее - этопроцедураAutoWriteMode(), котораяпосутиуправляетдисплеем, выводянанего последовательносимволы, хранящиесявглобальноммассиве OutString[], врежимеавтозаписи, Приэтомнамнеобходимотолько менятьадреспозиции, вкоторуювыводятсяданные.

WORD AutoWriteMode(WORD Address, BYTE NumBytes)

{

SetAddressPointer(Address); SendCommanct{SET_DATA_AUTO_HRITE_COMMAND);

forfint i = 0; i NumBytes; i++) {

AutoWrite(OutString[i]);

Address++; }

SendCommand(AUTO_RESET_COMMAND); return Address; }

3.5 Проектирование процедур управления периферийными устройствами

Все процедуры управления LCD-дисплеем осуществляются согласно системе команд встроенного контроллера Т6963:

3.6 Проектированиепроцедурыmain()

Процедураmain{) работаетследующимобразомпосле инициализациивсеузловAVRипериферийныхустройств, разрешаетсявыполнениевсехпрерываний. Послеэтогопрограмма ждетсрабатываниятаймера, которыйнастроентакимобразом, что оннемногочаще, чемможетпроисходитьпрерываниеотУСАПП. Сигналомтого, чтотаймер 0 сработалслужитфактустановки глобальнойпеременнойTmrOFlagв 1, чтоделаетсяобработчиком прерыванийтаймера.

Затем, всевремя, покакольцевойбуфернебудетпуст, происходитсчитываниеданныхизнего. Считанныйбайтпомещается встроку-массивOutString[], иувеличиваетсясчетчикпринятых байт.

Послеэтогопроверяется, анебыллипоследнийпринятыйиз буферабайтпризнакомокончаниястроки. Еслида, товрежиме автозаписиэтастрокавыводитсянадисплей (заисключением последнегосимволаконцастроки). Послеэтогострокаобнуляется исчетчикпринятыхбайтустанавливаетсявноль.

Влюбомслучаепроисходитсбросфлагатаймеравнольи происходитожиданиеследующегосрабатываниятаймера.


4. Листингпрограммы

Файлмакроопределенийmy_header.h:

^define BYTE unsigned char ttdefine WORD unsigned int

ttdefine READ_STATUS_COMMAND 0x39

ttdefine DATA_WRITE_COMMAND 0x32

tfdefine COMMANDjmTE_COMMAND ОхЗА

// Установкарегистров

^define SET_CURSOR_COMMAKD 0x21

tfdefine SET_OFFSET_COMMAND 0x22

#define SET_ADDRESS_COMMAND 0x24

// Установкаконтрольногослова

#define SET_TEXT_HOME_ADDRESS_COMMAND 0x^0

fldefine SET_TEXT_AREA_COMMAHD0x41

#define SET_GR№HIC_HOME_ADDRESS_CO№1AND 0x42

#define SET_GRAPHIC_AREA_CCMMAND0x43

// Константыустановкирежима

^define OR_MODE0x80

tfdefine EXOR_MODE0x81

^define ANDJMODE0x83

#define TEXT_ATTRIBUTE_MODE0x84

^define INTERNAL_CG_ROM_MODE 0x80

tfdefine EXTERNAL_CG_RAM__MODE 0x88

// Константырежимадисплея

#define DISPLAY_OFF0x90

^define CURSOR_ON_BLIHK_OFF0x92

^define CURSOR_ON_BLINK_OK0x93

#define TEXT_ON_GRAPHIC_OFF0x94

#define TEXT__OFF_GRAPHIC_ON0x98

^define TEXT_ON_GRAPHIC_OnOX9C

// Размеркурсора

#define ONE_LINE OxAO

tfdefine TWO_LINE OxAl

^define THREE_LINEOxA2

ttdefine FOUR_LINE ОхАЗ

^define FIVE_LINE OxA4

^define SIX_LINE OxA5

^define SEVEN_LINEOxA6

^defineEIGHT_LINEOxA7

// Автоматическоечтение/данных

tfdefine SET_DATA_AUTO_WRITE_COMMAND OxBO

^define SET_DATA_AUTO_READ_COMMAND OxBl

^define AUTO_RESET_COMMANDOxB2

//

#define SCREEN_PEEK_CCMMANDOxEO

#define SCREEN_COPY_CC»1MANDOxE8

// Установка/сбросОитов

tfdefine SET_BIT OxFO

^define RESET_BIT OxF8

^define BIT_0 OxFO

#define BIT_1 OxFl

ttdefine BIT_2 OxF2

^define BIT_3 OxF3

idefine BIT_4 OxF4

#define BIT_5 OxFS

^define BIT_6 OxF6

^define BIT_7OxF7

Файлглавкойпрограммыkurs.c;

/* Includes */ ^include iom!28.h ^include ina90.h

Sinclude my_header.h

^define USART_RX_BUFFER_SI2E 128

itdefine TmrOReload 4

static unsigned char TmrOFlag;

Static unsigned char USART_RxBuf[USART_RX_BUFFER_SIZE];

static volatile unsigned char USART_RxHead; static volatile unsigned char USART_RxTail;

staticBYTEOutString[128];

// Процедурыинициализацииустройств

void InitAVR(void);

void USART_Init( unsigned int baudrate );

void InitLCD(void);

void InitTimer(void);

void InitPortARead(void);

void InitPortAWrite(void)?

voidInitPortCWrite(void);

// ПроцедурыдляработысУСАППиLCD

unsigned char USART_Receive( void );

void Data«riteBYTE Data);

void CommandWrite(BYTE Command);

void ReadStatus(void);

void ReadStatus2(void);

void SendCoimand{BYTE Command);

void SendlByteCommand(BYTE Data, BYTE Command);

void Send2ByteCommand(WORD Data, BYTE Command);

void SetCursorPointer(WORD Position)

void SetAddressPointer(WORD Address)

void ByteWriteToRam(WORD AddressPointer, BYTE Data)

void AutoWrite(BYTE Data);

void mainf void )

f

BYTE HumBytes = 0;

InitAVR();

_SEI(); /* Разрешитьпрерывания */

while (!)

{

if(TmrOFlag) // Произошлосрабатываниетаймера

{

BYTE rec = 0;

while(DatalnReceiveBuffer() != 0) // Покабуффернепуст

{

rec = USART_Receive(); // Принялибайтизбуффера

OutString[NumBytes] = Rebuild(rec); // Записалиеговстроку NumBytes-n-;// Увеличитьсчетчикпринятыхбайт

if (rec == OxOD)// Конецстроки - ?

f

/* ВыводимстрокунаLCDврежимеAutoWrite*/

AutoWriteModefO, —NumBytes)

for(int i = 0; i = NumBytes; i++) OutStringU] = 0;

NumBytes = 0; }

\

TmrOFlag = 0;

} )

}

/* Процедураинициализации USART */ void USART_Init( unsigned int baudrate ) t

unsignedcharx;

/* Установитьчастоту */

UBRROH = (unsigned char) (baudrate»8) ;

UBRROL = (unsigned char) baudrate;

/* Включитьприемник UART */ UCSRB = { (1 « RXCIE) | (1«RXEH) ) ;

У/Форматприемаданных: 8 битданных, 1 стоп-бит, проверканачетность UCSRC = (1«URSEL) I (3«UCSZO) | (1«UPM1) ;

/* Обнулитьбуфферприемника */ х = 0;

USARTJbcTail = х; USART_RxHead = х;

)

/* Процедурачтенияизприемника */ BYTEUSART_Receive( void }

{

unsignedchartmptail;

while( USART_RxHead == USART_RxTail ) /* Ждемпоступленияданных */ ;

tmptail = USART_RxTail + 1; /* Рассчетиндексабуффера */ USART_RxTail = tmptail;/* Сохранитьновелииндекс */

return USART_RxBuf[tmptail]; /* Вернутьданные */

unsigned char DatalnReceiveBuffer( void )

{

return ( USART_RxHead != USART_RxTail ); /* ВозвращаетОеслибуфферпуст */

}

/* Обработчикпрерыванияотприемника */ #pragma vector=USART_RXC_vect _interrupt void USART_RX_interrupt( void ) {

unsigned char data;

unsigned char tmphead;

/* Прочестьполученныеданные */

data = UDR;

/* Рассчетновогоиндекса */

tmphead = ( USARTJRxHead + 1 };

USART_RxHead = tmphead; /* СохранитьновыйиндексV

if ( tmphead == USART_RxTail ) (

/* Ошибка! Буфферприемникапереполнен */

}

USART_RxBuf[tmphead] = data; /* Сохранитьполученныеданныевбуффере */ }

// Процедураинициализациитаймера

voidJnitTimer(void)

{

disable_interrupt();

TCCRO = 5;// timerO counts elk/1024

TIMSK |= M « TOIEO); //Enable TimerO Interrupt TCWTO = TmrO_Reload; TmrOFlag = 0;

enable_interrupt(};

}

/* Обработчикпрерыванияоттаймера */ tfpragma vector=TIMERO_OVF_vect

interrupt void TIMERO_OVF_interrupt(void)

(

TCNTO=TmrO_Reload;

TmrOFlag =1; }

void InitPortARead(void) {

DDRA = 0;

PORTA = Oxff; }

void InitPortAWrite(void) {

DDRA = Oxff; }

void InitPortCWrite(void) I

DDRC = Oxff;

PORTC = 0x30; }

void InitLCD(void) {

int tmp = 0;

Send2ByteComraand(tm.p, ET_TEXT_HOME_ADDRESS_COMMAND);

tmp = 0x14;

Send2ByteCommand(tmp, SET_TEXT_AREA_COMMAND);

tmp = 0x80;

CoromandWrite(INTERNAL_CG_ROM_MODE);

CommandWrite{TEXT_ON_GRAPHIC_OFF);

I

void InitAVR(void)

I

InitPortAWriteO ;

InitPortCWriteO ;

InitLCDO;

InitTimer();

USART_Init( 47 };//Установитьчастоту 9,600 используя1.3728MHz кристалл

}

// Процедурыдляработыс LCD-дисплеемvoid DataWrite(BYTE Data)

t

PINC = DATA_WRITE_COMMAND;

PIНА~ Data; }

void CommandWrite(BYTE Command)

f

PINC = CCMMRND_WRITE_COMMAND;

Р1ЫА = Command; J

void ReadStatus(void) {

BYTE tempFlag = 0; BYTE stat; InitPortAReadO ; while(tempFlag != 1) (

PINC = READ_STATUS_COMMAND;

Stat = PIMH.;

if((stat 0x03) == 0x03) tempFlag = 1; }

InitPortAWriteO }

void ReadStatusS(void)

{

BYTE tempFlag = 0; BYTE stat; InitPortAReadO; while(tempFlag != 1) {

PINC = READ_STATUS_COMMAND;

stat = PINA;

if((stat b 0x08) == 0x08) tempFlag = 1; }

InitPortAWriteO }

void SendCommandfBYTE Command)

i

ReadStatus{); WriteCommand(Command); }

void SendlByteCommandfBYTE Data, BYTE Command) {

ReadStatus();

DataWrite(Data);

ReadStatus{);

CommandWrite(Command); }

void Send2ByteCommand{WORD Data, BYTE Command) {

ReadStatus();

DataWrite((BYTE)Data);

ReadStatus();

DataHrite((BYTE)(Data » 8));

ReadStatus ();

CommandWrite(Command); }

// Position: младшийбайт - координатаX (отOOhдо 4Fh)

//старшийбайт - координатаY (отOOhдоIFh)

void SetCursorPointer(WORD Position)

{

Send2ByteComnand(Positon, SET_CURSOR_COMMAND);

// Address: младшийбайт

//старшийбайт

void SetAddressPointer(WORD Address)

{

Serid2BytesCommand[Address, ST_ADDRESS_COMMAND);

}

void ByteWriteToRamfWORD AddressPointer, BYTE Data)

(

SetAddressPointer(AddressPointer);

ReadStatus();

DataWrite (Data) ,-

ReadStatus();

DataWrite(DATAJWRITEjLNC_ADP); }

void AutoWrite(BYTE Data) (

ReadStatus2();

PINA = Data;

}

// МассивсимволовOutStringдолженбытьобъявленкак

// глобальныймассивтипа BYTE

WORD AutoWriteModefWORD Address, BYTE NumBytes)

I

SetAddressPointer(Address);

SendCommand(SET_DATA_AUTO_WRITE_COMMRND);

for(int i = 0; i NumBytes; i++) {

AutoWrite(OutString[i]);

Address++; }

SendCommand (AUTO_RESET_CCMMAND) ; return Address;

}



Скачать архив с текстом документа