interface lcd and keypad with atmega88

Discussion in 'Embedded Systems and Microcontrollers' started by mr_l, May 5, 2012.

  1. mr_l

    Thread Starter New Member

    Aug 20, 2011
    12
    0
    Hello everyone.
    I am a bit stuck with one task and i need help.
    I am trying to read input from keypad and display it on the display.
    I first wrote the program code which reads the input from the keyboard and tested it with LEDs and it works
    well.
    Then I wrote code that prints text to display with no input from the keyboard and then tested it and it also
    works well.
    But when I put together whole code it does not work as it should.
    I am new in programming of embedded systems and i know
    that my code is not the best and that probably has a lot of mistakes but I try to do the best they can.
    Here is my code

    Code ( (Unknown Language)):
    1.  
    2. #define F_CPU 8000000UL
    3. #include <avr/io.h>
    4. #include <stdio.h>
    5. #include <util/delay.h>
    6.  
    7.  
    8.  
    9. #define RS 0 //pin nr in port
    10. #define RW 1 //pin nr in port
    11. #define E 2 //pin nr in port
    12.  
    13. FILE *myFile;
    14. void write_LCD(unsigned char data, FILE *stream);
    15. int get_char(FILE *stream);
    16. void write_instruction(unsigned char data);
    17. void init_LCD(void);
    18. void delay8us(void);
    19.  
    20.  
    21. void delay8us(void) {
    22. volatile unsigned char x;
    23. for(x=0;x<5;x++);
    24. }
    25.  
    26. void test_if_busy(void) {
    27. unsigned char x;
    28. PORTC &=~(1<<RS);
    29. PORTC |= (1<<RW);
    30. DDRB &=~(1<<7);     // input
    31. PORTB &=~(1<<7);    // remove pullup
    32. do {
    33. PORTC |= (1<<E);
    34. delay8us();
    35. x = (PINB & 0x80); // read high nibble
    36. PORTC &=~(1<<E);
    37. PORTC |= (1<<E);
    38. PORTC &=~(1<<E);    // read low nibble
    39.          
    40. }
    41. while(x);
    42. DDRB |= (1<<7); // output
    43. }
    44.  
    45. void write_LCD(unsigned char data, FILE *stream) {
    46. char x;
    47. PORTB = (data & 0xf0); //high nibble
    48. PORTC &=~(1<<RW);
    49. PORTC |= (1<<RS);
    50. PORTC |= (1<<E);
    51. PORTC &=~(1<<E);
    52. x = (data<<4);
    53.  _delay_ms(65);
    54. PORTB = x; //low nibble
    55. PORTC &=~(1<<RW);
    56. PORTC |=(1<<RS);
    57. PORTC |=(1<<E);
    58. PORTC &=~(1<<E);
    59. test_if_busy();
    60. }
    61.  
    62. char get_key(void)
    63. {
    64. volatile char button;
    65. volatile char position;
    66.  
    67. button = PINB;
    68.  
    69. if (button == 0b01111011)
    70. position = 49;
    71. else if (button == 0b01111101)
    72. position = 50;
    73. else if (button == 0b01111110)
    74. position = 51;
    75. else if (button == 0b10111011)
    76. position = 52;
    77. else if ( button == 0b10111101)
    78. position = 53;
    79. else if ( button == 0b10111110)
    80. position = 54;
    81. else if ( button == 0b11011011)
    82. position = 55;
    83. else if ( button == 0b11011101)
    84. position = 56;
    85. else if ( button == 0b11011110)
    86. position = 57;
    87. else if ( button == 0b11101011)
    88. position = 8;
    89. else if ( button == 0b11101011)
    90. position = 48;
    91. else if ( button == 0b11101101)
    92. position = 13;
    93. else if ( button == 0b11101110)
    94. position = 68;
    95. else if (button == 0b11101111)
    96. position = 5;
    97. return position;
    98. }
    99.  
    100.  
    101. int get_char(FILE *stream){
    102. char c;
    103. volatile char column;
    104. volatile char row;
    105.  
    106. do{
    107. row = 0b01111111;   // send 0 to first row
    108. for (int i = 0; i<2; i++){
    109. PORTB = row;
    110. column = PINB;      // read input from keypad
    111. }
    112.  
    113. for(int i = 0, a = 64; i<5; i++){  // check all 4 rows
    114. if(column == row)// if key is not pressed in first row
    115. row = column + a;       // check next row
    116. for(int j = 0; j < 2; j++){
    117. PORTB = row;
    118. column = PINB;
    119. }
    120. i++;
    121. a = a/2;
    122. }  
    123. else
    124. c = get_key();
    125. }
    126. c = get_key();
    127. }while(column == 0b11101111); // if neither key is not pressed repeat loop
    128.  
    129. write_LCD(c, stream);
    130. return (int)c;
    131.    
    132. }
    133.  
    134.  
    135. void write_instruction(unsigned char data) {
    136. unsigned char x;
    137.  
    138. PORTB = (data & 0xf0);
    139. PORTC &=~(1<<RW);
    140. PORTC &=~(1<<RS);
    141. PORTC |= (1<<E);
    142. PORTC &=~(1<<E);
    143. x = (data<<4);
    144. PORTB = x;
    145. PORTC &=~(1<<RW);
    146. PORTC &=~(1<<RS);
    147. PORTC |= (1<<E);
    148. PORTC &=~(1<<E);
    149. test_if_busy();
    150. }
    151.  
    152.  
    153. void set4bitmode() {
    154. _delay_ms(65);
    155. PORTB = (0x20 & 0xf0);
    156. PORTC &=~(1<<RW);
    157. PORTC &=~(1<<RS);
    158. PORTC |= (1<<E);
    159. PORTC &=~(1<<E);
    160. }
    161.  
    162.  
    163.  void init_LCD(void) {
    164. unsigned char x;
    165. for(x= 0;x<5;x++) {
    166. _delay_ms(65);
    167. }
    168. PORTB = 0; //all low
    169. PORTC &=~(1<<RS);
    170. PORTC &=~(1<<RW);
    171. PORTC &=~(1<<E);
    172. DDRB = 0xF0; // all output
    173. PORTB = 0x0F;
    174. DDRC |= (1<<RS);
    175. DDRC |= (1<<RW);
    176. DDRC |= (1<<E);
    177. _delay_ms(65);
    178. set4bitmode(); // 4 bit interface
    179. for(x=0;x<3;x++) {
    180. write_instruction(0x28);
    181. _delay_ms(65);
    182. }
    183. write_instruction(0x0F);
    184. write_instruction(6);
    185. write_instruction(1);
    186. }
    187.  
    188.  
    189. int main(void)
    190. {
    191. char teck;
    192. init_LCD();
    193. write_instruction(1); // clear display
    194. myFile = fdevopen(write_LCD, get_char);
    195.    
    196. while(1){
    197.  
    198. scanf("%c", &teck);
    199. printf("%d",teck);
    200. }
    201. }
    202.  
    203.  
     
  2. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Can you post a schematic of your circuit? That will give us crucial information needed to assist you with diagnosing your problem.

    hgmjr
     
  3. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Without a schematic it is difficult to confirm everything but from the looks of your code you are using PORTB for both the LCD display data as well as your keypad scanning function.

    Is that being done intentially?

    hgmjr
     
  4. mr_l

    Thread Starter New Member

    Aug 20, 2011
    12
    0
    Here is scheme of my circuit

    [​IMG]

    I solved the problem I changed port i mean i put all lcd pins
    on the PORTC and now it works. But now i have another problem.
    Number printing works fine but as soon as I press the letter or symbol it prints
    pressed letter and then lot of unpressed numbers.
    I thought first that this is due data types so i tested to change type of variable position in int type but the result was the same. Have you any idea what it could be.
     
  5. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Circuit diagram attachment did not appear. Can you try again?

    hgmjr
     
  6. mr_l

    Thread Starter New Member

    Aug 20, 2011
    12
    0
  7. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    I will have to wait until after work to view your schematic since the website that you used to post the schematic is blocked on my company network.

    hgmjr
     
  8. mr_l

    Thread Starter New Member

    Aug 20, 2011
    12
    0
    Ok thanks a lot.
     
  9. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,607
    Here's mr_l's schematic:

    [​IMG]

    (mr_l: in the advanced post window there is a box to hit to add in the url of pictures like this. The icon is a sun over a hill with a yellow sky.)
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,607
    I can't really follow your code but it seems there is no check for a key to be unpressed, meaning you press it once and then whenever the loops returns it again prints the key. Or possibly a debouncing issue.

    Has your code changed since you added it above?
     
  11. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    I think we could use an update to your code since you said that you have altered your code.
     
  12. mr_l

    Thread Starter New Member

    Aug 20, 2011
    12
    0
    I solved the problem. First as I said, I put all LCD pins on the portC
    and LCD started to work.
    Another problem I've solved so that I changed

    Code ( (Unknown Language)):
    1.  char get_key(void) into int get_key(void)
    because get_key function () should be returned characters ASCII value

    I then deleted the row
    Code ( (Unknown Language)):
    1.  write_LCD(c, stream);
    because it returns the value of printf () function and has nothing to do with scanf() function
    so
    Code ( (Unknown Language)):
    1.  int get_char(FILE *stream)
    function returns value to scanf() function
    and the last thing I changed is in main() function
    Code ( (Unknown Language)):
    1.  
    2. printf("%d",teck); into
    3. printf("%c",teck);
    4.  
    And as I said, now it works well
    In any case thanks for the help guys
     
    Last edited: May 12, 2012
  13. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Can we please request that you put your latest code (That works) into this thread so that future users can have the benefit of seeing your solution?

    hgmjr
     
Loading...