Меню сайта
Администрация
579-010-666
Или воспользуйтесь формой обратной связи.
Разделы
Автолюбителям [13]
Таймер NE555 [11]
Конструктор схем [11]
Измерительная аппаратура [5]
Осциллографы [2]
На микрухах [10]
Роботы [0]
Световые эффекты [1]
Термостат [0]
Обучение PIC с нуля [17]
Чат
500
Наш опрос
Оцените мой сайт

Результат опроса Результаты Все опросы нашего сайта Архив опросов

Всего голосовало: 148
Статистика



Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » Статьи » Обучение PIC с нуля

13. Программный I2C
Следующим экспериментом в серии выступает применение протокола передачи I2C. Здесь нет описания самого протокола, этого добра в сети хватает в статье содержится инструкция по установке связи между микроконтроллером PIC16f628a и так называемым «расширителем» портов мк PCA9539.

Итак:

Задача:
Установка связи по протоколу I2C.

Исходный материал: PIC16f628a, PCA9539, devboard.

Вкратце о том, зачем это мне: у меня сейчас на стадии разработки проект часы/термометр, и я выбирал средство индикации для него. Остановился на двух дисплеях: трехразрядный семисегментник и четырехразрядный семисегментник. Для управления ими нужно 8+4+8+3 = 23 бита с нашими 16 портами это нереально. Сначала я думал использовать для этого сдвиговый регистр, но потом мне прилетели халявные образцы от NXP и я решил заюзать их. В данном случае будет использоваться 7+2 = 9 портов, причем 2 порта для шины I2C будут использоваться и для связи с термометром и часами реального времени.

Для начала посмотрим внутрь нашего io expander’a:

Помимо 16 портов здесь присутствует два бита ручного указания адреса, а также вывод прерываний. Фактически, адрес конкретно устройства здесь формируется только двумя битами А0 и А1:

В моем случае я эти биты подтянул на землю, то есть адрес устройства выглядит так:

То есть начало передачи для нашей индикации должно начинаться с такого байта.

Далее должен следовать командный байт, который указывает куда именно собираемся записывать информацию (конфигурационный бит, непосредственно порты и т.д.).

*Цифры ниже приведены в десятичной системе0 Входной порт 0
1 Входной порт 1
2 Выходной порт 0
3 Выходной порт 1
4 Инверсия полярности порта 0
5 Инверсия полярности порта 1
6 Конфигурационный порт 1
7 Конфигурационный порт 2


При работе с данной микросхемой нужно помнить, что регистры всегда работают в паре, то есть если вы пишите в порт 0 данные, то придется их записывать и порт 1, командный бит по сути просто указывает на то, в какой из портов данные будут записываться сначала.

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

Остановимся пока на только на записи в микросхему, с чтением будем разбираться чуть позже. Переходим непосредственно к коду. Здесь главная фишка в том, что мы оперируем не непосредственно состояниями выходов порта, а лишь изменением направления данного порта (ввод/вывод). Поэтому не забываем вначале нашей программы добавлять следующие строки:

#define SCL TRISB6

#define SDA TRISB5

#define SCL_IN RB6

#define SDA_IN RB5

Задержка для тактирования:

void i2c_delay (void)

{

__delay_us(10);

}

Далее процедура старта:

void i2c_start(void) //

{

SCL = 1;

SDA = 1;

i2c_delay();

SDA = 0;

i2c_delay();

SCL = 0;

}



Процедура окончания:

void i2c_stop (void)

{

SDA = 0;

i2c_delay();

SCL = 1;

i2c_delay();

SDA = 1;

i2c_delay();

}



Процедура записи выглядит так:

bit i2c_tx(unsigned char d)

{

char x;

static bit b;

for (x=0; x<8; x++) { //передача 8 бит данных
i2c_delay();
if (d&0x80) SDA = 1;
else SDA = 0;
i2c_delay();
SCL = 1;
d <<= 1;
i2c_delay();
SCL = 0; }
i2c_delay();
i2c_delay();
SDA = 1; //готовимся получить ACK бит
SCL = 1;
i2c_delay();
b = SDA_IN; //получаем ACK бит
SCL = 0;
return b; //Возвращаем значение бита ACK через функцию
}



Итак, для записи в микросхему у нас есть все что нужно. В качестве примера будем выводить двухзначное число на дисплей, которое будет увеличиваться на единицу по нажатию на кнопку. Для вывода на дисплей создадим отдельную функцию:

void dispo(unsigned char temp)

{
unsigned char i = 0;
i = trunc(temp/10);
maj= 0; min =0;
i2c_start();
i2c_tx(0b11101000);
i2c_tx(0b00000010);
i2c_tx(digit[i]);
i2c_tx(digit[i]);
i2c_stop();
maj= 1; min = 0;
__delay_ms(5);
i = temp - (trunc(temp/10)*10);
maj= 0; min = 0;
i2c_start();
i2c_tx(0b11101000);
i2c_tx(0b00000010);
i2c_tx(digit[i]);
i2c_tx(digit[i]);
i2c_stop();
maj= 0; min = 1;
__delay_ms(5);
}



Надо также помнить, что перед записью в порты их нужно сконфигурировать на выход, записав нули в конфигурационные биты. Нажатие на кнопку обрабатывается прерыванием. Результат работы:



Источник: http://diymicro.ru/?p=103
Категория: Обучение PIC с нуля | Добавил: 4ydocactus (04.06.2012)
Просмотров: 2613 | Теги: pic16f628a, SCI, I2C, PIC микроконтроллеры | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Профиль
Суббота
04.05.2024
17:49

Новости сайта
Добавленно новых материалов:
****************************************
1.06.2012
Просьба...
Уважаемые пользователи!
Выделите пожалуйста 1 минуту вашего времени и кликните пару ссылок от рекламы на Google. Тем самым вы потдержите проект.
Спасибо!
Реклама