Advertisement
Guest User

Untitled

a guest
Aug 29th, 2013
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. /*
  3. The circuit:
  4.  * LCD RS pin       to digital pin 11
  5.  * LCD R/W pin      to digital pin 12
  6.  * LCD Enable pin   to digital pin 13
  7.  * LCD D0 pin       to digital pin 0
  8.  * LCD D1 pin       to digital pin 1
  9.  * LCD D2 pin       to digital pin 2
  10.  * LCD D3 pin       to digital pin 3
  11.  * LCD D4 pin       to digital pin 4
  12.  * LCD D5 pin       to digital pin 5
  13.  * LCD D6 pin       to digital pin 6
  14.  * LCD D7 pin       to digital pin 7
  15.  */
  16.  
  17. // commands
  18. #define LCD_CLEARDISPLAY 0x01
  19. #define LCD_RETURNHOME 0x02
  20. #define LCD_ENTRYMODESET 0x04
  21. #define LCD_DISPLAYCONTROL 0x08
  22. #define LCD_CURSORSHIFT 0x10
  23. #define LCD_FUNCTIONSET 0x20
  24. #define LCD_SETCGRAMADDR 0x40
  25. #define LCD_SETDDRAMADDR 0x80
  26.  
  27. // flags for display entry mode
  28. #define LCD_ENTRYRIGHT 0x00
  29. #define LCD_ENTRYLEFT 0x02
  30. #define LCD_ENTRYSHIFTINCREMENT 0x01
  31. #define LCD_ENTRYSHIFTDECREMENT 0x00
  32.  
  33. // flags for display on/off control
  34. #define LCD_DISPLAYON 0x04
  35. #define LCD_DISPLAYOFF 0x00
  36. #define LCD_CURSORON 0x02
  37. #define LCD_CURSOROFF 0x00
  38. #define LCD_BLINKON 0x01
  39. #define LCD_BLINKOFF 0x00
  40.  
  41. // flags for display/cursor shift
  42. #define LCD_DISPLAYMOVE 0x08
  43. #define LCD_CURSORMOVE 0x00
  44. #define LCD_MOVERIGHT 0x04
  45. #define LCD_MOVELEFT 0x00
  46.  
  47. // flags for function set
  48. #define LCD_8BITMODE 0x10
  49. #define LCD_4BITMODE 0x00
  50. #define LCD_2LINE 0x08
  51. #define LCD_1LINE 0x00
  52. #define LCD_5x10DOTS 0x04
  53. #define LCD_5x8DOTS 0x00
  54.  
  55. #define RS 0x08
  56. #define RW 0x10
  57. #define EN 0x20
  58.  
  59. #define LCD_4_BITS
  60.  
  61. #ifdef LCD_4_BITS
  62. #define LCD_X_BITMODE LCD_4BITMODE
  63. #else
  64. #define LCD_X_BITMODE LCD_8BITMODE
  65. #endif
  66.  
  67. uint8_t initCmd = LCD_FUNCTIONSET | LCD_X_BITMODE | LCD_2LINE | LCD_5x8DOTS;
  68. uint8_t displayOn = LCD_DISPLAYCONTROL | LCD_DISPLAYON;// | LCD_BLINKON | LCD_CURSORON;
  69. uint8_t displayMode = LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  70.  
  71. void command(uint8_t cmd);
  72. void write4bits(uint8_t data, uint8_t cmd, bool noWait);
  73. void write(uint8_t data, uint8_t rs = RS, bool noWait = false);
  74. void clearDisplay(bool hwClear = false);
  75.  
  76.  
  77. void setup()
  78. {  
  79.     // Set all relevant pins as output
  80. #ifdef LCD_4_BITS
  81.     DDRD = 0xF0;
  82. #else
  83.     DDRD = 0xFF;
  84. #endif
  85.     PORTD &= 0x0F;
  86.  
  87.     DDRB |= 0x3E;
  88.     PORTB = (PORTB & 0xC1) | 0x6;
  89.    
  90.     initLcd();
  91. }
  92.  
  93. uint8_t startChar = 0;
  94.  
  95. void loop()
  96. {
  97.     unsigned long time = micros();
  98.     command(LCD_SETDDRAMADDR);
  99.     waitLcdBusy();
  100.     time = micros() - time;
  101.     time = micros();
  102.     for (uint8_t i = 0; i < 80; i++)
  103.         write(startChar + i);
  104.     time = micros() - time;
  105.     // Set LCD write direction to right to left so that the numbers are printed in the correct order.
  106.     command(LCD_ENTRYMODESET);
  107.     command(LCD_SETDDRAMADDR|0x45);
  108.     write(' ');
  109.     do {
  110.         unsigned long m = time;
  111.         time /= 10;
  112.         uint8_t c = m - 10 * time;
  113.         write(c + '0');
  114.     } while(time);
  115.     write(' ');
  116.     command(LCD_ENTRYMODESET | LCD_ENTRYLEFT);
  117.     startChar++;
  118.     if (startChar >= 49)
  119.         startChar = 0;
  120.     delay(1000);
  121. }
  122.  
  123.  
  124. void initLcd()
  125. {
  126.     // Initialization sequence
  127.     delay(50);
  128. #ifdef LCD_4_BITS
  129.     write4bits(0x03, 0, true);
  130.     delayMicroseconds(4500);
  131.     write4bits(0x03, 0, true);
  132.     delayMicroseconds(150);
  133.     write4bits(0x03, 0, true);
  134.     delayMicroseconds(150);
  135.     write4bits(0x02, 0, true);
  136.     delayMicroseconds(150);
  137. #else
  138.     write(initCmd, 0, true);
  139.     delayMicroseconds(4500);
  140.     write(initCmd, 0, true);
  141.     delayMicroseconds(150);
  142.     write(initCmd, 0, true);
  143.     delayMicroseconds(150);
  144. #endif
  145.     write(initCmd, 0, true);
  146.     delayMicroseconds(150);
  147.     command(LCD_DISPLAYCONTROL | LCD_DISPLAYOFF);  
  148.     command(LCD_CLEARDISPLAY);
  149.     command(displayMode);
  150.     // ----------------------------
  151.  
  152.     command(displayOn);
  153.     command(LCD_RETURNHOME);
  154. }
  155.  
  156.  
  157.  
  158. void command(uint8_t cmd)
  159. {
  160.     write(cmd, 0);
  161. }
  162.  
  163. void write4bits(uint8_t data, uint8_t cmd, bool noWait)
  164. {
  165.     cmd |= EN;
  166.    
  167.     // While LCDs DB7 pin is high, busy-wait.
  168.     if (!noWait) waitLcdBusy();
  169.  
  170.     // Write data.
  171.     PORTD = (PORTD & 0x0F) | (data & 0xF0);
  172.  
  173.     // Issue Enable
  174.     PORTB = (PORTB & 0xC7) | cmd;
  175.     delayMicroseconds(1);
  176.     PORTB &= ~cmd;
  177. }
  178.  
  179. void write(uint8_t data, uint8_t cmd, bool noWait)
  180. {
  181. #ifdef LCD_4_BITS
  182.     write4bits(data, cmd, noWait);
  183.     delayMicroseconds(1);
  184.     write4bits(data << 4, cmd, true);  
  185. #else
  186.     cmd |= EN;
  187.    
  188.     // While LCDs DB7 pin is high, busy-wait.
  189.     if (!noWait) waitLcdBusy();
  190.  
  191.     // Write data.
  192.     PORTD = data;
  193.  
  194.     // Issue Enable
  195.     PORTB = (PORTB & 0xC7) | cmd;
  196.     delayMicroseconds(1);
  197.     PORTB &= ~cmd;
  198. #endif
  199. }
  200.  
  201. void waitLcdBusy()
  202. {
  203.     bool ret = false;
  204.  
  205.     // Set bit 7 of portD as input.
  206.     DDRD &= ~0x80;
  207.  
  208.     PORTB = (PORTB & 0xC7) | RW;
  209.     do
  210.     {
  211.         // Read busy flag from DB7.
  212.         PORTB |= EN;
  213.         delayMicroseconds(1);
  214.         ret = (PIND & 0x80) != 0;
  215.         PORTB &= ~EN;
  216. #ifdef LCD_4_BITS
  217.         // Read AC3 - as per HD44780 Datasheet, page 32 Interfacing the HD47780U - 4 bit mode.
  218.         delayMicroseconds(1);
  219.         PORTB |= EN;
  220.         delayMicroseconds(1);
  221.         PORTB &= ~EN;
  222. #endif
  223.     } while (ret);
  224.    
  225.     PORTB &= ~RW;
  226.     // Set bit 7 of portD to output.
  227.     DDRD |= 0x80;  
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement