Пятница, 03.05.2024, 16:44
Главная
Приветствую Вас, Гость
Статистика



Онлайн лист

Онлайн всего: 1
Гостей: 1
Пользователей: 0



Реклама



Главная » Статьи » Микроконтроллеры

Наверх


Рисуем свои символы на LCD (HD44780)

     Дисплеи на основе контроллера HD44780 хороши собой и очень удобны в использовании, но имеют один недостаток - ограниченный набор символов. Может возникнуть ситуация, когда нужного для нашего проекта символа в стандартном наборе просто не окажется и что же тогда делать. Выход из этой ситуации есть.
     Производители контроллеров HD44780 предусмотрели возможность такой ситуации, поэтому в памяти контроллера есть специальные символы по адресам 0х00 - 0х07 - это переопределяеемые символы, графическое изображение которых может назначить сам пользователь. а значит что мы в контроллер можем записать до 8 необходимых нам символов.
Разберемся как же это сделать.
     Ответ я нашел в одном из примеров, который шел вместе с CodeVisionAVR (кстати это не единственный полезны и интересный пример, они располагаются Папка с программой\examples\).
     
И так для записи одного символа в контроллер дисплея нам необходимо сделать следующее:

typedef unsigned char byte;    \\ Объявляем новый тип переменной 

\\ Определяем непосредственно сам символ (имеет 5 точек в ширину и 7 в высоту)
flash byte char0[8]={              
0b10000000,
0b10001111,
0b10000011,
0b10000101,
0b10001001,
0b10010000,
0b10100000,
0b11000000};

Единичками на дисплее будут закрашенные точки, все что оставлено нулями будет пустым.
\\ Определяем функцию записи нашего символа в экран 
void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}

Это была предварительная подготовка. Теперь в основном теле функции main необходимо произвести запись символа в контроллер дисплея, что делаем командой define_char(char0,0); в скобках указываем название символа, которые мы задали выше и его адрес в контроллере, т.е. символ char0 будет доступен по адресу 0х00.
Запись символа производится строго только после инициализации дисплея, никак не до ( то есть после lcd_init(16);).

Все основное для записи у нас есть, теперь используем на примере. 

Пример 1


В прошлой статье я рассматривал способ создания прогрессбара на стандартном символе 0xFF. Прогрессбар состоял из 16 прямоугольников и заполнялся скажем так несколько грубовато, добавив несколько своих символов в экран мы можем сделать его плавным.
Подготовим коды новых символов, так как символ состоит из 5 столбцов то можно нарисовать пять этих столбцов и постепенно закрашивать символ целиком:

flash byte char0[8]={
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0000000};

flash byte char1[8]={
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0000000};

flash byte char2[8]={
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0000000};

flash byte char3[8]={
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0000000};

flash byte char4[8]={
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000};

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

Код программы:



#include <mega16.h>  // Подключаем библиотеку микроконтроллера  
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h> // Подключаем библиотеку дисплея
#include <delay.h> // Подключаем библиотеку реализации задержек
#define pause delay_ms(100) // Объявляем переменную pause, которая будет осуществлять задержку
char i; // Переменная для счетчика для анимации
char j; // П
еременная для счетчика для анимации
typedef unsigned char byte; // Новый тип переменной для наших символов
 
// Побитное изображение нашего символа для записи в контроллер дисплея
flash byte char0[8]={
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0010000,
0b0000000};

flash byte char1[8]={
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0011000,
0b0000000};

flash byte char2[8]={
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0011100,
0b0000000};

flash byte char3[8]={
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0011110,
0b0000000};

flash byte char4[8]={
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000};
// Функция записи символа в контроллер дисплея
void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}
// Функция инициализации микроконтроллера
void avr_init(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;

}
// Основная программа
void main(void)
{
avr_init();
lcd_init(16); // Инициализация экрана
// Запись символов char0 - char4 по адресам 0х00 - 0х04 соответственноdefine_char(char0,0);
define_char(char1,1);
define_char(char2,2);
define_char(char3,3);
define_char(char4,4);
lcd_clear(); // Очищаем экран
while (1)
{i=0; // код вывода анимации из новых символов на дисплей
lcd_clear();
j=0;
while(j<16){
i=0;
while(i<5){
lcd_gotoxy(j,0);
lcd_putchar(i);
i++;
pause;
};
j++;
};
};
}






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




   

Пример 2


Индикатор заряда аккумулятора или батареи.

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

Нам понадобятся новые символы:

    flash byte char0[8]={
   0b0001110,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0011111,
   0b0000000};

    flash byte char0[8]={
   0b0001110,
  0b0010001,
  0b0010001,
  0b0010001,
  0b0010001,
  0b0011111,
  0b0011111,
  0b0000000};

    flash byte char0[8]={
   0b0001110,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0000000};
  

    flash byte char0[8]={
   0b0001110,
   0b0010001,
   0b0010001,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0000000};


    flash byte char0[8]={
   0b0001110,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0010001,
   0b0011111,
   0b0000000};


    flash byte char0[8]={
   0b0001110,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0011111,
   0b0000000};

Ниже приведен код анимации разряда аккумулятора:







#include <mega16.h>  // Подключаем библиотеку микроконтроллера  
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h> // Подключаем библиотеку дисплея
#include <delay.h> // Подключаем библиотеку реализации задержек
#define pause delay_ms(100) // Объявляем переменную pause, которая будет осуществлять задержку
char i; // Переменная для счетчика для анимации
typedef unsigned char byte; // Новый тип переменной для наших символов
 
// Побитное изображение нашего символа для записи в контроллер дисплея
flash byte char0[8]={
0b0001110,
0b0010001,
0b0010001,
0b0010001,
0b0010001,
0b0010001,
0b0011111,
0b0000000};

flash byte char1[8]={
0b0001110,
0b0010001,
0b0010001,
0b0010001,
0b0010001,
0b0011111,
0b0011111,
0b0000000};

flash byte char2[8]={
0b0001110,
0b0010001,
0b0010001,
0b0010001,
0b0011111,
0b0011111,
0b0011111,
0b0000000};

flash byte char3[8]={
0b0001110,
0b0010001,
0b0010001,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000};

flash byte char4[8]={
0b0001110,
0b0010001,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000};

flash byte char5[8]={
0b0001110,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0011111,
0b0000000};
// Функция записи символа в контроллер дисплея
void define_char(byte flash *pc,byte char_code)
{
byte i,a;
a=(char_code<<3)|0x40;
for (i=0; i<8; i++) lcd_write_byte(a++,*pc++);
}
// Функция инициализации микроконтроллера
void avr_init(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;

}
// Основная программа
void main(void)
{
avr_init();
lcd_init(16); // Инициализация экрана
// Запись символов char0 - char4 по адресам 0х00 - 0х04 соответственноdefine_char(char0,0);
define_char(char1,1);
define_char(char2,2);
define_char(char3,3);
define_char(char4,4);
define_char(char5,5);
lcd_clear(); // Очищаем экран
while (1)
{ // код вывода анимации из новых символов на дисплей
i=5;
while(i>0){
lcd_gotoxy(0,1);
lcd_putchar(i);
pause;
i--;
};
};
}






                                                                                                                                                                       Результат выполнения:


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



Нравится
Категория: Микроконтроллеры | Добавил: Naprisar (04.04.2012)
Просмотров: 19330 | Комментарии: 1 | Теги: LCD, микроконтроллер, HD44780, ATmega16
Всего комментариев: 1
1 Владимир  
0
В обоих примерах нужно добавить строку define_char(char0,0);

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Наверх