Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @file hd44780.c
- * @brief Простой и относительно универсальный вывод данных на дисплей
- * с контроллером HD44780.
- * @details Для использования необходимо написать:
- * - функцию задержки на 500 нс или более;
- * - функцию установки данных DB[3:0] на дисплее.
- * - функцию установки сигнала RS на дисплее.
- * - функцию установки сигнала E на дисплее.
- *
- * Указатели на эти функции передаются функции инициализации дисплея,
- * которая создает значительную задержку (не менее 25 мс).
- * Далее необходимо вызывать функцию hd44780_update с периодичностью не менее 40 мкс,
- * но не более необходимого для визуально быстрого обновления содержимого дисплея.
- * Содержимое дисплея можно менять функциями @link hd44780_putc @endlink и @link hd44780_putstring @endlink.
- */
- #include "hd44780.h"
- #define HD44780_CMD_CLEARDISPLAY 0x01
- #define HD44780_CMD_ENTRYMODESET 0x04
- #define HD44780_CMD_DISPLAYCONTROL 0x08
- #define HD44780_CMD_FUNCTIONSET 0x20
- #define HD44780_CMD_SETDDRAMADDR 0x80
- #define HD44780_DISPLAYON_MASK 0x04
- #define HD44780_DISPLAYOFF_MASK 0x00
- #define HD44780_4BITMODE_MASK 0x00
- #define HD44780_2LINE_MASK 0x08
- #define HD44780_1LINE_MASK 0x00
- #define HD44780_FLAG_ENTRYRIGHT 0x02
- #define HD44780_STRING_1_OFFSET 0x00
- #define HD44780_STRING_2_OFFSET 0x40
- #define HD44780_STRING_3_OFFSET 0x10
- #define HD44780_STRING_4_OFFSET 0x50
- void hd44780_state_init(hd44780_state_t *state,
- uint8_t width,
- uint8_t height,
- void (*delay_w)(void),
- void (*set_data)(uint8_t),
- void (*set_RS)(uint8_t),
- void (*set_E)(uint8_t)) {
- uint8_t i, j;
- state->delay_w = delay_w;
- state->set_data = set_data;
- state->set_RS = set_RS;
- state->set_E = set_E;
- state->width = width;
- state->height = height;
- state->cursor_x = 0;
- state->cursor_y = 0;
- for (i = 0; i < width; i++) {
- for (j = 0; j < height; j++) {
- state->data[i][j] = ' ';
- }
- }
- }
- void hd44780_write_nibble(hd44780_state_t *state, uint8_t data) {
- state->delay_w();
- state->set_data(data);
- state->delay_w();
- state->set_E(1);
- state->delay_w();
- state->set_E(0);
- state->delay_w();
- }
- void hd44780_write_cmd(hd44780_state_t *state, uint8_t cmd) {
- state->set_RS(0);
- hd44780_write_nibble(state, cmd >> 4);
- hd44780_write_nibble(state, cmd);
- }
- void hd44780_write_data(hd44780_state_t *state, uint8_t data) {
- state->set_RS(1);
- hd44780_write_nibble(state, data >> 4);
- hd44780_write_nibble(state, data);
- }
- void delay_40us(hd44780_state_t *state) {
- uint16_t i;
- for (i = 0; i < 100; i++) {
- state->delay_w();
- }
- }
- void hd44780_init(hd44780_state_t *state,
- uint8_t width,
- uint8_t height,
- void (*delay_w)(void),
- void (*set_data)(uint8_t),
- void (*set_RS)(uint8_t),
- void (*set_E)(uint8_t)) {
- uint16_t i;
- hd44780_state_init(state, width, height, delay_w, set_data, set_RS, set_E);
- state->set_E(0);
- state->set_RS(0);
- state->set_data(0);
- // Ожидание 20 мс.
- for (i = 0; i < 40000; i++) {
- state->delay_w();
- }
- // Установка разрядности интерфейса.
- hd44780_write_nibble(state, 0x03);
- // Задержка не менее 4,1 мс.
- for (i = 0; i < 10000; i++) {
- state->delay_w();
- }
- hd44780_write_nibble(state, 0x03);
- delay_40us(state);
- hd44780_write_nibble(state, 0x03);
- delay_40us(state);
- hd44780_write_nibble(state, 0x02);
- // Установка параметров.
- hd44780_write_cmd(state, HD44780_CMD_FUNCTIONSET | HD44780_4BITMODE_MASK | HD44780_2LINE_MASK);
- delay_40us(state);
- // Выключение дисплея.
- hd44780_write_cmd(state, HD44780_CMD_DISPLAYCONTROL | HD44780_DISPLAYOFF_MASK);
- delay_40us(state);
- // Очистка дисплея.
- hd44780_write_cmd(state, HD44780_CMD_CLEARDISPLAY);
- // Ожидание не менее 1,5 мс.
- for (i = 0; i < 20000; i++) {
- state->delay_w();
- }
- hd44780_write_cmd(state, HD44780_CMD_ENTRYMODESET | HD44780_FLAG_ENTRYRIGHT);
- delay_40us(state);
- hd44780_write_cmd(state, HD44780_CMD_DISPLAYCONTROL | HD44780_DISPLAYON_MASK);
- delay_40us(state);
- }
- /**
- * @brief Вывод символа на дисплей по заданным координатам.
- * @param state: Указатель на структуру с состоянием дисплея.
- * @param xpos: Положение символа по горизонтали.
- * @param ypos: Положение символа по вертикали.
- * @param ch: Код выводимого символа.
- */
- void hd44780_putc(hd44780_state_t *state, uint8_t xpos, uint8_t ypos, char ch) {
- state->data[xpos][ypos] = (char)ch;
- }
- /**
- * @brief Вывод символа на дисплей по заданным координатам.
- * @param state: Указатель на структуру с состоянием дисплея.
- * @param xpos: Положение начала строки по горизонтали.
- * @param ypos: Положение начала строки по вертикали.
- * @param str: Указатель на выводимую строку.
- */
- void hd44780_putstring(hd44780_state_t *state, uint8_t xpos, uint8_t ypos, char *str) {
- while ((xpos < state->width - 1) && *str) {
- state->data[xpos][ypos] = (char)(*str);
- str++;
- xpos++;
- }
- }
- void hd44780_update(hd44780_state_t *state) {
- if (state->cursor_x == state->width) {
- state->cursor_x = 0;
- state->cursor_y++;
- if (state->cursor_y == state->height) {
- state->cursor_y = 0;
- }
- uint8_t addr = state->cursor_x;
- switch (state->cursor_y) {
- case 0:
- addr += HD44780_STRING_1_OFFSET;
- break;
- case 1:
- addr += HD44780_STRING_2_OFFSET;
- break;
- case 2:
- addr += HD44780_STRING_3_OFFSET;
- break;
- case 3:
- addr += HD44780_STRING_4_OFFSET;
- break;
- }
- hd44780_write_cmd(state, HD44780_CMD_SETDDRAMADDR | addr);
- } else {
- hd44780_write_data(state, state->data[state->cursor_x][state->cursor_y]);
- state->cursor_x++;
- }
- }
Add Comment
Please, Sign In to add comment