Здравствуйте хочу поделится опытом! Итак для того чтобы передать любой массив данных и обработать его в ядре микроконтроллёра необходимо создать протокол обмена. Что это такое. Это взаимодействие двух приложений по определённым правилам. Первая программа это терминальное окно на компьютере. В которое пишут сообщения в виде пакета данных. Пример: #kmr01%. Это сообщение(пакет) состоит из 7 символов в ASCII. Суть заключается в следующем. Этот пакет имеет формат. Это первый символ '#' и последний '%'.(Символы можно брать произвольные кроме тех, что внутри пакета). Итак внутри пакета находится тело сообщения. Его размер желательно брать не большим. В этом примере второй символ 'k' указывает, что это команда. Третий 'm'- работа с памятью. И четвертый 'r' - чтение из памяти. А два последний символа '01' - это собственно адрес той ячейки памяти которую мы хотим прочитать. Так вот когда такое сообщение приходит в микроконтроллер. Оно (тело сообщения без символов '#' и '%') помещается в буфер приёма сообщения. После чего выставляется признак(флаг), что сообщение пришло. И другая подпрограмма начинает обрабатывать это сообщение. Есть один момент при обработке тела сообщения это адрес '01' он передан в ASCII. Железяка ASCII не понимает. Нужен переводчик из ASCII в BIN(бинарный код). Пример процедуры преобразования для PIC контроллёров.
;Подпрограмма преобразования ASCII в BIN. ASCII_BIN: movfw R5 ;Считываем старшый байт для обработки movwf R7
movfw R6 ;Считываем младший байт для обработки movwf R8
movlw 0x41 ;Это >= A? subwf R5,f btfsc STATUS,C goto $+4 movlw 0x30 ;НЕТ - вычтем 30 subwf R7,f goto $+3 movlw 0x37 ;ДА - вычтем 37 subwf R7,f swapf R7 ;Переносим в старшую тетраду
movlw 0x41 ;Это >= A? subwf R6,f btfsc STATUS,C goto $+4 movlw 0x30 ;НЕТ - вычтем 30 subwf R8,w goto $+3 movlw 0x37 ;ДА - вычтем 37 subwf R8,w iorwf R7,w ;Результат преобразования в аккумуляторе return
пример кода для AVR микроконтроллёров.
;Подпрограмма преобразования ASCII в BIN. ASCII_BIN: cpi temp0,'A' ;Это >='A'? brsh PC+3 subi temp0,0x30 ;НЕТ - вычтем 0x30 rjmp PC+2 subi temp0,0x37 ;ДА - вычтем 0x37 swap temp0
cpi temp1,'A' ;Это >='A'? brsh PC+3 subi temp1,0x30 ;НЕТ - вычтем 0x30 rjmp PC+2 subi temp1,0x37 ;ДА - вычтем 0x37
or temp0,temp1 ;Результат в temp0 ret
Суть преобразования из ASCII и BIN такова. Допустим нам надо перевести '01' ASCII в '01' BIN. '01' в HEXe это '3031'. Это занимает два байта. А нам нужен один байт но с той же по смыслу информацией '01'. Нам надо получить так, что в HEXe эта информация была представлена не как '3031', а '01'. Для этого необходимо вычесть из каждого байта 30 или 37 в зависимости от информации которую несёт один байт данных. А полученные результаты сгруппировать в один байт.
Дело в том что персональный компьютер не понимает другой формат данных. И для использования терминальных окон или других программ осуществляющих обмен данными по интерфейсам необходимо преобразование одного формата в другой. Тобиш из терминальной программы ми отправляем в формате ASCII. Но эти данные не понятны микроконтроллеру. Поэтому в микроконтроллере легче всего осуществить такое преобразование. А при отправка из микроконтроллера в компьютер необходимо обратное преобразование из бинарного в ASCI.
;Подпрограмма преобразования BIN в ASCII. для PIC микроконтроллеров. BIN_ASCII: movwf R5 ;Дублируем отправляемый байт movwf R6
movlw 0x0F ;Разделим тетрады для подготовки andwf R5,f ;преобразования в ASCII swapf R6 andwf R6,f
movlw 0x0A ;Это >= A? subwf R5,w btfsc STATUS,C goto $+4 movlw 0x30 ;НЕТ - прибавим 30 addwf R5,f goto $+3 movlw 0x37 ;ДА - прибавим 37 addwf R5,f
movfw R6 ;Берём следующюю тетраду
movlw 0x0A ;Это >= A? subwf R6,w btfsc STATUS,C goto $+4 movlw 0x30 ;НЕТ - прибавим 30 addwf R6,f goto $+3 movlw 0x37 ;ДА - прибавим 37 addwf R6,f ;Результат преобразования в R5 и R6
return
;Подпрограмма преобразования BIN в ASCII для AVR микроконтроллеров BIN_ASCII: mov temp1,temp0 ;Дублируем байт swap temp1 andi temp0,0x0F ;Выделяем младшие тетрады andi temp1,0x0F push temp1 ;Прячем в стек
cpi temp0,0x0A ;Это >='A'? brsh PC+4 ldi temp1,0x30 add temp0,temp1 ;НЕТ - прибавим 0x30 rjmp PC+3 ldi temp1,0x37 add temp0,temp1 ;ДА - прибавим 0x37 pop temp1 ;Востанавливаем из стека push temp0 ;Прячем в стек
cpi temp1,0x0A ;Это >='A'? brsh PC+4 ldi temp0,0x30 add temp1,temp0 ;НЕТ - прибавим 0x30 rjmp PC+3 ldi temp0,0x37 add temp1,temp0 ;ДА - прибавим 0x37 pop temp0 ;Востанавливаем из стека ret
Операционная система оперирует числами с формате ANSI и ASCII.А в микроконтроллерах ATmega или PIC которые не работают под операционной системой их ядра не понимает эту кодировку как персональный компьютер. А какую вы передаёте смысловую информацию роли не играет. Главное чтобы она была упакована.
Пример вычисления двух чисел отправленных с персонального компьютера. Допустим на компьютере есть два числа
первое пусть будет - 110000 второе пусть будет - 44000
которые надо передать в микроконтроллер и там к примеру сложить
представим с начало эти числа в таком виде первое 11*10^4 второе 44*10^3
Далее их мантиссы и степени необходимо перевести в HEX, а основания примем как стандартное основание для всех чисел. первое B и 4 второе 2С и 3
Затем эти пять символов(байт) отправляем в микроконтроллер где они преобразуется в бинарное представление и далее программа видит, что степени разные одно равно 4 другое 3. Делим 2С на A при этом увеличиваем степень с 3 до 4. По сути вещей мы сдвинули запятую влево у числа тем самым приравняли степени. Теперь мантиссы можно сложить.
4+B=F
Итак получили результат мантисса F и степень 4
затем преобразуемый результат в ASCII и полученные два байта отправляем на терминальное окно персонального компьютера
мы видим 'F4'
представим в десятичной системе
15*10^4=150000
проверим 44000+110000=154000
погрешность 4000 объясняется тем, что взята маленькая разрядная сетка в 8 бит. Если бы мы взяли 16 то результат был бы точней.
Вот пример организации персонального компьютера с микроконтроллером.
|