Как обеспечить взаимодействие микроконтроллера TSC80251 и си

Как обеспечить взаимодействие микроконтроллера TSC80251 и символьного ЖКИ

Раздел: Оптоэлектроника

1. Описание

Эта статья описывает программное и аппаратное обеспечение, необходимое для того, чтобы обеспечить взаимодействие микроконтроллера TSC80251 и микросхемы контроллера и формирователя ЖКИ Hitachi HD44780. HD44780 это один из самых распространённых контроллеров, использующихся в символьных одно - четырёх строчных индикаторах. Он также выпускается несколькими различными производителями. Эта статья показывает как подключить и запрограммировать индикатор с четырьмя строками по 16 символов от Hantronix (HDM16416H), но может быть легко применена к ЖКИ с меньшим разрешением. Аппаратное обеспечение базируется на отладочной плате KEIL, входящей в стартовый комплект TSC80251. Эта отладочная плата является одноплатным компьютером с маленькой программой-монитором, поддержанной программным обеспечением KEIL и средствами разработки программного обеспечения BSO/TASKING. Плата подключается к ПК через последовательный канал и код может быть загружен в ОЗУ на плате из средства разработки. Далее плата используется как целевая система и простой эмулятор. Отдельная макетная область может быть использована для схем пользователя.

 

2. Аппаратное обеспечение

  

2.1. Описание аппаратного обеспечения

 

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

 

2.2. Интерфейс с микроконтроллером

 

 

HD44780 контроллер может быть настроен для взаимодействия с 4 или 8-битными микроконтроллерами. Наиболее простой способ взаимодействия это настроить интерфейс для 8-разрядного обмена и далее подключить индикатор как устройство включённое в адресное пространство памяти. Недостатком этого решения является необходимость в связующих логических схемах для интерфейса с индикатором и в том, что необходимо программировать задержки, чтобы избежать нарушения синхронизации при взаимодействии с TSC80251. Эта статья демонстрирует как организовать интерфейс с контроллером в 4-битном режиме. Когда контроллер настроен для 4-битного обмена, используются следующие сигналы:

DB4, DB5, DB6, DB7 - Мультиплексированная шина данных (четыре бита посылаются дважды, формируя байт) RS - Выбор регистра R/W - сигнал Чтение/Запись E - Разрешение

 

2.3. Управление контрастом

Рекомендуемый способ настройки контраста ЖКИ - подсоединить вход Vo ЖКИ к 10кОм переменному резистору, как показано на рисунке 2. Настройка производится во время заводской наладки. В данной статье предлагается убрать переменный резистор и подключить вход Vo напрямую к ШИМ выходу Программируемой Матрицы Счетчика, имеющемуся в TSC80251G1. Это решение позволяет полностью управлять контрастом с помощью программного обеспечения и не требует внешних компонентов. Вследствие своей инерционности, ЖКИ воспринимает прямоугольный сигнал как аналоговый без добавления какого-либо фильтра.

 

 

2.4. Управление подсветкой

 

 

Бит выходного порта используется для управления подсветкой посредством Atmel Wireless Microcontrollers LITTLE FOOT MOS-FET.

На отладочной плате нажимная кнопка, подсоединённая к входу внешнего прерывания 1 (INT1), используется демонстрационным программным обеспечением, чтобы включать и выключать подсветку ЖКИ.

 

3. Временные диаграммы

 

 

Времена выполнения команд: Очистить Индикатор 1.64 мс; Курсор в Начало 40 мкс; все другие 40 мкс, исключая чтение флага занятости, который выполняется в одном цикле разрешения (или в двух циклах 4-битного режима), и чтения и записи ОЗУ знакогенератора, которые должны быть отделены 120 мкс задержками. Эти времена выполнения означают, что после выдачи команды, ЦП должен производить проверку Флага Занятости до тех пор пока ФЗ (бит 7) не станет равным 0, или, если ЦП подключён к модулю в режиме только - записи, перед выдачей следующей команды сделать задержку на время более чем время исполнения команды. Эти времена обычно предопределены, ЖКИ использующиеся в режиме только - записи должны обеспечивать заданные задержки.

Операция записи

Операция чтения

Значения временных параметров

Значение Обозначение Min Max Единици Enable cycle time tCYC 500   ns Enable pulse width PWEH 220   ns Enable rise/fall time tEr, tEf   25 ns RS, RW set ut time tAS 40   ns Data delay time tDDR 60 120 ns Data set up time tDSW 10   ns Hold time tH 20   ns

Требование к ширине строба разрешения является критичным. В низкоуровневых процедурах строб разрешения E выдаётся с помощью следующих инструкций языка C:

E_PORT = 1; /* установить высокий уровень E */
E_PORT = 0; /* установить низкий уровень E */

Компилятор преобразует это в:

