Advertisement
hbinderup94

lcd162.c

Feb 11th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.70 KB | None | 0 0
  1. /*-------------------------------------------------------------------
  2.   File name: "lcd162.c"
  3.  
  4.   Driver for "LCD Keypad Shield" alphanumeric display.
  5.   Display controller = HD44780U (LCD-II).
  6.  
  7.   Max. uC clock frequency = 16 MHz (Tclk = 62,5 ns)
  8.  
  9.   Connection : PORTx (4 bit mode) :
  10.   [LCD]        [Portx]
  11.   RS   ------  PH 5
  12.   RW   ------  GND
  13.   E    ------  PH 6
  14.   DB4  ------  PG 5
  15.   DB5  ------  PE 3
  16.   DB6  ------  PH 3
  17.   DB7  ------  PH 4
  18.  
  19.   Henning Hargaard, February 5, 2018
  20. ---------------------------------------------------------------------*/
  21.  
  22. #define F_CPU 16000000
  23. // ADC values for button presses
  24. #define BUTTON_SELECT 540
  25. #define BUTTON_LEFT 308
  26. #define BUTTON_UP 50
  27. #define BUTTON_DOWN 155
  28. #define BUTTON_RIGHT 0
  29. #define NO_KEY_PRESSED 1000
  30.  
  31. #include <avr/io.h>
  32. #include <util/delay.h>
  33. // Enabling us to use macro _NOP() to insert the NOP instruction
  34. #include <avr/cpufunc.h>
  35. #include "lcd162.h"
  36.  
  37. // library function itoa() is needed
  38. #include <stdlib.h>
  39.  
  40. //*********************** PRIVATE (static) operations *********************
  41. static void waitBusy()
  42. {
  43.   _delay_ms(2);
  44. }  
  45.  
  46. static void pulse_E()
  47. {
  48.   PORTH = PORTH | (1<<6);   // Enable E (PH6)
  49.  
  50.   // min 230ns delay
  51.   _NOP();
  52.   _NOP();
  53.   _NOP();
  54.   _NOP();
  55.  
  56.   PORTH = PORTH & ~(1<<6);  // Disable E (PH6)
  57.  
  58.   // Fit cycle time
  59.   _NOP();
  60.   _NOP();
  61. }
  62.  
  63. // Sets the display data pins according to the 4 lower bits of data
  64. static void set4DataPins(unsigned char data)
  65. {
  66.   PORTH = (PORTH & 0b11100111) | ((data<<1) & 0b00011000);
  67.   PORTE = (PORTE & 0b11110111) | ((data<<2) & 0b00001000);
  68.   PORTG = (PORTG & 0b11011111) | ((data<<5) & 0b00100000);  
  69. }
  70.  
  71. static void sendInstruction(unsigned char data)
  72. {      
  73.     unsigned char msb_data = (data>>4);
  74.     waitBusy(); // To make sure that previous tasks are done
  75.  
  76.     // Send MS 4 bits
  77.     PORTH &= 0b10010000;    // RS and E low for instructions
  78.     set4DataPins(msb_data);
  79.     pulse_E();
  80.        
  81.     set4DataPins(data);
  82.     pulse_E();
  83. }
  84.  
  85. static void sendData(unsigned char data)
  86. {      
  87.     unsigned char msb_data = (data>>4);
  88.     waitBusy(); // To make sure that previous tasks are done
  89.     PORTH = PORTH | (1<<5); // Enable RS for data
  90.     PORTH = PORTH & ~(1<<6); // E=0 to enable E pulse
  91.  
  92.     set4DataPins(msb_data);
  93.     pulse_E();
  94.  
  95.     set4DataPins(data);
  96.     pulse_E();
  97.     _delay_us(0.5);
  98.     PORTH = PORTH & ~(1<<5);    // Disable RS  
  99. }
  100.  
  101. //*********************** PUBLIC functions *****************************
  102.  
  103. // Initializes the display, blanks it and sets "current display position"
  104. // at the upper line, leftmost character (cursor invisible)
  105. // Reference: Page 46 in the HD44780 data sheet
  106. void LCDInit()
  107. {
  108.   // Initializing the used port
  109.   DDRH |= 0b01111000;  // Outputs
  110.   DDRE |= 0b00001000;
  111.   DDRG |= 0b00100000;
  112.   DDRF |= 0b00000001;   // Keys as input
  113.  
  114.  
  115.   // Wait 50 ms (min. 15 ms demanded according to the data sheet)
  116.   _delay_ms(50);
  117.   // Function set (still 8 bit interface)
  118.   PORTG |= 0b00100000;
  119.   PORTE |= 0b00001000;
  120.   pulse_E();
  121.  
  122.   // Wait 10 ms (min. 4,1 ms demanded according to the data sheet)
  123.   _delay_ms(10);
  124.   // Function set (still 8 bit interface)
  125.   pulse_E();
  126.  
  127.   // Wait 10 ms (min. 100 us demanded according to the data sheet)
  128.   _delay_ms(10);
  129.   // Function set (still 8 bit interface)
  130.   pulse_E();
  131.  
  132.   // Wait 10 ms (min. 100 us demanded according to the data sheet)
  133.   _delay_ms(10);
  134.   // Function set (now selecting 4 bit interface !)
  135.   PORTG &= 0b11011111;
  136.   pulse_E();
  137.  
  138.   // Function Set : 4 bit interface, 2 line display, 5x8 dots
  139.   sendInstruction( 0b00101000 );
  140.   // Display, cursor and blinking OFF
  141.   sendInstruction( 0b00001000 );
  142.   // Clear display and set DDRAM adr = 0   
  143.   sendInstruction( 0b00000001 );
  144.   // By display writes : Increment cursor / no shift
  145.   sendInstruction( 0b00000110 );
  146.   // Display ON, cursor and blinking OFF
  147.   sendInstruction( 0b00001100 );
  148. }
  149.  
  150. // Blanks the display and sets "current display position" to
  151. // the upper line, leftmost character
  152. void LCDClear()
  153. {
  154.     sendInstruction(0b00000001);
  155. }
  156.  
  157. // Sets DDRAM address to character position x and line number y
  158. void LCDGotoXY( unsigned char x, unsigned char y )
  159. {
  160.   // To be implemented
  161.     unsigned char instruction = 0b10000000;
  162.     if (y == 0)
  163.         instruction |= x ;
  164.     else if (y == 1)
  165.         instruction |= (0b11000000 | x);    // Shifted 0x40 as second line starts there
  166.  
  167.     sendInstruction(instruction);
  168. }
  169.  
  170. // Display "ch" at "current display position"
  171. void LCDDispChar(char ch)
  172. {
  173.     sendData(ch);
  174. }
  175.  
  176. // Displays the string "str" starting at "current display position"
  177. void LCDDispString(char* str)
  178. {
  179.     for (uint8_t i = 0; i < strlen(str); i++)
  180.     {
  181.     LCDDispChar(str[i]);
  182.     }
  183. }
  184.  
  185. // Displays the value of integer "i" at "current display position"
  186. void LCDDispInteger(int i)
  187. {
  188.     char buffer [40];
  189.     itoa(i, buffer, 10);
  190.     LCDDispString(buffer);
  191. }
  192.  
  193. // Loads one of the 8 user definable characters (UDC) with a dot-pattern,
  194. // pre-defined in an 8 byte array in FLASH memory
  195. void LCDLoadUDC(unsigned char UDCNo, const unsigned char *UDCTab)
  196. {
  197.   // To be implemented     
  198. }
  199.  
  200. // Selects, if the cursor has to be visible, and if the character at
  201. // the cursor position has to blink.
  202. // "cursor" not 0 => visible cursor.
  203. // "blink" not 0 => the character at the cursor position blinks.
  204. void LCDOnOffControl(unsigned char cursor, unsigned char blink)
  205. {
  206.     unsigned char controlBit = 0b00001111;
  207.  
  208.     if (cursor == 0)
  209.         controlBit &= ~(1<<1);
  210.     if (blink == 0)  
  211.         controlBit &= ~(1<<0);
  212.  
  213.     sendInstruction(controlBit);
  214. }
  215.  
  216. // Moves the cursor to the left
  217. void LCDCursorLeft()
  218. {
  219.       unsigned char controlBit = 0b00010000;
  220.       sendInstruction(controlBit);
  221. }
  222.  
  223. // Moves the cursor to the right
  224. void LCDCursorRight()
  225. {
  226.       unsigned char controlBit = 0b00010100;
  227.       sendInstruction(controlBit);
  228. }
  229.  
  230. // Moves the display text one position to the left
  231. void LCDShiftLeft()
  232. {
  233.     unsigned char controlBit = 0b00011000;
  234.     sendInstruction(controlBit);
  235. }
  236.  
  237. // Moves the display text one position to the right
  238. void LCDShiftRight()
  239. {
  240.       unsigned char controlBit = 0b00011100;
  241.       sendInstruction(controlBit);
  242. }
  243.  
  244. // Sets the backlight intensity to "percent" (0-100)
  245. void setBacklight(unsigned char percent)
  246. {
  247.   // To be implemented
  248. }
  249.  
  250. // Reads the status for the 5 on board keys
  251. // Returns 0, if no key pressed
  252. unsigned char readKeys()
  253. {
  254.     int keyValue = ADCW;
  255.  
  256.     if (keyValue >= NO_KEY_PRESSED)
  257.         return 0;
  258.  
  259.     if (keyValue >= BUTTON_SELECT)
  260.     {
  261.         LCDDispString("Select");
  262.         return 1;
  263.     }
  264.     else if (keyValue >= BUTTON_LEFT)
  265.     {
  266.         LCDCursorLeft();
  267.         return 1;
  268.     }
  269.     else if (keyValue >= BUTTON_DOWN)
  270.     {
  271.         LCDDispString("Down");
  272.         return 1;
  273.     }
  274.      else if (keyValue >= BUTTON_UP)
  275.      {
  276.         LCDDispString("Up");
  277.         return 1;
  278.     }
  279.     else if (keyValue >= BUTTON_RIGHT)
  280.     {
  281.         LCDCursorRight();
  282.         return 1;
  283.     }
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement