Guest User

Untitled

a guest
Oct 18th, 2017
62
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.   * @file    hd44780.c
  3.   * @brief   Простой и относительно универсальный вывод данных на дисплей
  4.   *          с контроллером HD44780.
  5.   * @details Для использования необходимо написать:
  6.   *            - функцию задержки на 500 нс или более;
  7.   *            - функцию установки данных DB[3:0] на дисплее.
  8.   *            - функцию установки сигнала RS на дисплее.
  9.   *            - функцию установки сигнала E на дисплее.
  10.   *
  11.   *          Указатели на эти функции передаются функции инициализации дисплея,
  12.   *          которая создает значительную задержку (не менее 25 мс).
  13.   *          Далее необходимо вызывать функцию hd44780_update с периодичностью не менее 40 мкс,
  14.   *          но не более необходимого для визуально быстрого обновления содержимого дисплея.
  15.   *          Содержимое дисплея можно менять функциями @link hd44780_putc @endlink и @link hd44780_putstring @endlink.
  16.   */
  17. #include "hd44780.h"
  18.  
  19. #define HD44780_CMD_CLEARDISPLAY 0x01
  20. #define HD44780_CMD_ENTRYMODESET 0x04
  21. #define HD44780_CMD_DISPLAYCONTROL 0x08
  22. #define HD44780_CMD_FUNCTIONSET 0x20
  23. #define HD44780_CMD_SETDDRAMADDR 0x80
  24.  
  25. #define HD44780_DISPLAYON_MASK 0x04
  26. #define HD44780_DISPLAYOFF_MASK 0x00
  27.  
  28. #define HD44780_4BITMODE_MASK 0x00
  29. #define HD44780_2LINE_MASK 0x08
  30. #define HD44780_1LINE_MASK 0x00
  31.  
  32. #define HD44780_FLAG_ENTRYRIGHT 0x02
  33.  
  34. #define HD44780_STRING_1_OFFSET 0x00
  35. #define HD44780_STRING_2_OFFSET 0x40
  36. #define HD44780_STRING_3_OFFSET 0x10
  37. #define HD44780_STRING_4_OFFSET 0x50
  38.  
  39. void hd44780_state_init(hd44780_state_t *state,
  40.                         uint8_t width,
  41.                         uint8_t height,
  42.                         void (*delay_w)(void),
  43.                         void (*set_data)(uint8_t),
  44.                         void (*set_RS)(uint8_t),
  45.                         void (*set_E)(uint8_t)) {
  46.   uint8_t i, j;
  47.  
  48.   state->delay_w = delay_w;
  49.   state->set_data = set_data;
  50.   state->set_RS = set_RS;
  51.   state->set_E = set_E;
  52.   state->width = width;
  53.   state->height = height;
  54.   state->cursor_x = 0;
  55.   state->cursor_y = 0;
  56.  
  57.   for (i = 0; i < width; i++) {
  58.     for (j = 0; j < height; j++) {
  59.       state->data[i][j] = ' ';
  60.     }
  61.   }
  62. }
  63.  
  64. void hd44780_write_nibble(hd44780_state_t *state, uint8_t data) {
  65.   state->delay_w();
  66.   state->set_data(data);
  67.   state->delay_w();
  68.   state->set_E(1);
  69.   state->delay_w();
  70.   state->set_E(0);
  71.   state->delay_w();
  72. }
  73.  
  74. void hd44780_write_cmd(hd44780_state_t *state, uint8_t cmd) {
  75.   state->set_RS(0);
  76.   hd44780_write_nibble(state, cmd >> 4);
  77.   hd44780_write_nibble(state, cmd);
  78. }
  79.  
  80. void hd44780_write_data(hd44780_state_t *state, uint8_t data) {
  81.   state->set_RS(1);
  82.   hd44780_write_nibble(state, data >> 4);
  83.   hd44780_write_nibble(state, data);
  84. }
  85.  
  86. void delay_40us(hd44780_state_t *state) {
  87.   uint16_t i;
  88.   for (i = 0; i < 100; i++) {
  89.     state->delay_w();
  90.   }
  91. }
  92.  
  93. void hd44780_init(hd44780_state_t *state,
  94.                         uint8_t width,
  95.                         uint8_t height,
  96.                         void (*delay_w)(void),
  97.                         void (*set_data)(uint8_t),
  98.                         void (*set_RS)(uint8_t),
  99.                         void (*set_E)(uint8_t)) {
  100.   uint16_t i;
  101.  
  102.   hd44780_state_init(state, width, height, delay_w, set_data, set_RS, set_E);
  103.  
  104.   state->set_E(0);
  105.   state->set_RS(0);
  106.   state->set_data(0);
  107.  
  108.   // Ожидание 20 мс.
  109.   for (i = 0; i < 40000; i++) {
  110.     state->delay_w();
  111.   }
  112.  
  113.   // Установка разрядности интерфейса.
  114.   hd44780_write_nibble(state, 0x03);
  115.   // Задержка не менее 4,1 мс.
  116.   for (i = 0; i < 10000; i++) {
  117.     state->delay_w();
  118.   }
  119.   hd44780_write_nibble(state, 0x03);
  120.   delay_40us(state);
  121.   hd44780_write_nibble(state, 0x03);
  122.   delay_40us(state);
  123.   hd44780_write_nibble(state, 0x02);
  124.  
  125.   // Установка параметров.
  126.   hd44780_write_cmd(state, HD44780_CMD_FUNCTIONSET | HD44780_4BITMODE_MASK | HD44780_2LINE_MASK);
  127.   delay_40us(state);
  128.  
  129.   // Выключение дисплея.
  130.   hd44780_write_cmd(state, HD44780_CMD_DISPLAYCONTROL | HD44780_DISPLAYOFF_MASK);
  131.   delay_40us(state);
  132.  
  133.   // Очистка дисплея.
  134.   hd44780_write_cmd(state, HD44780_CMD_CLEARDISPLAY);
  135.   // Ожидание не менее 1,5 мс.
  136.   for (i = 0; i < 20000; i++) {
  137.     state->delay_w();
  138.   }
  139.  
  140.   hd44780_write_cmd(state, HD44780_CMD_ENTRYMODESET | HD44780_FLAG_ENTRYRIGHT);
  141.   delay_40us(state);
  142.  
  143.   hd44780_write_cmd(state, HD44780_CMD_DISPLAYCONTROL | HD44780_DISPLAYON_MASK);
  144.   delay_40us(state);
  145. }
  146.  
  147. /**
  148.   * @brief  Вывод символа на дисплей по заданным координатам.
  149.   * @param  state: Указатель на структуру с состоянием дисплея.
  150.   * @param  xpos: Положение символа по горизонтали.
  151.   * @param  ypos: Положение символа по вертикали.
  152.   * @param  ch: Код выводимого символа.
  153.   */
  154. void hd44780_putc(hd44780_state_t *state, uint8_t xpos, uint8_t ypos, char ch) {
  155.   state->data[xpos][ypos] = (char)ch;
  156. }
  157.  
  158. /**
  159.   * @brief  Вывод символа на дисплей по заданным координатам.
  160.   * @param  state: Указатель на структуру с состоянием дисплея.
  161.   * @param  xpos: Положение начала строки по горизонтали.
  162.   * @param  ypos: Положение начала строки по вертикали.
  163.   * @param  str: Указатель на выводимую строку.
  164.   */
  165. void hd44780_putstring(hd44780_state_t *state, uint8_t xpos, uint8_t ypos, char *str) {
  166.   while ((xpos < state->width - 1) && *str) {
  167.     state->data[xpos][ypos] = (char)(*str);
  168.     str++;
  169.     xpos++;
  170.   }
  171. }
  172.  
  173. void hd44780_update(hd44780_state_t *state) {
  174.   if (state->cursor_x == state->width) {
  175.     state->cursor_x = 0;
  176.     state->cursor_y++;
  177.     if (state->cursor_y == state->height) {
  178.       state->cursor_y = 0;
  179.     }
  180.     uint8_t addr = state->cursor_x;
  181.     switch (state->cursor_y) {
  182.       case 0:
  183.         addr += HD44780_STRING_1_OFFSET;
  184.         break;
  185.       case 1:
  186.         addr += HD44780_STRING_2_OFFSET;
  187.         break;
  188.       case 2:
  189.         addr += HD44780_STRING_3_OFFSET;
  190.         break;
  191.       case 3:
  192.         addr += HD44780_STRING_4_OFFSET;
  193.         break;
  194.     }
  195.     hd44780_write_cmd(state, HD44780_CMD_SETDDRAMADDR | addr);
  196.   } else {
  197.     hd44780_write_data(state, state->data[state->cursor_x][state->cursor_y]);
  198.     state->cursor_x++;
  199.   }
  200. }
RAW Paste Data