PIC. Урок 16. MSSP. SPI. Светодиодный индикатор MAX7219. Часть 1



Вот и настало время нам испытать модуль MSSP в режиме SPI на практике.

Так как мы привыкли делать всё последовательно, то сначала поставим себе задачу попроще: поработать с шиной SPI в режиме ведущего устройства только на передачу. Поэтому я и подобрал такое устройство для подключения к контроллеру, от которого нам данные не нужны и чтобы оно работало только на приём — это светодиодный индикатор на микросхеме MAX7219, являющейся драйвером индикатора. Индикатор имеет 8 разрядов, также за счет наличия микросхемы MAX7219 уникальной возможностью данного индикатора является то, что он может работать в режиме распознавания кодов символов и нам не придётся управлять сегментами каждого индикатора. Мало того, что управление динамической индикацией он также осуществляет самостоятельно.

Немного изучим микросхему MAX7219, открыв на неё техническую документацию.

Вот типовая схема подключения микросхемы MAX7219

 

 

Мы видим, что у данного драйвера есть 8 параллельных выходов для сегментов и также восемь параллельных выходов для разрядов. Также есть контакт для последовательного входа данных, выхода на схеме нет, хотя вообще он у драйвера есть, то есть разработчики сами прекрасно понимают, что мониторить здесь нечего. Также есть вход для выбора микросхемы Chip Select и вход для синхроимупульсов. На 18 ножку Iset мы подтягиваем резистор с шины питания, который рекомендуется впаивать с номиналом 9,53 килоома, тем самым мы устанавливаем пиковый ток для сегментов. Ну и, соответственно, мы подключаем на 19 ножку питание, а на 9 и 4 — общий провод.

Также посмотрим блок-схему микросхемы

 

 

Здесь мы видим внизу 16-битный регистр, 8 младших битов которого являются данными, а следующие 4 бита — адресом для регистров. Также мы видим несколько регистров различного назначения, драйвер сегментов и драйвер разрядов. Видим мы ещё широтно-импульсный модулятор, управляющий интенсивностью свечения и управляемый особым регистром. Существует также интересный регистр — SCAN-LIMIT, который управляет количеством задействованных разрядов.

Интересным является также декодер сегментов, который может сам формировать свечение определённых сегментов в разряде в зависимости от поступившего значения. Раньше, я помню, это называлось дешифратором. Данный декодер можно также отключать, причём его можно для каких-то разрядов включить, а для каких-то — выключить. Возникает вопрос — для чего вообще выключать декодирование? Ответ здесь многогранный. Во-первых, для того, чтобы вывести какие-то особенные замысловатые символы, которых нет в списке кодов. А самое главное то, что при использовании декодера символов мы можем управлять индикатором только с общим катодом, индикатором с общим анодом мы уже управлять не можем, а если декодирование отключить, то уже можно что-то придумать для управления и общими анодами. Ну мы этим заниматься не будем, будем пользоваться декодером.

Также мы должны учитывать, что сдвиговый регистр у микросхемы 16-битный, а у контроллера 8-битный, поэтому слать информацию с контроллера мы будем с помощью двух байтов, отправляемых непрерывно.

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

Поэтому перейдём к проекту.

Проект мы сделаем из проекта урока 14 CCP_PWM и назовем его LED7219.

Откроем наш проект в MPLAB X и начнём с ним работать, выбрав данный проект главным.

Создадим новую библиотеку для работы с драйвером индикатора с помощью создания добавления в проект файлов LED7219.h и LED7219.c следующего содержания:

 

LED7219.h:

 

#ifndef _LED7219_H

#define _LED7219_H

//-----------------------------------------------------

#include <xc.h> // include processor files - each processor file is guarded.

#define _XTAL_FREQ 4000000

//-----------------------------------------------------

//-----------------------------------------------------

#endif /* _LED7219_H */

 

LED7219.c:

 

#include "LED7219.h"

//-----------------------------------------------------

 

Перейдём в файл main.c и подключим там также нашу библиотеку

 

#include "main.h"

#include "LED7219.h"

 

 

Из функции main() удалим полностью весь код, оставив лишь переменную для счётчика и пустой бесконечный цикл

 

void main()

{

  unsigned int i=0;

  while(1)

  {

  }

}

 

Также удалим функцию SetPWM вместе с телом.

