AVR микроконтролери

Продължаваме да работим сAVR микроконтролери и днес, както обещахме, ще предаваме и получаваме данни през UART интерфейса, използвайки съответнитепрекъсвания. Вече обсъдихме цялата теория в предишната статия (тук), на същото място написахме малък пример за пренос на данни без прекъсвания. Следователно сега имаме пълното право незабавно да се заемем с бизнеса, тоест да напишем програма)

Дори не знам какъв проблем да измисля .. И нека направим това - ще получим данни чрез UART и след това веднага ще ги изпратим обратно. Ако всичко е изпълнено правилно, тогава предадените и получените данни трябва напълно да съвпадат.

Първо, може би, ще дам пълния код на програмата и след това ще обсъдим всичко подробно)

И така, какво виждаме тук? 😉

Първо включваме всички необходими файлове. В случая са само две.

За да конфигурираме UART, имаме нужда от стойност, която трябва да бъде записана в регистъра UBRR0. Нека скоростта е 9600 kB/s. Търсим желаната стойност в листа с данни и дефинираме променливата с дефиниране:

Сега трябва да декларираме всички променливи, от които се нуждаем. И освен това, нека дефинираме типа данни bool:

На тази подготовка може да се счита за завършена)

За да изпратим данни, ще използваме функцията UART_SendData():

Флагът readyToExchange сигнализира края на приемането/предаване. Тоест, след като прехвърлихме всичките си байтове, задаваме този флаг на едно. И, разбира се, трябва да активираме самия трансфер и необходимото прекъсване:

Напишете манипулатор на прекъсвания:

Тук поставяме данните в регистъра UDR0, откъдето те излитат към външния свят. Естествено, ние увеличаваме указателя към данните, за да прехвърлим следващите байтове. Също така увеличаваме променливата на брояча за суматаизпратени байтове. След това проверяваме дали броят на изпратените байтове е равен на броя на байтовете, които трябва да бъдат изпратени. Ако е равно, тогава работата ни е завършена, изпратихме всичко, можете да затворите магазина, тоест да забраните прекъсването:

При получаване на данни ситуацията е приблизително същата, програмата е изградена по подобен начин:

Всичко, което остава, е да започне някак си. Отиваме до функцията main() и виждаме какво имаме там:

Като начало, тук имаме глобално разрешаване на прекъсване и настройка за скорост на предаване. Цялото действие е в нашия цикъл while(1). Извикваме команда за получаване на осем байта данни и изчакваме, докато този процес приключи и флагът readyToExchange лети. След това ние сме малко по-глупави в забавянето, така че приемането най-накрая да приключи и да започнем предаването на масива от данни, който току-що сме получили. Това е всичко )

Остава да се уверите, че всичко работи както трябва. Отворете терминал (между другото, използвамAdvanced Serial Port Monitor ). Прехвърляме 8 байта данни към контролера и той трябва да ни изпрати същите байтове в отговор.

това
Виждаме, че всичко е успешно! Данните съвпадат, програмата работи правилно. Това всъщност е всичко за днес, докато не се срещнем отново на нашия уебсайт!

И колко добре ще работи, ако изпратя втория ред след него. Оказва се, че докато не задам флага readyToExchange на 1, второто съобщение няма да изчезне.

Например, ще има две съобщения void main(void) sei(); UBRR0 = AVR_USART_9600_VALUE;

UART_SendData(“Стартиране на системи”, 8); // Това ще изчезне

UART_SendData("инициализация TWI", 8); - и вече не е.

трябва

Да, така е. При тази опция за изпращане, след извикване на UART_SendData, е необходимо да се анализира флагът за готовност и едва тогава да се започне ново изпращане.

Милден! На стари години попаднах в Avr-ki ... Дяволът ме дръпна))) Не мога да се сприятеля с тези Uarts))) Обяснете на глупавите как да приемат линии с различна дължина? Максимум 38 знака, минимум 3. Последният винаги е „;“ Всъщност първите две са командата, след това параметърът от 1 до 35 знака, последният знак е „;“. „Идентификационен номер на тип“; – заявка, отговор на нея, например „ID090;“ Вече написах цялата обработка с мъка наполовина))) Но тези UART не могат да бъдат победени по никакъв начин. Пълният проблем за uarts е следният: има вграден такъв - той използва едновременно приемане и предаване. И една програма - само за прием. Контролерът трябва постоянно да слуша и двата приемника. От софтуера е тъпо да се изпращат без анализ данни за предаване. От вграденото тук вече тече обработка. Но ако няма нищо на рецепцията известно време (около секунда), тогава трябва да изпратите заявка - четири знака. Въведете „АКО“; Или понякога, ако е необходимо, нещо като „PCxxx;“ Как може да стане това?

микроконтролери

Просто приемайте байт по байт и когато се получи краен знак, деактивирайте предаването.

Честно казано, вече го пробвах. Нищо не ми се получи. Факт е, че например за заявка като „АКО;“ След това трябва да получа IF и още 35 стойности; и от този поток трябва да извадя на различни места първо 5-цифрена десетична стойност, а след това още 2-3 едноцифрени или едносимволни, от пакет с FA или FB- 5-цифрени стойности, използва се на същото място като от "if". тези. от FAxxxXXXXXXxxx; само кой X.))) И ми трябват като цяло десетично число))) Е, поне трябва да обработвате само това, което идва от вградения UART). И тогава има този софтуер))) Просто вече съм обсебен, вероятно) Основите на програмирането се състояха дори преди повече от 30 години) FORTRAN иPL / 1)))) И аз работих с контролери в средата на 90-те)))) Тогава усвоих някои 580BE31 или 8035 за една нощ))) Очевидно мозъците вече са започнали да ръждясват, работят със скърцане))))

данни

Е, основното е да приемете всичко и след това да го обработите отделно, без прекъсване)

Разбирам, че трябва да направя нещо подобно

деклариране на масив uint8 rx_str[];

и след това нещо подобно

< uint8 i=0; докато (UDR!=”;”) rx_str[i]= UDR; i++;> rx_str[i]= UDR; // за да не загубите “;” - всъщност rx_str[i]=”;” върни i; >

тези. попълнете масива и вземете броя знаци, въпреки че всъщност не ми трябва. Той ще бъде обработен само ако има или 14 от тях (първите 2 FA или FB) или 38 (първите два IF), с третото „0“ и последното „;“ Но няма да въвеждам как да подредя всичко правилно))) Добре, няма да ви измъчвам, по-добре е да отидете на риболов за уикенда))))

трябва

Как беше риболовът? =)

Добър вечер! И риболовът беше в делтата на Волга)))) И там винаги е отлично!))) Вълшебна риба вобла)))) Дори калмикските пътища не развалиха целия позитив. Но дисковете ще трябва да бъдат закупени по различен начин - едно колело може просто да бъде изхвърлено - дискът е счупен, наклонът е разкъсан. Но риболовът беше страхотен!))) Моят приятел от Астрахан ни доведе на такива места - чудо! Сега на брега на Волга и нейните „сателити“ - хвърлете камък и ще ударите рибаря и три дни не видяхме много хора)))