Метка proc_E0, как и метка ргос_Е2далее, должны располагаться сразу после основного цикла Gcykle(потому что команда rjmpимеет ограниченное пространство действия, см. главу 13 ). Далее, где-то (в конце программы, например) записываем, наконец, собственно процедуру WriteKoeffприема коэффициентов и записи их в память. В ней мы учтем, что коэффициенты нельзя писать сразу в EEPROM, так как запись байта длится дольше, чем его прием через UART, и во избежание их потери необходим некий буфер. Но нам и не нужно его специально изобретать, т. к. коэффициенты все равно дублируются в SRAM, куда мы их первоначально и запишем. Если бы мы этого не сделали, то пришлось бы перезапускать контроллер после записи [15] Кстати, у многих начинающих программистов возникает вопрос — а можно ли перезапустить контроллер программно? Для этого нужно воспользоваться сторожевым таймером — см. главу 17 .
. Сказанное иллюстрирует листинг 16.4.
Листинг 16.4.
WriteKoeff: ;записать коэффициенты +8 байт
cli ;запрещаем прерывания
ldi ZH,1
ldi ZL, tZH ;начальный адрес SRAM
LoopWR:
rcall in_com ;принимаем следующий байт
st Z+,temp ;сложили в SRAM
cpi ZL,pKL+1 ;до адреса pKL ровно 8 байт, см. листинг в Приложении 5
brne LoopWR
;теперь коэффициенты находятся в SRAM, складываем в EEPROM clr ZH
clr ZL ;адрес EEPROM = 0:0
ldi YH,1
ldi YL,tZH ;начальный адрес SRAM
LoopWE:
ld temp,Y+ ;забираем из SRAM
rcall WriteEEP ;переписываем в EEPROM
inc ZL ;следующий адрес
cpi ZL,8
brne LoopWE
ldi temp,$AA ;все Ok, посылаем ответ
rcall out_com
sei ;разрешаем прерывания
ret
Если все благополучно, по окончании процедуры в компьютер будет послан байт со значением $АА. Если такой байт не получен, значит, что-то, например, потерялось по дороге, или произошел еще какой-то сбой.
Процедура чтения коэффициентов вызывается так:
ргос_Е2: ;читать все коэффициенты 8 байт из EEPROM
rcall ReadKoeff
rjmp Gcykle
А собственно процедура чтения (листинг 16.5) будет гораздо короче, т. к. не требуется спешить с приемом байтов и, соответственно, обращаться к SRAM (вообще-то нам безразлично, откуда получать коэффициенты, так что будем читать из оригинала — из EEPROM).
Листинг 16.5
ReadKoeff: ;читать коэффициенты 8 байт из EEPROM
cli
clr ZH
clr ZL
LoopRE:
rcall ReadEEP
rcall out_com
inc ZL
cpi ZL,8 ;счетчик до 8
brne LoopRE
sei
ret
Разобранный нами последовательный порт UART хорош своей изумительной простотой. UART в той или иной форме содержат практически все современные контроллеры, кроме самых простых, вроде семейства Tuny. Эта простота, однако, оборачивается и некоторыми недостатками. Во-первых, UART может работать только с заранее оговоренной скоростью обмена. Это неудобно, когда вы заблаговременно не знаете характеристики линии: при соединении с компьютером на столе можно задавать скорость и 115 200, а при необходимости передачи по километровому кабелю и скорость 9600, которую мы тут выбрали, окажется чересчур высокой (подробнее об этом см. главу 18 ).
Если не брать во внимание способ синхронизации по отдельной линии, как в USART (лишний провод нам ни к чему), то в принципе можно придумать способ, когда устройства соединяются на самой быстрой скорости, на которой это возможно: так, например, работает модем, который со стороны компьютера есть тот же UART, отличающийся только формой передачи сигнала по линии (в нем единицы и нули передаются не уровнями напряжения, а посылками различной частоты или фазы), отчего может работать на значительно больших расстояниях. Не так уж сложно решить и задачу автоопределения на одной стороне скорости обмена, заданной на другой: нужно попробовать соединиться на различных скоростях, и когда заранее оговоренный байт (или их последовательность) будет принят верно, значит, мы достигли нужной скорости.
Можно ли, однако, решить задачу так, чтобы скорость передачи задавалась с одного конца, как в синхронном обмене, но при этом избежать лишнего провода? Оказывается, вполне возможно, если работать на небольших скоростях. Но UART имеет еще один капитальный недостаток: он предназначен только для соединения не более чем двух устройств между собой. Режим мультипроцессорного обмена USART, о котором мы упоминали, есть попытка решить эту проблему, но лучше выстроить сразу такой протокол, при котором несколько устройств могут быть соединены между собой, и без помех обмениваться данными в нужном направлении. Все последовательные интерфейсы, кроме «чистого» UART, построены именно таким образом, включая и SPI, и USB и многие другие. В том числе и протокол I 2С, который мы сейчас и разберем.
Читать дальше
Конец ознакомительного отрывка
Купить книгу