Логотип

Если Вы хотите обучаться программированию микроконтроллеров, но попали, сюда не прочитав предыдущих уроков, то советую начать изучение материала с самого начала.

Программирование микроконтроллеров. Урок 17
Интерфейс SPI, подключение дисплея Nokia 5110.

Урок 17 (Интерфейс SPI, подключение дисплея Nokia 5110.)

На прошлом занятии мы с вами научились пользоваться прерываниями и разобрали работу таймера/счетчика Т0. А сегодня мы разберем как работает интерфейс SPI и подключим к нашему контроллеру небольшой ЖК дисплей.

В микроконтроллерах семейства Mega имеются три интерфейса с помощью которых его можно подключать к различной периферии, микропроцессорным устройствам или компьютерам. UATR/USART – в основном используют для соединения с компьютерами, TWI – используют для объединения большого количества разных устройств с целью их совместной работы. Ну и остается еще последовательный периферийный интерфейс SPI который используют для управления другими контроллерами или периферийными устройствами.

Полную структурную схему модуля SPI можно посмотреть в даташите, но если ее сильно упростить, то останется только сдвиговые регистры, тактовый и управляющий сигналы.

Обмен данными по SPI

Обмен данными по SPI

На схеме показан один из вариантов обмена данными между двумя микроконтроллерами. Обмен данными по SPI происходит одновременно в обоих направлениях как от ведущего (Master) устройства к ведомому (Slave), так и обратно с помощью сдвиговых восьмибитовых регистров по линиям MISO (ведущий вход, ведомый выход) и MOSI (ведущий выход, ведомый вход). Сдвиги происходят в устройствах одновременно в такт управляющему сигналу SCK генерируемому ведущим микроконтроллером. В результате передачи сдвиговые регистры обмениваются своими данными. Все легко и просто, но есть нюансы. Линия SS (Slave Select) очень важна для ведомых устройств. Когда на ней низкий потенциал, ведомое устройство готово к приему/передачи, а когда высокий потенциал устройство позволяет производить необходимые действия со сдвиговым регистром. Например, чтение или запись новых данных. Еще раз. Запись данных для передачи в сдвиговый регистр ведомого микроконтроллера возможна только при высоком потенциале на линии SS, а передача данных только при низком потенциале на этой линии. У ведущего МК работа линии SS определяется пользователем и должна работать как линяя вывода общего назначения. Если ведомых устройств больше одного, то у ведущего МК линий управления должно быть столько, сколько устройств к нему подключено (последовательное подключение ведомых устройств мы сейчас не рассматриваем).

Для управления и контроля работы модуля отведено три регистра: SPCR, SPSR и SPDR.

SPDR – регистр данных для записи передаваемых/принимаемых данных.

SPSR – регистр состояния модуля:
      0 разряд (SPI2X) – удвоение скорости обмена. Актуален только для ведущего контроллера. Установка «1» удваивает частоту SCK;
      6 разряд (WCOL) – флаг конфликта записи. Устанавливает «1» в случае попытки записи в регистр данных во время процесса приема/передачи данных;
      7 разряд (SPIF) – флаг прерывания от SPI. Флаг устанавливается «1» по окончании процесса передачи данных, а также при переводе МК в режим ведомого с помощью лини SS.

SPCR – регистр управления SPI:
      0, 1 разряды (SPR1 и SPR2) – управление скоростью передачи;
      2 разряд (CPHA) – Фаза тактового сигнала. «0» - запись принимаемых данных происходит по переднему фронту тактового сигнала SCK. «1» - запись данных происходит по заднему фронту SCK;
      3 разряд (CPOL) – Полярность тактового сигнала. «0» - перед началом тактирования на выводе CSK будет низкий уровень. «1» - перед началом тактирования на выводе CSK будет высокий уровень;
      4 разряд (MSTR) – выбор режима работы. «1» – Master, «0» – Slave;
      5 разряд (DORD) – Порядок передачи данных. «1» - первым передается младший бит, «0» - старший бит;
      6 разряд (SPE) – «1» - включение, «0» - выключение модуля SPI;
      7 разряд (SPIE) – «1» - разрешение, «0» - запрещение прерывания от SPI.

Перед тем как мы рассмотрим алгоритм работы модуля необходимо сказать еще пару слов о нюансах его работы. Во-первых, при включении модуля некоторые выводы МК автоматически переходят в состояние «вход». В режиме «Ведущий» это выход MISO, а в режиме «Ведомый» MOSI, CSK, SS. И если в режиме «Ведомый» всё логично, то в режиме «Ведущий» в случае если вам не нужно принимать данные от ведомого МК, использовать вывод MISО (PB3) в качестве вывода общего назначения становится затруднительно. Во-вторых, и это касается больше режима «Ведомый», при работе с модулем SPI необходимо самостоятельно настраивать работу подтягивающих резисторов для всех выводов модуля.

Теперь перейдем непосредственно к работе модуля. Перед началом передачи/приема данных необходимо разрешить работу модуля установив «1» в разряд SPE. А также настроить работу модуля определив значения в разрядах регистра SPCR. Если выводы МК не используются кроме как для работы модуля, то настройку SPI можно провести всего один раз при инициализации МК в начале его работы. При необходимости передачи данных ведущему на линии SS необходимо установить «0» после чего записать передаваемое число в регистр SPDR. Как только в регистр SPDR будет помещено число автоматически запускается генератор тактовых импульсов и произойдет передача данных. По окончании передачи поднимается флаг SPIF регистра SPSR. После чего можно извлечь переданные данные из регистра SPDR или записать в него новые данные для пересылки.

