University projects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

141 lines
3.1 KiB

  1. /* LCD 4-bit driver
  2. *
  3. * Authors: Sam Black, Sam Burras, Ben Francis
  4. *
  5. * Derived from Custom Computer Services
  6. * (C) Copyright 1996, 2003 LCD.C
  7. *
  8. * Version 1.0 Date: 07/02/07
  9. *
  10. */
  11. struct lcd_pin_map {
  12. boolean rs;
  13. boolean rw;
  14. boolean enable;
  15. boolean button;
  16. int data : 4;
  17. };
  18. /* Create structs to map I/O */
  19. struct lcd_pin_map lcd;
  20. struct lcd_pin_map lcd_dir;
  21. /* Set ports up correctly */
  22. #byte lcd=0x06
  23. #byte lcd_dir=0x86
  24. /* Send initialization sequence */
  25. /* No cursor */
  26. byte CONST lcd_init_nocursor[4] = {0x28, 0x0C, 0x01, 0x06};
  27. /* Cursor */
  28. byte CONST lcd_init_cursor[4] = {0x28, 0x0E, 0x01, 0x06};
  29. /* Scrolling */
  30. byte CONST lcd_init_scrolling[4] = {0x20, 0x0C, 0x01, 0x05};
  31. /* Set direction of pins to send chars to LCD */
  32. /* RS, RW, ENABLE, BUTTON, DATA */
  33. struct lcd_pin_map CONST lcd_write = {0, 0, 0, 1, 0};
  34. /* Set direction of pins to read status from LCD */
  35. struct lcd_pin_map CONST lcd_read = {1, 0, 0, 1, 1};
  36. /* Based on lcd.c */
  37. void lcd_send_nibble( byte n ) {
  38. lcd.enable = 1;
  39. delay_us(50);
  40. lcd.data = n;
  41. delay_ms(1);
  42. lcd.enable = 0;
  43. delay_us(50);
  44. }
  45. /* Based on lcd.c */
  46. void lcd_send_byte( byte address, byte n ) {
  47. /* Set port direction */
  48. lcd_dir = lcd_write;
  49. /* Set what we are writing to */
  50. /* 0 is Instruction */
  51. /* 1 is Data */
  52. lcd.rs = address;
  53. /* Write to LCD */
  54. lcd.rw = 0;
  55. delay_us(500);
  56. lcd_send_nibble(n>>4);
  57. delay_ms(1);
  58. lcd_send_nibble(n & 0xf);
  59. /* Reset RW/RS */
  60. lcd.rw = 1;
  61. lcd.rs = 0;
  62. delay_us(500);
  63. }
  64. /* Based on lcd.c */
  65. boolean lcd_read_status() {
  66. boolean status;
  67. /* Set port direction */
  68. lcd_dir = lcd_read;
  69. /* Read from the LCD */
  70. lcd.rw = 1;
  71. delay_us(1);
  72. lcd.enable = 1;
  73. delay_us(1);
  74. status = lcd.rs;
  75. lcd.enable = 0;
  76. delay_us(2);
  77. /* Return the status */
  78. return(status);
  79. }
  80. /* Based on lcd.c */
  81. void lcd_init(int init) {
  82. int i;
  83. lcd_dir = lcd_write;
  84. lcd.rs = 0;
  85. lcd.rw = 0;
  86. lcd.enable = 0;
  87. delay_ms(15);
  88. for(i=0; i<=3; i++) {
  89. lcd_send_nibble(0x03);
  90. delay_ms(5);
  91. }
  92. /* Semd extra init nibble */
  93. lcd_send_nibble(0x02);
  94. delay_ms(5);
  95. switch (init) {
  96. case 1 : for(i=0; i<=3; i++)
  97. lcd_send_byte(0, lcd_init_nocursor[i]); break;
  98. case 2 : for(i=0; i<=3; i++)
  99. lcd_send_byte(0, lcd_init_cursor[i]); break;
  100. case 3 : for(i=0; i<=3; i++)
  101. lcd_send_byte(0, lcd_init_scrolling[i]); break;
  102. default : for(i=0; i<=3; i++)
  103. lcd_send_byte(0, lcd_init_nocursor[i]); break;
  104. }
  105. }
  106. /* Based on lcd.c */
  107. void lcd_putc( char c ) {
  108. switch (c) {
  109. /* clear the screen */
  110. case '\f' : lcd_send_byte(0, 0x01);
  111. delay_ms(2); break;
  112. /* back space */
  113. case '\b' : lcd_send_byte(0, 0x08); break;
  114. /* new line */
  115. case '\n' : lcd_send_byte(0, 0xC0); break;
  116. default : lcd_send_byte(1, c); break;
  117. }
  118. }