D296 setb P1.6 - 4 такта
C296 clr P1.6 - 4 такта

Для тактовой частоты 24 МГц один такт занимает 83.3 нс. Строб E будет длиться как минимум 4*83.3 = 333 нс, так что эта величина больше минимума, требуемого в спецификации. Кроме того, дополнительные такты должны быть добавлены, если код выполняется из внешней памяти.

 

4. Программное обеспечение

 

 

Предлагаемое программное обеспечение реализует функцию ‘putchar’, которая заменяет стандартную функцию. Функция ‘putchar’ это низкоуровневая функция символьного вывода, которая используется функциями потокового ввода/вывода языка ANSI C, такими как printf, puts, vprintf и т.п. Таким образом стандартные функции ANSI C могут быть использованы для форматного вывода на индикатор. Также реализовано несколько специфических для индикатора функций, таких как ‘set_cursor’, ‘lcd_clr’ и т.п.

Следующие файлы содержатся в приложении:

MAIN.C

Этот файл содержит главную функцию демонстрационной программы. void main (void); главная функция инициализирует контроллер ЖКИ и внешнее прерывание и выводит строку на индикатор.

LCD.C

Этот файл содержит драйверы ЖКИ.

void lcd_preter (char); выводит символ на ЖКИ.
void lcd_init (void); инициализирует индикатор после включения.
void lcd_clr (void); очищает индикатор и устанавливает курсор в начальную позицию.
void set_cursor (char, char); устанавливает курсор в позицию y, x.
void cursor_on (void); включает курсор.
void cursor_off (void); выключает курсор.
void backlight_on (void); включает подсветку.
void backlight_off (void); выключает подсветку.

PUTCHAR.C

Этот файл содержит функцию putchar: низкоуровневую функцию символьного вывода, которая используется функциями потокового ввода/вывода.

LCD.H

Этот файл - это файл описания ЖКИ и он содержит константы, которые могут быть изменены пользователем в зависимости от его задач и от типа ЖКИ (например порт ЖКИ, число строк, средний контраст …).

PROTOS.H

Этот файл содержит объявления глобальных функций из LCD.C. Этот файл должен быть включён во все файлы, в которых есть обращения к функциям ЖКИ.

REG251G1.H

Это файл определений регистра и он содержит SFR и BIT адреса для TSC80251G1.

 

5. Приложение A: Программное обеспечение

 

5.1. MAIN.C

/*
** ---------------------------------------------------------------------------
** MAIN.C
** ---------------------------------------------------------------------------
** Фирма: Atmel Wireless Microcontrollers
** Версия: 1.0
** ---------------------------------------------------------------------------
** Примечание: Этот файл содержит демонстрационное программное
** обеспечение для функций ЖКИ
** ---------------------------------------------------------------------------
*/

/*
** Импорт
*/
#include /* регистры специальных функций 251G1 */
#include /* заголовки функций ввода/вывода */
#include ”protos.h” /* заголовки функций драйвера ЖКИ */

/*
** Заголовки
*/
static void ex1_install (void);

/*
** ---------------------------------------------------------------------------
** main - главная функция пользователя
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: демонстрационная функция
** ---------------------------------------------------------------------------
*/
void main (void) { /* главная точка входа программы */
ex1_install();
EA = 1; /* разрешить глобальное прерывание */
lcd_init(); /* инициализация ЖКИ */
set_cursor(0,1); /* позиционировать курсора */
printf(”Atmel TSC80251

”); /* вывести текст на индикатор */
printf(” LCD CONTROLLER
”);
printf(” DEMO. SOFTWARE”);
while(1); /* бесконечный цикл */
}
/*
** ---------------------------------------------------------------------------
** ex1_install - установка внешнего прерывания 1
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: разрешить EX1 как прерывание по фронту
** ---------------------------------------------------------------------------
*/
void ex1_install (void) {
EX1 = 1; /* разрешить внешнее прерывание 1 */
IT1 = 1; /* сделать прерывание срабатывающим по фронту */
}

5.2. PUTCHAR.C

/*
** ---------------------------------------------------------------------------
** PUTCHAR.C
** ---------------------------------------------------------------------------
** Фирма: Atmel Wireless Microcontrollers
** Версия: 1.0
** ---------------------------------------------------------------------------
** Примечание: Этот файл содержит функцию символьного вывода низкого уровня
** для использования в функциях потокового ввода/вывода
** ---------------------------------------------------------------------------
*/
/*
** Импорт
*/
#include ”protos.h” /* заголовки функций драйвера ЖКИ */
/*
** ---------------------------------------------------------------------------
** putchar - посылает символ в стандартный выходной поток
** ---------------------------------------------------------------------------
** Вход: символ для вывода
**
** Выход: выведенный символ
**
** ---------------------------------------------------------------------------
** Примечание: putchar это функция символьного вывода низкого уровня
** для использования в функциях потокового ввода/вывода
** Стандартная функция посылает символ в последовательный интерфейс,
** новая функция затем отображает символ на ЖКИ
** ---------------------------------------------------------------------------
*/
char putchar (char c) {
lcd_preter(c); /* выводит символ на индикатор */
return(c);
}

