Мен бірнеше жыл бұрын жасаған TWI интерфейсі бар аппараттық құралдағы біршама хардкорды есіме түсірдім. Кім не айтса да, Ассемблер сананы тазарту және алгоритмдер туралы түсінікті дамыту үшін тамаша. Assembler бағдарламасында AVR микроконтроллерлерімен жұмыс істеу барысында мен үйренген ең маңызды нәрсе - барлық операциялар, барлық директивалар, барлық функциялар нақты реттілікпен жазылуы керек. Ақыр соңында, егер сіз тізілімге деректерді қате ретпен жазсаңыз, онда контроллер микробағдарламасы мүлдем жұмыс істемейді. Бағдарлама кодын жоғары деңгейлі тілдерде жазғанда, кейде сіз функциялар мен әдістерді шақыру тізбегінде толық немқұрайлылықты көре аласыз, дегенмен кітапханаларға арналған нұсқауларды жиі оқуға болады, ол үшін сол немесе басқа функционалдылықты қандай ретпен инициализациялау керек. жұмыс істеу үшін бәрі. Бірақ оларды кім мұқият оқиды? Егер сіз, құрметті оқырман, осы абзацты оқып шықсаңыз және төменде келтірілген кітапхананың бағдарламалық кодын бірден көшіріп-қоймасаңыз.
TWI интерфейс
Схема ішіндегі интерфейстің бұл түрі 1980 жылдары Philips жасаған I2C интерфейсіне ұқсас. Бұл интерфейс Atmega микроконтроллерлері үшін аппараттық модуль ретінде пайдаланылады және басқа құрылғылар пайдаланатын I2C шинасымен жұмыс істеуді айтарлықтай жеңілдетеді. I2C атауынан басқа атау патенттік құқықтың нәтижесі болып табылады.
I2C шинасы сияқты, TWI интерфейсі де екі екі бағытты байланыс желісі арқылы жұмыс істейді: SDA (ағылшынша сериялық деректер) және SCL (ағылшынша сериялық сағат). Екі байланыс желісі де тізбекте резисторлар арқылы қуат көзіне тартылады, ол әдетте +5 және +3,3 вольтты құрайды. Классикалық нұсқадағы мекенжай кеңістігі 128 мекенжайды, кеңейтілген стандартты 1024 мекенжайды құрайды.
Интерфейс жұмысын құрайтын шинада мағыналы күйлердің төрт түрі бар:
- БАСТАУ - SDA жолының күйін 1-ден 0-ге өзгерту, SCL күйін 1-де өзгерту
- STOP - SDA сызығының күйін 0-ден 1-ге өзгерту, SCL күйін 1-ге өзгерту
- Тасымалдау биті 1-ге тең - SDA 1 күйінде, SCL 0-1-0 күйін өзгертеді
- Тасымалдау биті 0-ге тең - SDA 1 күйінде, SCL 0-1-0 күйін өзгертеді
SDA күйін SCL 1-ге тең өзгерту ешқандай рөл атқармайды және еленбейді.
TWI автобусы Master-Slave принципі бойынша жұмыс істейді. Хост бастапқы хабарды жібереді, содан кейін ол бір байтты ақпаратты жібере бастайды. Құл ақпаратты алғаннан кейін, ол растау битін жібереді. Деректерді тасымалдаудың соңы тоқтату хабарламасымен анықталады.
TWI интерфейсімен жұмыс істеуге арналған кітапхана
Бұл мақала Atmega48 , Atmega88 , Atmega168 , Atmega328 микроконтроллерлеріне арналған TWI интерфейсімен жұмыс істеуге арналған кітапхананы ұсынады. Кітапхананы TWI интерфейсі бар басқа Atmega микроконтроллерлерімен жұмыс істеу үшін де пайдалануға болады.
Назар аударыңыз. Әртүрлі үлгілердегі регистрлердің атаулары әртүрлі болуы мүмкін.
/* * i2c\_lib.asm * * Библиотека процедур для шины i2c (Atmega48) * Библиотека предназначена для использования в качестве подключаемого модуля * к другим проектам. * * Библиотека работает с интерфейсом TWI в avr микроконтроллерах * * Библиотека работает с регистром r16 * * Created: 15.07.2013 23:51:32 * Author: Евгений Легоцкой */ ;======= Стартовая посылка по шине i2c ================================================= i2c\_start: push r16 ldi r16,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) ; Выполняем посылку стартовой комбинации sts TWCR,r16 ; Посылаем полученный байт в TWCR rcall i2c\_wait ; Ожидание формирования start в блоке TWI pop r16 ; Возвращаем данные в r16 из стека ret ;======= Стоповая посылка по шине i2c ================================================== i2c\_stop: push r16 ldi r16,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) ; Отправляем стоповую посылку sts TWCR,r16 ; Посылаем полученный байт в TWCR pop r16 ; Возвращаем данные в r16 из стека ret ;======= Посылка байта информации по шине i2c ========================================== i2c\_send: push r16 sts TWDR,r16 ; Записываем передаваемый байт в регистр TWDR ldi r16,(1<<TWINT)|(1<<TWEN) ; Формируем байт, отвечающий ; за пересылку информационного байта sts TWCR,r16 ; Посылаем полученный байт в TWCR rcall i2c\_wait ; Ожидание окончания пересылки байта pop r16 ; Возвращаем данные в r16 из стека ret ;======= Приём информационного байта по шине i2c ======================================= i2c\_receive: ; Принятый байт помещается в регистр r16, поэтому рекомендуется ; продумать программу так, чтобы в этот момент в нём не было ; важной информации, байт не сохраняется в стеке в коде данной ; процедуры ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWEA) ; Формируем байт, отвечающий за прием sts TWCR,r16 ; Посылаем полученный байт в TWCR rcall i2c\_wait ; Ожидание окончания приёма байта lds r16,TWDR ; Считываем полученную информацию из TWDR ret ;======= Приём последнего байта (NACK) ================================================= i2c\_receive\_last: ; Принятый байт помещается в регистр r16, поэтому рекомендуется ; продумать программу так, чтобы в этот момент в нём не было ; важной информации, байт не сохраняется в стеке в коде данной ; процедуры ldi r16,(1<<TWINT)|(1<<TWEN) ; Формируем байт, отвечающий за прием информационного байта sts TWCR,r16 ; Посылаем полученный байт в TWCR rcall i2c\_wait ; Ожидание окончания приёма байта lds r16,TWDR ; Считываем полученную информацию из TWDR ret ;======= Ожидание готовности TWI ======================================================= i2c\_wait: lds r16,TWCR ; Загружаем значение из TWCR в r16 sbrs r16,TWINT ; Функция ожидания выполняется до тех пор, пока поднят флаг ; прерывания в 1 rjmp i2c\_wait ret ;=======================================================================================
Назар аударыңыз. Сондай-ақ, кітапхана жұмыс істеуі үшін Микроконтроллер стекін инициализациялау қажет. Мысалы, келесідей:
;======= Макросы ========================================================================= ; Макрос вывода в порт или регистр .macro outi ldi r16, @1 out @0,R16 .endm ;========================================================================================= RESET: outi SPL,Low(RAMEND) ; Инициализация стека outi SPH,High(RAMEND)