Урок 26
HAL. SPI. Драйвер индикатора MAX7219
Продолжаем заниматься с шиной SPI. На прошлом занятии мы подключили четыре индикатора к двум сдвиговым регистрам и добились управления разрядами.
А сегодня мы также будем управлять многорзрядным индикатором но уже с помощью специализированной микросхемы-драйвера, подключенной также по интерфейсу SPI к микроконтроллеру. Эта микросхема — MAX7219. Данную микросхему изучим только в общих чертах, так как мы её уже глубоко изучили на подобном занятии по AVR, я думаю, повторяться смысла нет. Поэтому сегодняшняя наша цель — научиться управлять данной микросхемой при помощи контроллера STM32. У нас по прежнему та же самая отладочная плата — STM32 F4 Discovery.
Вот схема подключения данной микросхемы к контроллеру
К микросхеме мы подключаем два четырехразрядных индикатора, причем с общим катодом. Причём это не мы подключаем, это всё выполнено в виде отдельного модуля
А вот так на практике выглядит вся схема подключения
Проект создаём из позапрошлого проекта SPI_595_LED, так как там нет никаких таймеров, а они нам и не будут нужны. Называем его LED7219. Файлы led.c и led.h переименовываем соответственно в max7219.c и в max7219.h.
Запускаем Cube. Убавим немного скорость SPI, т.к. в документации к микросхеме стоит 10 МГц
Генерируем и открываем проект в Keil.
Смотрим схему подключения индикаторов.
Переходим в проект. Подключаем файл max7219.c и настраиваем программатор.
Соберём проект.
В main.h и max7219.c исправим подключение файла
#include «led.h»
#include «max7219.h»
Исправим заголовки и уберем дефайлны в файле max7219.h. Останется там вот что
#ifndef MAX7219_H_
#define MAX7219_H_
#include «stm32f4xx_hal.h»
#include «main.h»
#endif /* MAX7219_H_ */
В файле main.c уберём все переменные
/* Private variables ———————————————————*/
#define cs_set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET)
#define cs_reset() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_SET)
#define cs_strob() cs_reset();cs_set()
uint8_t aTxBuffer[1]={0};
/* USER CODE END PV */
Уберем один дефайн из файла max7219.c
#define cs_set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET)
#define cs_reset() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_SET)
#define cs_strob() cs_reset();cs_set()
Вместо portseg добавим другую переменную
uint8_t portseg=0;
char dg=8;
несколько изменим переменную aTxBuffer[1], уберем с нее extern и немного изменим имя
uint8_t aTxBuf[1]={0};
Посмотрим даташит на микросхему max7219 – как передаются данные, какие существуют регистры.
удалим код функции segchar ну или вместо неё сделаем другую функцию
void Send_7219 (uint8_t rg, uint8_t dt)
{
cs_set();
aTxBuf[0]=rg;
HAL_SPI_Transmit (&hspi3, (uint8_t*)aTxBuf, 1, 5000);
aTxBuf[0]=dt;
HAL_SPI_Transmit (&hspi3, (uint8_t*)aTxBuf, 1, 5000);
cs_reset();
}
Сделаем прототип
void Send_7219 (uint8_t rg, uint8_t dt);
Напишем функцию очистки индикатора
//———————————————————
void Clear_7219 (void)
{
uint8_t i=dg;
do
{
Send_7219(i,0xF);//символ пустоты
} while (—i);
}
Напишем функцию вывода числа на индикатор
//———————————————————
void Number_7219(volatile long n)
{
uint8_t ng=0;//переменная для минуса
if(n<0)
{
ng=1;
n*=-1;
}
Clear_7219();
if(n==0)
{
Send_7219(0x01,0);//в первый разряд напишем 0
return;
}
uint8_t i=0;
do
{
Send_7219(++i,n%10);
n/=10;
} while (n);
if (ng)
{
Send_7219(i+1,0xA);//символ —
}
}
Также напишем функцию инициализации микросхемы
//———————————————————
void Init_7219(void)
{
Send_7219(0x09,0xFF);//включим режим декодирования
Send_7219(0x0B,dg-1);//кол-во используемых разрядов
Send_7219(0x0A,0x02);//интенсивность свечения
Send_7219(0x0C,0x01);//включим индикатор
Clear_7219();
}
Напишем прототипы на добавленные функции
void Send_7219 (uint8_t rg, uint8_t dt);
void Init_7219(void);
void Number_7219(volatile long n);
void Clear_7219 (void);
В файле main.c исправим тип переменной-счётчика
uint32_t i=0;
Здесь уберем всё кроме задержки
/* USER CODE BEGIN 2 */
cs_set();
aTxBuffer[0]=0xFF;
HAL_SPI_Transmit (&hspi3, (uint8_t*)aTxBuffer, 1, 5000);
cs_strob();
HAL_Delay(200);
/* USER CODE END 2 */
В бесконечном цикле код пока закомментируем
while (1)
{
// for(i=0;i<=9;i++)
// {
// segchar(i);
// HAL_Delay(1000);
// }
/* USER CODE END WHILE */
После задержки напишем код вывода цифр на дисплей
HAL_Delay(200);
Init_7219();
Send_7219(1,0×01);//1
Send_7219(2,0×02);//2
Send_7219(3,0×03);//3
Send_7219(4,0×04);//4
Send_7219(5,0×05);//5
Send_7219(6,0×06);//6
Send_7219(7,0×07);//7
Send_7219(8,0×08);//8
Затем подождём 2 секунды и попробуем вывести отрицательное число
Send_7219(8,0×08);//8
HAL_Delay(2000);
Clear_7219();
Number_7219(-4356);//попытаемся вывести отрицательное значение
Соберём проект, прошьём контроллер и посмотрим результат
Подождём ещё 2 секунды и очистим дисплей
Number_7219(-4356);//попытаемся вывести отрицательное значение
HAL_Delay(2000);
Clear_7219();
/* USER CODE END 2 */
В бесконечном цикле уберём цикл for, т.к. превысить количество символов индикатора мы физически не сможем, даже если и дождёмся максимального значения типа переменной счётчика. Убавим задержку, код немного также изменим.
while (1)
{
Number_7219(i);
HAL_Delay(200);
i++;
/* USER CODE END WHILE */
Собираем, прошиваем, смотрим
Предыдущий урок Программирование МК STM32 Следующий урок
Техническая документация на микросхему MAX7219
Отладочную плату и светодиодный восьмиразрядный индикатор с драйвером можно приобрести здесь:
Индикатор светодиодный семиразрядный с драйвером MAX7219
Смотреть ВИДЕОУРОК (нажмите на картинку)
Здравствуйте. У меня платка STM32F103C8T6 10 матриц 8х8 на max7219, стоит Keil 5.22. Помогите пожалуйста убрать ошибку, сней вроде всё работает но она меня напрягает сам непойму что сделать надо.
../Src/main.c(26): warning: #1295-D: Deprecated declaration demo_ScrollBuff — give arg types
int demo_ScrollBuff();
../Src/main.c: 1 warning, 0 errors
Проект прилагаю
https://yadi.sk/d/q-IVnMMQ3Mx3v9
Здравствуйте.
Какая у Вас кодировка текста исходных файлов? Я использую Systems Workbench и мой компютер не отображает комментарии на руском языке.
я не пользуюсь кириллицей последнее время.
Спасибо за уроки!
Но имхо в функции:
void Send_7219 (uint8_t rg, uint8_t dt)
{
cs_set();
aTxBuf[0]=rg;
HAL_SPI_Transmit (&hspi3, (uint8_t*)aTxBuf, 1, 5000);
aTxBuf[0]=dt;
HAL_SPI_Transmit (&hspi3, (uint8_t*)aTxBuf, 1, 5000);
cs_reset();
}
надо добавить cs_set(); после cs_reset(); иначе команда не выполниться.
Исходный код, который в архиве от проекта на AVR (не STM).
Повторял проект в Atollic TrueStudio Столкнулся с двумя ошибками при компиляции:
1 в функции очистки индикатора вместо } while (–i); нужно написать } while (i—);
2 в файле MAX7219.c нужно добавить extern SPI_HandleTypeDef hspi2; перед функцией void Send_7219 (uint8_t rg, uint8_t dt)