5.3. LCD.C

/*
** ---------------------------------------------------------------------------
** LCD.C
** ---------------------------------------------------------------------------
** Фирма: Atmel Wireless Microcontrollers
** Версия: 1.0
** ---------------------------------------------------------------------------
** Примечание: Этот файл содержит драйверы ЖКИ
** ---------------------------------------------------------------------------
*/

/*
** Импорт
*/
#include /* регистры специальных функций 251G1 */
#include /* заголовки функций ввода/вывода */
#include ”lcd.h”
/* определения констант ЖКИ */
/*
** Определения
*/
static int row=0, col=0; /* содержит текущую позицию курсора */

/*
** Заголовки
*/
void lcd_preter (char);
void lcd_init (void);
void set_cursor (char,char);
void lcd_clr (void);
void cursor_on (void);
void cursor_off (void);
void backlight_on (void);
void backlight_off (void);

static void vo_install (void);
static char check_busy_flag (void);
static void putlcd (unsigned char);
static void write_cmde (unsigned char);
static void write_data (unsigned char);
static void write_nibble (unsigned char);

/*
** ---------------------------------------------------------------------------
** lcd_init - функция инициализации и конфигурации ЖКИ контроллера
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: Эта функция вызывается один раз для инициализации ЖКИ.
** Контроллер HD44780 содержит 8 областей ОЗУ
** где пользовательские символы могут быть определены.
** Четыре из этих областей используются в примере, чтобы определить
** локальные символы е, Ц, Д и Е использующиеся из функции lcd_preter
** ---------------------------------------------------------------------------
*/
void lcd_init (void) {
char i;
static const char code init_tab[] = {0x33, 0x32, 0x28, 0x08, 0x01, 0x06, 0x0C};
/* Эта последовательность данных инициализирует индикатор:
4 битный интерфейс, 4 строки, 5*7 точек, +1 авто приращение,
индикатор включён, курсор выключен */
static const char code fonttab[] = {
0x0E, 0x11, 0x0E, 0x01, 0x0F, 0x11, 0x0F, 0x00, /* е - адрес 0 в CG RAM */
0x0A, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, /* Ц - адрес 1 в CG RAM */
0x0A, 0x00, 0x0E, 0x11, 0x11, 0x1F, 0x11, 0x00, /* Д - адрес 2 в CG RAM */
0x0E, 0x11, 0x0E, 0x11, 0x11, 0x1F, 0x11, 0x00}; /* Е - адрес 3 в CG RAM */



for (i = 0; i < sizeof init_tab; ++i) {
write_cmde(initdata[i]); /* выдать данные инициализации в контроллер */
}
write_cmde(CG_RAM); /* выбрать ОЗУ изображения символа */
for (i = 0; i < sizeof font_tab; ++i) {
write_data(fonttab[i]); /* загрузить Шведские символы */
}
write_cmde(DD_RAM); /* выбрать ОЗУ данных индикатора */
vo_install(); /* управление Vo */
}

/*
** ---------------------------------------------------------------------------
** vo_install - настройка контраста отображения
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: разрешение ШИМ выхода на канал 4 PCA
** ---------------------------------------------------------------------------
*/
static void vo_install (void) {
VO_PORT = 1; /* разрешить альтернативную функцию */
CMOD = 0x00; /* тактовая частота PCA = Fosc/12 */
CCAPM4 = 0x42; /* настроить канал 4 как выход ШИМ */
CCAP4H = VO_MEDIUM /* настроить контраст на среднее значение */
CR = 1; /* запустить таймер PCA */
}

/*
** ---------------------------------------------------------------------------
** set_cursor - установка позиции курсора
** ---------------------------------------------------------------------------
** Вход: строка и столбец позиции курсора
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: Строки и столбцы нумеруются с 0 (с отсчётом от нуля)
** ---------------------------------------------------------------------------
*/
void set_cursor (char rownr, char colnr) {
int cmd;
rownr= rownr%NB_ROW; /* убедиться, что позиция в пределах */
colnr= colnr%NB_COL; /* убедиться, что позиция в пределах */
switch (rownr) {
case 0:
cmd = ROW0;
break;
case 1:
cmd = ROW1;
break;
case 2:
cmd = ROW2;
break;
case 3:
cmd = ROW3;
break;
}
write_cmde(cmd | colnr); /* выдать новую позицию курсора */
row = rownr; /* обновить глобальное значение строки позиции курсора */
col = colnr; /* обновить глобальное значение столбца позиции курсора */
}





