
- •Поехали!
- •Поговори-ка ты со мной..
- •Что то с памятью моей стало память.
- •Пример.
- •Итак, будем удивлять! Для начала необходимо спаять схему управления нагрузкой на 220 вольт.
- •Теперь надо научиться передавать данные через com-порт.
- •Программа для получения текстовых сообщений.
- •Итак. По порядку.
- •Ураа! склад!!!
Программа для получения текстовых сообщений.
Для того чтобы работать с контроллером, не утруждая себя разработкой отдельных приложений в каждой из возможных операционных систем, необходимо применить так называемый терминальный протокол. По виду он напоминает режим работы из командной строки (если ещё кто-то помнит такой). Данные передаются и принимаются в текстовом виде. к примеру если нам нужно передать какое-то число в микроконтроллер, то мы передаем его не "прямиком", а в текстово-шестнадцатеричном виде. К примеру, число 125 мы передадим как его шестнадцатеричное представление 7D.
Такой метод передачи хорош тем, что программа обрабатывающая подобный протокол сама по себе очень проста. Ведь каждая цифра в 16ричной системе - это ровно пол байта. Программе достаточно просто конвертировать каждую цифру в ее значение и затем собрать полученные полубайты в байт.
"7D" |
||||||||
7 |
D |
|||||||
0 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
|
0b01111101 |
В общем программе остается вычислить номер принятого символа из строки "0123456789ABCDEF" и подставив его в нужный полубайт спокойно дожидаться символа <CR> - возврат каретки, который в терминальном режиме означает окончание ввода (клавиша Enter)
Получение номера принятого символа основанно не на поиске в строке (что было бы правильнее) а на обработке кода принятого символа. так символы с "0" по "9" имеют код c $30 по $39 а символы "A".."F" ("a".."f") - $41.. $46 ($61..$66). Получая символ программа убирает старший полубайт принятого символа, и если символ был из буквенного набора (тоесть больше $39) то добавляет к оставшемуся полубайту 9.
Итог "7D" --> $37 $44 ---> $07 $04(+9) ---> $07 $0D --> $7D
в таком виде полученный байт выводится в порт В.
;========================================================== ;Autor: MadMayDay 2008 ;Project: StepByStep ;Name: USART-Port ;========================================================== .device ATtiny2313 .include "tn2313def.inc" .def SlopReg=R16 .def ViewReg=R18 .def HighChar=R19 .def LowChar =R20 .def NextChar=R21 ;========================================================== Start: rjmp Init; ;---------------------------------------------------------- ;устанавливаем часть ног микросхемы в состояние "выход", ;и часть в состояние "вход" ;входы - pin 02,03,06,07,08,09,11 ;выходы - pin 12,13,14,15,16,17,18,19 Init: ldi SlopReg,0b11111111 ; грузим признак выхода out DDRB,SlopReg ; в регистр управления ; портом "B" ldi SlopReg,0b00000010 ; грузим признак входа out DDRD,SlopReg ; в регистр упр. портом "D" ldi SlopReg,0b11111111 ; грузим признак "активности" out PortD,SlopReg ; в регистр входа ;---------------------------------------------------------- ; подготовка приемо передатчика USART ; кроме делителя ничего менять не надо все настроенно на работу с компьютером. ; прерывания не используются. ; вход RXD- PD0(pin2), выход TXD- PD1(pin3) ldi SlopReg,0 ; 19200 бод на частте кварца 8 мегагерц out UBRRh,SlopReg ; Делитель USART = 25 ldi SlopReg,25 ; заливаем в регистр UBRR out UBRRl,SlopReg ; не забывая, что его размер 2 байта ldi SlopReg,0b00000110 ; 8 бит. 1 стоп. без четности out UCSRC,SlopReg ; заливаем в регистр управления UCSRC ldi SlopReg,0b00011000 ; признаки прием и передача разрешена. out UCSRB,SlopReg ; заливаем в регистр управления UCSRB ;---------------------------------------------------------- ; Читаем по одному байту из COM-порта и пытаемся транслировать ; Если принят <CR> то выводим полученное ране значение в порт. ldi ViewReg,$00 ; формируем начальное состояние и out PortB,ViewReg ; отображаем его на «экране» ;---------------------------------------------- NoData: in SlopReg,UCSRA ; Считываем регистр состояния USART bst SlopReg,RXC ; и запоминаем флаг принятости байта. brtc NoData ; если запомненный флаг не установлен ; то, ждем еще раз. ;---------------------------------------------- ; если символ принят, то bst SlopReg,FE ; запоминаем флаг ошибки. in NextChar,UDR ; и считываем принятый байт brts NoData ; если флаг ошибки установлен ; ждем следующий ;---------------------------------------------- cpi NextChar,$0d ; если принятый не <cr> brne StrToInt ; то обрабатываем его как цифру ; иначе (если получен <cr>) DoOut: out PortB,ViewReg ; отображаем на «экране» полученное. rjmp NoData ; и ждем следующей порции ;---------------------------------------------- ;перевод цифры в число StrToInt: mov SlopReg,NextChar ; andi NextChar,$0F ; обрубаем лишние биты sbrc SlopReg,06 ; если символ из А..F subi NextChar,-9 ; прибавляем к его коду 9 lsl ViewReg ; сдвигаем предыдущий полубайт lsl ViewReg ; на полубайт (4 бита) lsl ViewReg ; lsl ViewReg ; or ViewReg,NextChar ; и ставим полученное значение ;---------------------------------------------- rjmp NoData ; и снова здорова. End: ;========================================================== |
Следует заметить что приведенный выше код совсем не защищен от ошибок. Тоесть если мы вместо шестнадцатиричного числа размером в байт пошлем текстовую строку произвольного содержания, то и результат будет произвольный. Однако результат будет однозначно и программа будет продолжать работать штатно.