Связь с ПК

Учим общаться МК и ПК.

Программы будем в основном писать на ассемблере под AVR Studio 4 , т.к. для несложных примеров, он лучше отображает работу МК.

Для данной работы нам понадобится комплект из отладочной и интерфейсной платы, а так же потенциометр, в качестве которого будет применен переменный резистор 20 кОм.

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

Для работы с виртуальным COM портом (вроде именно такой создает FT232RL) нам потребуется приложение под Windows. Благо COM порт существует уже давно и это очень любимый порт почти всех электронщиков, значит мучиться с написанием собственной библиотеки, или класса для работы с ним, нам не придется. Пойдем по пути наименьшего сопротивления, взяв класс, написанный на Delphi Игорем  Павловым, который можно в оригинале найти тут .

Нам для удобства, нужно разместить на форме три баттона и два эдитбокса обозвав их:

btnOpenClick – открыть порт

btnCloseClick – закрыть порт

btnWriteClick – записать в порт

edtWrite – то, что будем отправлять в порт

edtRead – сюда будем выводить полученное

Из всего когда, написанного Павловым, нам понадобится изменить только одну процедуру TForm1.OnRead, что бы она выглядела таким образом:

procedure TForm1.OnRead(Sender: TObject; ReadBytes: array of Byte);

begin

edtRead.Text:=IntToHex(ReadBytes[i], 2);

end;

Данная процедура, выводит  полученный ОДИН БАЙТ в edtRead в шестнадцатеричном виде, для наших экспериментов -самое то!

Дальше, надо залить прошивку в наш МК, но какую? Да самую простую!


RESET:	LDI R16,HIGH(RAMEND)
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT SPL,R16
LDI R16,(1<<refs0)|(1<<adlar)
OUT ADMUX,R16
LDI R16,(1<<aden)|(1<<adie)|(1<<adsc)|(1<<adfr)|(7<<adps0)
OUT ADCSRA,R16
LDI R16,(1<<txen)|(1<<rxen)
OUT UCSRB,R16
LDI R16,12
OUT UBRRL,R16

MAIN:	NOP
RJMP MAIN

; Обработка прерывания по завершению Аналого-Цифрового преобразования
ADC_I:	IN	R16,ADCH
CP R16,R17
BREQ PC+3
MOV R17,R16
RCALL SEND
RETI

; Отправляем в UART
SEND:	SBIS UCSRA,UDRE ; Отправляем в UART
RJMP SEND // Отправляем в UART
OUT UDR,R16
RET

А теперь устроим разбор полетов! Начнем с начала. Нам нужно запрограммировать UART на МК, для работы с ПК. По скольку мы решили (временно) отказаться от кварцевого резонатора, значит будем рассчитывать скорость передачи по UART для частоты один мегагерц. Открываем страницу 159, даташита на Atmega8 и ищем нашу частоту и выбираем скорость , по наименьшему проценту ошибки. Выбрали скорость равную 4800 бод, значит делитель UBRR у нас получился 12. Для полноценной работы UART нам остается только сконфигурировать вывода МК PD0 в RX , а PD1 в TX. С UART Закончили, получилось вот что:


LDI R16,(1<<txen)|(1<<rxen)
OUT UCSRB,R16
LDI R16,12
OUT UBRRL,R16

Дальше нам надо сконфигурировать АЦП, тут немного сложнее, нам понадобится запрограммровать биты:

 ADEN: ADC Enable

ADSC: ADC Start Conversion

ADFR: ADC Free Running Select

ADIE: ADC Interrupt Enable

ADPS2:0: ADC Prescaler Select Bits

Выходит, что это почти все, т.е. все, которые можно запрограммровать в регистре ADCSRA. Из перевода, можно понять для чего нужны все эти биты, по этому остановлюсь только на важных. Бит ADFR нужен для постоянной работы АЦП, если его не запрограммировать, то АЦП после выполнения своей задачи самоотключится и запускать его придется программированием бита ADSC, что бы этого не делать, мы используем бит ADFR. Следующие биты, это  ADPS2:0, отвечающие за делитель частоты кварца, для генерации тактирования АЦП. Тут есть небольшая особенность, АЦП будет работать только от частоты 50-200 килогерц, а у нас аж мегагерц. по этому мы будем делить частоту кварца! Открываем 209 страницу даташита на Atmega8 и смотрим какой делитель нам подходит. а подходит нам любой, который больше пяти, т.к. 1000000/200=5, но мы не будем замарачиваться и поставим все 128 .пускай он реже дергает нас на прерывание ;)

Следующее что надо запрограммировать в АЦП,  это два бита в регистре ADMUX. REFS1:0 отвечают за вход опорного напряжения, ну нам в принципе по…все ровно, по этому надо брать с AVCC, а значит надо поставить единичку в REFS0. По скольку у нас десяти разрядный АЦП, то у нас есть младший байт и старший байт. По правильному, Старший байт у нас должен занимать всего два бита, а младший восемь бит. Но у нас же восьмиразрядный МК, нам не удобно, да и не нужно десять бит, значит нам надо запрограммровать бит ADLAR в едницу, что бы старший байт заполнялся полностью ( все 8 бит), а младший оставшимся двумя,  которые мы спишим как “шум”. Получим вот это:


LDI R16,(1<<refs0)|(1<<adlar)
OUT ADMUX,R16
LDI R16,(1<<aden)|(1<<adie)|(1<<adsc)|(1<<adfr)|(7<<adps0)
OUT ADCSRA,R16

Остается только описать обработчик прерывания по завершению преобразования АЦП и передать его  в UART. Тут мы чуть-чуть схитрим, нам ведь не надо постоянно слать в COM порт всякий мусор, вдруг мы захотим за место этого что то другое передать!? по этому мы сравним “свежий” замер с предыдущий и отправим замер в UART только в том случае, если они разные.


ADC_I:	IN	R16,ADCH
CP R16,R17
BREQ PC+3
MOV R17,R16
RCALL SEND
RETI

SEND:	SBIS UCSRA,UDRE
RJMP SEND
OUT UDR,R16
RET

Ну вот и все, теперь можно писать протокол для управления МК с компьютера, или наоборот.

Скачать Исходник

Запись опубликована в рубрике Atmega с метками , , . Добавьте в закладки постоянную ссылку.

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>