/*
** ---------------------------------------------------------------------------
** lcd_clr - очистка индикатора и установка курсора в начало
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
void lcd_clr(void) {
write_cmde(CLR_LCD);
}

/*
** ---------------------------------------------------------------------------
** cursor_on - включение курсора
** cursor_off - выключение курсора
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
void cursor_on (void) {
write_cmde(CUR_ON);
}

void cursor_off (void) {
write_cmde(CUR_OFF);
}

/*
** ---------------------------------------------------------------------------
** backlight_on - включение подсветки
** backlight_off - выключение подсветки
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
void backlight_on (void) {
BL_PORT= 1;
}

void backlight_off (void) {
BL_PORT= 0;
}
/*
** ---------------------------------------------------------------------------
** write_cmde - вывод байта команды в индикатор
** ---------------------------------------------------------------------------
** Вход: байт команды для вывода
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
static void write_cmde (unsigned char cmde) {
while (check_busy_flag()); /* ждать, если индикатор занят*/
RS_PORT = 0; /* выбрать регистры команд */
write_nibble(cmde >> 4); /* вывести старший полубайт */
write_nibble(cmde); /* вывести младший полубайт */
}

/*
** ---------------------------------------------------------------------------
** write_data - вывод байта данных в индикатор
** ---------------------------------------------------------------------------
** Вход: байт данных для вывода
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
static void write_data (unsigned char byte) {
while (check_busy_flag()); /* ждать, если индикатор занят */
RS_PORT = 1; /* выбрать регистры данных */
write_nibble(byte >> 4); /* вывести старший полубайт */
write_nibble(byte); /* вывести младший полубайт */
}

/*
** ---------------------------------------------------------------------------
** check_busy_flag - проверка флага занятости индикатора
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: вызывается из write_cmde и write_data
** ---------------------------------------------------------------------------
*/
static char check_busy_flag (void) {
char bf;
LCD_PORT |= LCD_DAT_MSK; /* высокий уровень шины данных */
RS_PORT = 0; /* выбрать регистры команд */
RW_PORT = 1; /* доступ для чтения */
E_PORT = 1; /* установить высокий уровень E */
bf = LCD_PORT BF_BIT; /* прочитать флаг занятости */
E_PORT = 0; /* установить низкий уровень E */
E_PORT = 1; /* второе чтение вследствие 4 битного интерфейса */
E_PORT = 0;
return (bf); /* возвратить флаг занятости */
}
/*
** ---------------------------------------------------------------------------
** write_nibble - вывод полубайта в индикатор
** ---------------------------------------------------------------------------
** Вход: полубайт для вывода
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание:
** ---------------------------------------------------------------------------
*/
static void write_nibble (unsigned char nibble) {
LCD_PORT = ~LCD_DAT_MSK; /* высокий уровень шины данных */
RW_PORT = 0; /* доступ для записи */
nibble = LCD_DAT_MSK; /* очистить старший полубайт */
LCD_PORT |= nibble; /* вывести полубайт */
E_PORT = 1; /* установить высокий уровень E */
E_PORT = 0; /* установить низкий уровень E */
}

/*
** ---------------------------------------------------------------------------
** lcd_preter - командный интерпретатор ЖКИ
** ---------------------------------------------------------------------------
** Вход:
**
** Выход:
**
** ---------------------------------------------------------------------------
** Примечание: вызывается из putchar
** ---------------------------------------------------------------------------
*/
void lcd_preter (char c) {
switch (c) {
case C_R: /* Возврат Каретки */
set_cursor(row, 0);
break;
case L_F: /* Перевод Строки */
row = (row+1)%NB_ROW;
set_cursor(row, 0);
break;
case B_S: /* Возврат на Позицию Назад */
if (col != 0) {
set_cursor(row, --col);
putlcd(’ ’);
set_cursor(row, --col);
}
break;
case ’ц’:
putlcd(0xef); /* отобразить специальный символ */
break;
case ’д’:
putlcd(0xe1); /* отобразить специальный символ */
break;
case ’е’:
putlcd(0); /* отобразить специальный символ из ОЗУ индикатора */
break;
case ’Ц’:
putlcd(1); /* отобразить специальный символ из ОЗУ индикатора */
break;
case ’Д’:
putlcd(2); /* отобразить специальный символ из ОЗУ индикатора */
break;
case ’Е’:
putlcd(3); /* отобразить специальный символ из ОЗУ индикатора */
break;
default:
if (c>0x1f c






Рекомендуемый контент




Copyright © 2010-2017 housea.ru. Контакты: info@housea.ru При использовании материалов веб-сайта Домашнее Радио, гиперссылка на источник обязательна.