Введение
Наконец то переделал свою старую библиотеку для семисегментного индикатора. Теперь она более функциональна и позволяет подключать индикатор к произвольным выводам микроконтроллера. Поддержку SPI убрал, чтобы не загромождать код. Если дойдут руки, то сделаю для SPI подключения отдельную библиотеку.
Особенности библиотеки:
- предназначена для микроконтроллеров AVR,
- легко интегрируется в готовый проект,
- может использоваться с компиляторами IAR, GCC, CodeVision,
- поддерживает подключение к произвольным выводам микроконтроллера,
- поддерживает индикаторы с общим катодом и с общим анодом,
- поддерживает подключение индикаторов через различные буферы,
- позволяет подключать индикатор с количеством разрядов до 8,
- предоставляет возможность посегментной и поразрядной развертки.
Полная версия библиотеки дополнительно обеспечивает:
- вывод отрицательных чисел,
- вывод текстовых сообщений,
- функцию моргания любых разрядов индикатора,
- вывод на индикатор нескольких чисел в произвольное место.
Состав библиотеки
indicator_2f.h - настройка параметров и подключения
indicator_2f.c - реализация функций
compiler_4.h - файл обеспечивающий поддержку трех компиляторов
port_macros.h - макросы виртуальных портов
Подключение к проекту
1. Копируем все файлы в папку проекта.
2. Подключаем indicator_2f.c к проекту
3. Инклюдим заголовочный файл indicator_2f.h к сишному файлу, в котором будут использоваться функции библиотеки.
4. Настраиваем параметры и подключение индикатора в файле indicator_2f.h
5. Прописываем в код вызов функций библиотеки индикатора
Настройка библиотеки индикатора
Настройка конфигурации состоит из следующих шагов.
1. Задаем количество цифр индикатора. Их может быть от 1 до 8.
#define IND_AMOUNT_NUM 4
2. Задаем тип развертки
#define IND_SCAN_SEGMENT 1
1 - посегментная развертка. За один цикл засвечиваются один сегмент всех разрядов.
0 - поразрядная развертка. За один цикл засвечиваются все сегменты одного разряда.
Поразрядная развертка дает более компактный код, но частота обновления индикатора в этом случае будет зависеть от количества разрядов индикатора.
3. Подключаем/отключаем функцию моргания
#define IND_USE_BLINK 1
0 – функция моргания не используется, 1 – функция моргания используется. В первом случае получается более компактный код.
4. Задаем период моргания
#define IND_DUR_BLINK 2000
Эта настройка определяет количество циклов, в течении которых моргающие разряды индикатора гаснут/горят. Один цикл – это время между вызовами функции обновления индикатора IND_Update().
5. Задаем куда подключены сегменты индикатора
Настройки, которые можно менять, обозначены на рисунке красной рамкой.
Первая строка - это конфигурация порта. Она задается в следующем формате: имя порта, буква порта, тип порта. Для настройки нужно менять только букву порта и его тип.
Если порт виртуальный, то буква может быть произвольной. В случае реального порта указывается его реальная буква.
Типов порта два - _VIRT и _REAL. Порт считается виртуальным в двух случаях: если он состоит из выводов нескольких портов, если он состоит из выводов одного порта, но они располагаются не по порядку.
Если используется реальный порт, то указывается тип _REAL. Это создает более компактный код.
Далее идут настройки выводов. Они задаются в таком формате: буква реального порта, номер вывода порта, активный уровень.
C- буква порта, 0 - используемый вывод порта, _HI - высокий активный уровень.
Здесь стоит остановиться только на активном уровне вывода. Есть три значения этого параметра: _HI, _LOW, _NONE.
Правило установки уровня простое. Если для зажигания сегмента индикатора на выводе микроконтроллера нужно установить логическую единицу, то активный уровень этого вывода _HI. Если для зажигания сегмента на выводе должен быть ноль, то активный уровень этого вывода _LOW. Если вывод не используется, то параметр устанавливается как _NONE.
6. Задаем куда подключены разряды индикатора
Настройки, которые можно менять, обозначены на рисунке красной рамкой.
Подключение разрядов аналогично описанному выше, поэтому разжевывать не буду.
Для работы с портами используются макросы виртуальных портов, на которых я уже делал библиотеку для LCD. Если что-то непонятно в их настройках, почитайте соответствующий материал - "виртуальные порты".
Использование библиотеки
void IND_Init(void) - функция инициализации. Настраивает порты ввода вывода, инициализирует внутренние переменные. Эта функция должна вызываться первой, например, в начале main`a.
void IND_OutSym(char *str, uint8_t pos) – записывает в буфер индикатора строку символов. Принимает указатель на строку (*str) и позицию первого символа (pos). Символы, которые может отобразить индикатор, определены в файле indicator_2f.c в массиве sym[]. Можно добавлять в этот массив свои символы.
Пример:
IND_OutSym(“cod”, 1);
void IND_OutUint(uint16_t value, uint8_t comma) – преобразует беззнаковое 16-и разрядное число (value) и записывает его в буфер индикатора. Число отображается на индикаторе, начиная с первого разряда. Также эта функция принимает номер разряда (comma), в котором будет гореть десятичная точка.
void IND_OutInt(int16_t value, uint8_t comma) – преобразует 16-и разрядное число со знаком (value) и записывает его в буфер индикатора. В первом разряде индикатора отображается знак числа. Также эта функция принимает номер разряда (comma), в котором будет гореть десятичная точка.
void IND_OutUintFormat(uint16_t value, uint8_t comma, uint8_t firstPos, uint8_t lastPos) - преобразует беззнаковое 16-и разрядное число (value) и записывает его в буфер индикатора в заданые позиции (firstPos, lastPos). Также эта функция принимает номер разряда (comma), в котором будет гореть десятичная точка.
void IND_OutIntFormat(int16_t value, uint8_t comma, uint8_t firstPos, uint8_t lastPos) - преобразует беззнаковое 16-и разрядное число со знаком (value) и записывает его в буфер индикатора в заданые позиции (firstPos, lastPos). Знак числа отображается в первой заданной позиции (firstPos). Также эта функция принимает номер разряда (comma), в котором будет гореть десятичная точка.
void IND_BlinkMask(uint8_t value) – задает маску (value), которая определяет моргающие разряды индикатора. Каждый бит маски соответствует одному разряду индикатора: нулевой бит – это первый разряд, первый бит – второй и так далее. Единица в маске – разряд моргает, ноль – не моргает.
Пример:
//задаем моргание 1, 2, 3, 4 разрядов индикатора
IND_BlinkMask (0x0f);
…
//ни один из разрядов не моргает
IND_BlinkMask (0x00);
void IND_Update(void) - функция обновляющая информацию на индикаторе. Эта функция должна периодически вызываться с частотой > 25* N. Где N - количество разрядов или сегментов индикатора, в зависимости от типа развертки. Вызов этой функции можно поместить в прерывание какого-нибудь таймера. В идеале ее нужно сделать встраиваемой, то есть описать прерывание таймера в файле indicator_2l.c и поместить в него код этой функции. Также можно вызывать эту функцию из основного цикла по сигналу таймера.
ВАЖНО! Если в прерываниях и в основном цикле программы выполняется работа с портами ввода-вывода, которые используются индикатором, то нужно обеспечивать атомарность этих операций.
Файлы
Облегченная версия библиотеки
IND-driver-2l-IAR.rar
IND-driver-2l-winavr.rar
Полная версия библиотеки
IND-driver-2f-IAR.rar
IND-driver-2f-winavr.rar
П.С: Об ошибках пишите в комментариях или вконтакте. Я ее, конечно, проверил, но косяки могут быть. А вообще получилось неплохо.
Comments
В качестве идеи для расширения возможностей - добавить регулировку яркости. Сам такое сделал на часах и яркость меняется в зависимости от внешнего освещения, 16 градаций яркости как для самих цифр так и для двоеточия между ними. Работает отлично, логика тоже простая - временной слот выделенный для отображения сегмента (или цифры смотря какой тип сканирования) делится на 16 и зажигается на время от 0 до 16/16. Могу поделиться кодом часов, у меня он не выделен в библиотеку
в последней библиотеке решил попробовать очень простой подход - объявляешь например LCD_PORTB если используется порт B или LCD_PORTD если порт D и т.д. все равно кол-во портов конечно, а уже внутри библиотеки исходя из этого определяешь и PORT и PIN и DDR
Неплохо бы было увидеть реализацию
тут все описано, есть видео и код управления яркостью тоже там приложен
Нет, системным программировани ем не занимался.
IND_SEG_0
сделать
IND_SEG_A ,
то библиотека не смогла бы работать?
Попробовал сегодня эту библиотеку. Все круто!
Но есть одно, но. При посегментной индикации очень сильно неравномерна засветка индикатора (все сегменты засвечены по разному). А при поразрядной - все ОК.
Code:
void IND_Clear(void)
{
uint8_t i;
/*очищаем внутренний буфер*/
for(i = 0; i < IND_AMOUNT_NUM; i++) {
ind_buf = 0;
}
}
#define _PM_DirPort_VIRT(port, id, value) do{ PM_SetDir(port##_##0, value, 0);
.Там где реализация поразрядной развертки
Code:
dig = (1<<count); при count=0 dig =1
и при PM_SetLevBitsPort(IND_DIG_PORT, dig); он зажет PORTD.0 ( это в моем случае ) но у меня в настройках стоит #define IND_DIG_0 D, 2, _LOW . Т.е изначально dig должен = 2
http://forum.cxem.net/index.php?app=core&module=attach§ion=attach&attach_id=372222
http://forum.cxem.net/index.php?app=core&module=attach§ion=attach&attach_id=372224
1. вызывается функция мигания (единожды, иначе приводит к неверному отображению);
2. затем функция обновления индикатора
3. затем функция записи символов в буфер.
Теперь любые выводимые символы будут мигать, пока снова не будет вызвана функция мигания с нулевым значением
IND_OutUintFormat
RSS feed for comments to this post