Вторник, 03.12.2024, 04:47
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Реклама Google
Форма входа
Категории раздела
Это нужно знать! [17]
Изучаем AVR [30]
Программаторы [12]
Необходимое ПО [8]
Готовые устройства [73]
Справочная [38]
Инструмент [0]
Технология [8]
Литература [0]
Arduino скетчи [18]
Поиск
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Микроконтроллеры - это просто!
Главная » Статьи » Изучаем AVR

Рисуем свои символы на 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--; 
 }; 
 }; 
 } 

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


 Все изложенное выше это не прямая инструкция к применению, а просто идеи и попытки изучения стандартных возможностей экрана. Это лишь несколько примеров, но рассмотренны все основные принципы, а вариантов использованиия может быть очень много.
Категория: Изучаем AVR | Добавил: Alex (09.02.2014)
Просмотров: 5462 | Рейтинг: 5.0/1
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright MyCorp © 2024