Перейдём в файл LED7219.c и добавим там функцию инициализации шины SPI. Я решил добавить инициализацию шины именно в файл библиотеки потому, что данная инициализация для различных подключенных устройств может отличаться

 

//-----------------------------------------------------

void SPI_init(void)

{

}

//-----------------------------------------------------

 

Посмотрим в документации на микросхему, какой режим SPI она поддерживает, а также скорость. Режим дан вкратце в описании ножки цифрового входа

 

 

То есть данные микросхема читает по восходящему фронту на ножке CLK.

Скорость передачи данный по SPI у микросхемы максимальная вот такая

 

 

Данную скорость мы уж точно не превысим.

Продолжим писать тело функции.

Сначала настроим ножки

 

void SPI_init(void)

{

  TRISC|=0x10; //MISO IN

  TRISC&=~0X28; //MOSI,SCK OUT

  TRISA&=~0X20; //SS OUT

  PORTA&=~0X20; //SS 0

 

Уровень ножки SS мы настроили сразу на низкий, чтобы микросхема сразу была выбрана.

 

 

Затем настроим регистры SSPCON и SSPSTAT на соответствующий режим работы

 

PORTA&=~0X20; //SS 0

// SSPM3:SSPM0 = 0000 (SPI Master mode, clock = 1 MHz)

// SKE=0, SKP=0 (SPI_MODE0)

// SMP=1 (Input data sampled at end of data output time)

// SSPEN= 1 (SPI Enabled)

SSPCON=0x30;

SSPSTAT=0x80;

 

Что и как мы включили, я описал в комментарии. Ножку MISO мы все равно включили, хотя использовать мы её не будем.

Выше добавим функцию передачи байта в шину

 

//-----------------------------------------------------

void SPI_SendByte(char data)

{

  SSPBUF=data;

  while(!SSPIF) ;

  SSPIF=0;

}

//-----------------------------------------------------

 

Здесь также всё понятно, потому что в прошлом уроке я всё это уже объяснил.

Добавим макрос для ножки CS (SS)

 

#include "LED7219.h"

//-----------------------------------------------------

#define cs RA5

//-----------------------------------------------------

 

После функции SPI_SendByte добавим функцию передачи значения в регистр микросхемы. Так как он 16-битный, то мы передаём сразу два байта

 

//-----------------------------------------------------

void Send_7219 (char rg, char dt)

{

  cs=0;

  SPI_SendByte(rg);

  SPI_SendByte(dt);

  cs=1;

}

//-----------------------------------------------------

 

На данную функцию мы создадим прототип в заголовочном файле и вернёмся обратно в наш файл LED7219.c

В самом низу файла добавим функцию инициализации микросхемы, в которой сначала вызовем функцию инициализации шины SPI, включим высокий уровень на ножке SS,и подождём немного, чтобы микросхема нормально вошла в свой режим

 

//-----------------------------------------------------

void LED7219_init(void)

{

  SPI_init();

  cs=1;

  __delay_ms(500);

}

//-----------------------------------------------------

 

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

 

 

Предыдущий урок Программирование МК PIC Следующая часть

 

 

Купить программатор (неоригинальный) можно здесь: PICKit3

Купить программатор (оригинальный) можно здесь: PICKit3 original

Отладочную плату PIC Open18F4520-16F877A можно приобрести здесь: PIC Open18F4520-16F877A

Логический анализатор 16 каналов можно приобрести здесь

Индикатор светодиодный семиразрядный с драйвером MAX7219

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

PIC MSSP. SPI. Светодиодный индикатор MAX7219

2 комментария на “PIC. Урок 16. MSSP. SPI. Светодиодный индикатор MAX7219. Часть 1
  1. Алексей:

    У вас есть небольшая ошибка в комментарии: // СKP=0,но бит в регистре выставлен правильно
    т.е. в еденицу (SSPCON=0x30;)

    • Алексей:

      Все разобрался.Пытался включить каскадом четыре микросхемы,но используя ваш код странным образом работала
      только самая первая,хотя данные проталкивал на всю длину строк(по 8 байт за раз).Проблема оказалась в том
      что согласно даташита на MAX7219 — пассивный уровень SCK-низкий,а увас в примере — высокий.Поэтому зна-
      чения битов должны быть CKP=0, CKE=1.Так будет правильно.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*