Более подробный разбор работы SPI можно посмотреть по этим ссылкам (Интерфейс SPI), (Atmega8 интерфейс SPI).

Ну а теперь давайте применим полученные знания о работе SPI на практике и подключим к нашему МК дисплей Nokia_5110. Описание к нему я надеюсь вы уже изучили, а значит можно переходить непосредственно к подключению.

Здесь я коснусь подключения дисплея вкратце, а более полную информацию можно получить, почитав статьи «Подключение LСD дисплея Nokia 5110 к микроконтроллеру ATmega8.», а также «Подключение LСD дисплея Nokia 5110 к микроконтроллеру ATtiny25».

Схема подключения lcd_nokia_5110

Схема подключения lcd_nokia_5110

Ничего сложного при подключении дисплея к МК нет. Для подсветки используем имеющийся у нас транзистор кт815 и сопротивления близкие по значению. В виду того, что этот дисплей будет с нами до окончания курса, то лучше его расположить так как сделал это я. Таким образом он не будет мешать дальнейшей работе.

Расположение nokia_5110 на макетной плате Расположение nokia_5110 на макетной плате

Расположение nokia_5110 на макетной плате

Расположение nokia_5110 на макетной плате

Так как мы подсоединяем дисплей по упрощенной схеме то линия MISО и SS нам не нужны. С другой стороны, для управления дисплеем необходимо организовать линию сброса RESET и линую данные/команда D/C. Для сброса мы используем линию SS (PB2), а для определения передаваемых данных линию PB1. Необходимая библиотека для работы с этим дисплеем находится в приложенных файлах (Lib_Nokia_5110_ATmega.c). Ее необходимо использовать с библиотекой основных макросов (lib_macro.c).

Отдельно хотелось бы остановиться на основной подпрограмме пересылки данных из МК в дисплей. Из-за того, что этот дисплей не использует все возможности SPI, а только ту часть, которая отвечает за прием данных от МК, то и подпрограмма пересылки будет усеченной. К тому же в нее включен элемент управления, который указывает дисплею как распорядиться входящими в него данными.

//Подпрограмма пересылки данных через SPI для дисплея nokia_5110
	void send_data (unsigned char data, unsigned char dc){
		LCD_PORT.LCD_DC = dc;		//Устанавливаем флаг данные/команда
		SPDR = data;			//записываем в регистр данные для передачи
		while (!(SPSR & (1<<SPIF)));	//Ждем завершение передачи данных
	}//END Подпрограмма пересылки данных через SPI

В подпрограмму мы отправляем два байта. Первый это данные для пересылки (data), а второй статус данных (dc). После чего мы, устанавливая на выводе МК статус передаваемых данных (0) – команда, (1) – дата, указывая дисплею как интерпретировать пересылаемые данные. Да. Если вы пользуетесь средой разработки, которая не понимает прямое обращение к биту порта, то строку

LCD_PORT.LCD_DC = dc;

Необходимо заменить на

if (ds) LSD_PORT |= (1<<LSD_DC);
else LSD_PORT &= ~(1<<LSD_DC);

После того как мы установили статус передаваемых данных, в регистр SPDR записываем данные для пересылки. Как только данные попали в регистр. Автоматически включается генератор и происходит передача данных. Передача данных происходит с частотой меньшей чем частота работы МК и для того, чтобы данные прошли без проблем последней строчкой мы ждем поднятия флага прерывания от SPI. Он будет означать, что данные переданы и интерфейс готов к приему новых данных для дальнейшей работы.

Теперь, давайте напишем простенькую программу, которая выведет на дисплее небольшую полоску. Которая будет означать, что данные были успешно переданы по SPI из МК в дисплей.

#include 
//Общие макросы
#include "lib_macro.c"
#define DATA 255 	//данные для заполнения линии
#define MAX_LINE 80 	//Длинна отображаемой линии
//Процедуры и функции
#include "Lib_Nokia_5110_ATmega.c"

void main(void)
{
	unsigned char temp;	//инициализация переменной
	lcd_init();		//инициализация дисплея
	//Рисуем полоску
	for (temp=ZERO;temp<MAX_LINE;temp++) {
		send_data (DATA, LCD_DAT); //пересылка данных
	};
	LED_ON;			//включаем светодиод
while (1) {}
} //END void main(void)

Если вы все сделали правильно, то должна включиться подсветка, а на дисплее должна отобразиться вот такая картинка.

Работа подключенного дисплея

Работа подключенного дисплея

Ну вот, как в песни поется – «всё просто и легко в этом мире». Безусловно, что интерфейс SPI хранит в себе много нюансов с которыми вы, будете разбираться во время своих экспериментов, но на данный момент программа минимум выполнена.

Возможно, что с первого раза у вас не отобразиться ничего на экране. Не отчаивайтесь. Поиграйтесь с настройками дисплея. Такими как: Смещение напряжения и Генератор повышенного напряжения.

К следующему уроку необходимо достать ручной энкодер и парочку сопротивлений на 10 кОм. Про энкодер надо будет найти информацию в сети и изучить их классификацию и режимы работы.

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


А на сегодня всё. Удачи.


17.06.19



Если вдруг найдете в статье неточности или заблуждения. Напишите мне об этом. Я подправлю.



Приложение:
Библиотека Lib_Nokia_5110_ATmega.c
Программа к уроку 17