3x4 keypad and Lcd Display

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

first of all this is my first post and i want to say a big "HELLO" to everyone...

well i think u can help me in my problem:

i need to programmize in C code an ATmega16 trough AVR STK500...i am using

>>the ATmelstudio7.0 compiler

>> LCD-display 4x16 character with first address =[0x80, 0xC0, 0x90, 0xD0]

>> Keypad look like this:

// "C6"   "C5"   "C4"

// COL6 COL5 COL4

//   1       2      3    ROW 1 "C3"

//   4       5      6    ROW 2 "C2"

//   7       8      9    ROW 3 "C1"

//   *       0      #   ROW 4 "C0"

I have tow problems

First

Then proceed with the programming. It must

First a memory area 4x16 in the RAM of the processor is described

and this memory area will be copied to the display.They will only work in this RAM space after eachIt is simply copied into the display, the display is only one.

Second

I need to used the 3x4 Keypad for future programming.

 

I found a suitable example keypad but something is missing because the code does not work.
Can someone tell me what is wrong in the keypad and hand part?
Below you will see the code.

-----------------------------------------  lcd.h --------------------------------------------

#define  F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

 

#ifndef LCD_H_
#define LCD_H_

#define LCD_Scrib                 PORTA
#define DataDir_LCD_Scrib    DDRA
#define LCD_Control              PORTB
#define DataDir_LCD_Control DDRB

 

#define LCD_RS           0
#define LCD_Enable     1

 

#define LCD_AkkuB2    2
#define LCD_AkkuB3    3

 

#define D_Sub                    DDRD
#define Sub_Control            PORTD

 

#define NOP() asm volatile("nop"::);

#define KEY_PIN           PINC
#define KEY_PORT        PORTC
#define KEY_DDR         DDRC

void instr_to_dis(unsigned char command);            //function:  Send a command
void date_to_dis(unsigned char character);            //function:  Send a character 
void LCD_Print(char *string);
void LCD_init(void);
void LCD_goto(unsigned char x, unsigned char y);
void LCD_Akku(void);
void Aschluss_D_Sub(void);

 

void tasten(void);

uint8_t keyscan(void);
uint8_t key_debounce( void );

 

#endif /* LCD_H_ */

 

----------------------------------- ldc.c -----------------------------------

/*
 * lcd.c
 *
 * Created: 27.09.2016 14:07:05
 *  Author: Ngangoum
 */ 
#define  F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>

#include "lcd.h"

const char Line_Address []={0x80,0xC0,0x90,0xD0};    // 4x16 lcd_Display

Aschluss_D_Sub()
{
    D_Sub = 0xFF;                    // PÓRTD as output
    
}

// void Tasten()
// {
//     //Data_Tasten = 0x70;                //0b01110000 PCx(x=0,1,2 and 3 as input)
//     
//     
// } 

void LCD_Akku()
{
    DataDir_LCD_Control &= ~((1<< LCD_AkkuB2) | (1<< LCD_AkkuB3));    // B2 and B3 of input setting 
    LCD_Control = 0x0C;                                                // 0b00001100 
    
}

void LCD_init()
{
    DataDir_LCD_Scrib = 0xFF;                            //PortA is output (DDR=0xFF)
    DataDir_LCD_Control |= 1<<LCD_RS | 1<<LCD_Enable;    // E and RS of output an PORTB setting 
    _delay_ms(100);
    LCD_Control = 0xFC;        // ob11111100 (rs & e of low )
    
    instr_to_dis(0x01);        //Clear Screen 0x01 = 0b00000001
    _delay_ms(2);
    instr_to_dis(0x38);        //Set Function 0b00001110 (8 bits interface, 2 line display and 5x7  dots Matrix) 
    _delay_us(50);
    instr_to_dis(0x0C);        //Display on/off 0b00001111 (Display 0n, cursor 0n and Blinking 0n)
    _delay_us(50);
    instr_to_dis(0x80);        //Set DDRAM Address 0b10000000
    _delay_us(50); 
    
}

void instr_to_dis(unsigned char command)
{
    
    LCD_Scrib = command;
    LCD_Control &= ~(1<<LCD_RS);        // RS turn of 0 (instruction)
    LCD_Control |= (1<<LCD_Enable);        // E turn of  1 
    NOP();
    NOP();
    LCD_Control &= ~(1<<LCD_Enable);    // E turn of  0
    _delay_us(100);
    
}

void data_to_dis(unsigned char character)
{
    
    LCD_Scrib = character;    
    LCD_Control |= (1<<LCD_RS);            // RS turn of 1 (data)
    LCD_Control |= (1<<LCD_Enable);        // E turn of  1
    NOP();
    NOP();
    LCD_Control &= ~(1<<LCD_Enable);    // E turn of  0
    _delay_us(100);
    
}

/* Diese Funktion bewegt der Cursor (Zeile y ,Spalte x) an dem LCD Module*/
void LCD_goto(unsigned char y, unsigned char x)
{
                                                
    instr_to_dis(Line_Address[y-1] + x-1);
    _delay_ms(10);
}

void LCD_Print(char *string)
{
    unsigned char i;
    
    while(string[i]!=0)
    {
        data_to_dis(string[i]);                    // Send a character in string format
        i++;
    }

//Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
unsigned char Memory(unsigned char row, unsigned char column)
{
     
        DataDir_LCD_Scrib = 0x80 ;                //PortA7 is output (DDR=0b10000000)
        instr_to_dis(0x80);                     // MSB = 1 set of DD-RAM
        row = Line_Address[row];
        row += column;
        instr_to_dis(row);
    
}

-------------------------------------tasten.c ---------------------------------------------------

 

#define  F_CPU 4000000UL
#include <avr/io.h>
#include <avr/pgmspace.h>        
#include <avr/interrupt.h>       
#include <stdlib.h>
#include <util/delay.h>

#include "lcd.h"

uint8_t keyscan(void);
uint8_t key_debounce( void );

#define KEY_PIN         PINC
#define KEY_PORT        PORTC
#define KEY_DDR         DDRC 

 

// "C6"   "C5"   "C4"                            C6-->PINC6 ..

// COL6 COL5 COL4

//   1       2      3    ROW 1 "C3"            C3--> PINC3

//   4       5      6    ROW 2 "C2"              .

//   7       8      9    ROW 3 "C1"              .

//   *       0      #    ROW 4 "C0"             .

 

uint8_t keyscan(void)
{
    uint8_t col = 0, row = 0;

    KEY_PORT |= 0x7F;                                // all pullups on (0b01111111)
    KEY_DDR = (KEY_DDR & 0x80) | 0x0F;    // pin 0..3 = input (0x70 =0b01110000)
    KEY_PORT &= 0x8F;                               // pin 0..3 = input low (0x8F =0b10001111)
    NOP();                                                  // wait until inputs sampled
    NOP();  
    if( ~KEY_PIN & 1<<0 )                           // if pin 0 = low
    col = 4;
    if( ~KEY_PIN & 1<<1 )
    col = 3;
    if( ~KEY_PIN & 1<<2 )
    col = 2;
    if( ~KEY_PIN & 1<<3 )
    col = 1;
    row = col;
    if( col ){                                                   // if column found, check row
        KEY_PORT |= 0x7F;                              // all pullups on (0b01111111)
        KEY_DDR = (KEY_DDR & 0x80) | 0x70;  // pin 4..6 = output
        KEY_PORT &= 0xF0;                             // pin 4..6 = output low
        NOP();                                                 // wait until inputs sampled
        if( ~KEY_PIN & 1<<4 )
        row = 5;
        if( ~KEY_PIN & 1<<5 )
        row = 9;
        if( ~KEY_PIN & 1<<6 )
        row = 13;
    }                                                     // 0 = no key
    return row - col;                               // 1..12 = key
}
uint8_t key_debounce( void )                // should be called every 5 .. 50ms
{
    static uint8_t oldkey, debounce;
    uint8_t key = keyscan();

    if( oldkey != key ){
        oldkey = key;
        debounce = 4;
    }
    if( debounce && --debounce == 0 )
    return key;
    return 0;
}

 

------------------------------------------   main ------------------------------------------

/*
 * Pr5.c
 *
 * Created: 08.09.2016 19:25:44
 * Author : Ngangoum
 */ 

#define  F_CPU 4000000UL
#include <avr/io.h>
#include <avr/pgmspace.h>            //supports storing strings & arrays in flash
#include <avr/interrupt.h>            //supports interrupts
#include <stdlib.h>
#include <util/delay.h>

#include "lcd.h"

 

int main(void)
{
   
    LCD_init();   

//     LCD_Print("Eternel!");
//     LCD_goto(3,1);
 

while(1)
{    
    
    Memory(4,16);
    instr_to_dis(0x01);                        // Clear screen
    data_to_dis(key_debounce());        // Echo the key pressed to LCD
}

    
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Etie wrote:
because the code does not work.
That's not much of a fault report. What did you expect to happen? What actually happened? Is the fault in the LCD output stuff or the keyboard input stuff? (and if you don't know you aren't developing in a modular way!)

 

In passing I would just point out that by default PC4..PC7 of a mega16 are not immediately usable as the chip comes with JTAG switched on and it uses those 4 pins. So what have you done about switching it off? I don't see any JTD writes in the code so I assume you have deactivated the JTAGEN fuse?

 

PS "Hallo" to you too!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey 

thanks for your support

 

i haven´t  deactivated the  JTAGEN.

Currently I do not get anything on the display (no reaction after I had pressed on the keyboard buttons)
I want to use the Keyboard Buttons at the futury
for example:
Button 1 must allow me to display some message .
Button # must allow me to choose a value from a list.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

device configuration

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well until you add lines to your program to write JTD twice or you change the state of that JTAGEN fuse you cannot use the top 4 bits of PORTC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey

Can you help me with an example, because I am still neophyte in C and micontroller.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have shot the JTAG.
And then how do I go about to operate the touch keyboard.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

while(1)
{    
    
    Memory(4,16);
    instr_to_dis(0x01);                        // Clear screen
    data_to_dis(key_debounce());        // Echo the key pressed to LCD
}

 

Lcd needs ascii code.

E.g. you send number 8 to Lcd, but you have to send 0x38  (ascii(8) = 0x38) 

For numbers 0-9 try

while(1)
{    
    Memory(4,16);
    instr_to_dis(0x01);                        // Clear screen
    data_to_dis(key_debounce() + 0x30);        // Echo the key pressed to LCD
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is true.
However I would like the reaction after you have pressed the button on the keyboard.
The keyboard does not react. That's my problem.
What should I do to make the functional keyboard.

for example:
I would like to display "N" position (4.1) if I press the button 1.

uint8_t keyscan(void)
{
    uint8_t col = 0, row = 0;

    KEY_PORT |= 0x7F;                     // all pullups on (0b01111111)
    KEY_DDR = (KEY_DDR & 0x80) | 0x0F;    // pin 0..3 = input (0x70 =0b01110000)
    KEY_PORT &= 0x8F;                     // pin 0..3 = input low (0x8F =0b10001111)
    NOP();                                // wait until inputs sampled
    NOP();
    if( ~KEY_PIN & 1<<0 )                 // if pin 0 = low
    col = 4;    
    if( ~KEY_PIN & 1<<1 )          // is that right?
    col = 3;
    LCD_goto(4,1);
    LCD_Print("N");

    if( ~KEY_PIN & 1<<2 )
    col = 2;
    if( ~KEY_PIN & 1<<3 )
    col = 1;

    row = col;
    if( col ){                                // if column found, check row
        KEY_PORT |= 0x7F;                   // all pullups on (0b01111111)
        KEY_DDR = (KEY_DDR & 0x80) | 0x70;  // pin 4..6 = output
        KEY_PORT &= 0xF0;                   // pin 4..6 = output low
        NOP();                              // wait until inputs sampled
        if( ~KEY_PIN & 1<<4 )
        row = 5;
        if( ~KEY_PIN & 1<<5 )
        row = 9;
        if( ~KEY_PIN & 1<<6 )
        row = 13;
    }                                        // 0 = no key
    return row - col;                        // 1..12 = key
}
uint8_t key_debounce( void )                // should be called every 5 .. 50ms
{
    static uint8_t oldkey, debounce;
    uint8_t key = keyscan();

    if( oldkey != key ){
        oldkey = key;
        debounce = 4;
    }
    if( debounce && --debounce == 0 )
    return key;
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can anyone help me with a 3x4 keyboard code that works and where I could use any of these button to display something.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is this what you need?

 

/* KEYPAD

	COL1 ->	PA6
	COL2 ->	PA5
	COL3 ->	PA4

	ROW1 ->	PA3
	ROW2 -> PA2
	ROW3 ->	PA1
	ROW4 -> PA0
*/

#define KEYPAD A	//KEYPAD IS ATTACHED ON PORTA (change as needed)

//Don't Touch the lines below
//*******************************
#define KEYPAD_PORT PORT(KEYPAD)
#define KEYPAD_DDR 	DDR(KEYPAD)
#define KEYPAD_PIN 	PIN(KEYPAD)
//*******************************

/*******************************************

Function return the keycode of keypressed
on the Keypad. Keys are numbered as follows

[00] [01] [02]
[03] [04] [05]
[06] [07] [08]
[09] [10] [11]

Arguments:
	None

Return:
	Any number between 0-11 depending on
	keypressed.

	255 (hex 0xFF) if NO keypressed.

Precondition:
	None. Can be called without any setup.

*******************************************/
uint8_t GetKeyPressed()
{
	uint8_t r,c;

	KEYPAD_PORT|= 0X0F;

	for(c=0;c<3;c++)
	{
		KEYPAD_DDR&=~(0X7F);

		KEYPAD_DDR|=(0X40>>c);
		for(r=0;r<4;r++)
		{
			if(!(KEYPAD_PIN & (0X08>>r)))
			{
				return (r*3+c);
			}
		}
	}

	return 0XFF;//Indicate No keypressed
}

//call from main like this

while(1)
	{
		key=GetKeyPressed();	//Get the keycode of pressed key

		LCDWriteIntXY(0,0,key,3);	//Print it at location 0,0 on LCD.
	}

Edit: untested!

Last Edited: Wed. Oct 12, 2016 - 02:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you.
the code is fairly incomplete but I will fight to detect the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think this works. Hope it helps

 

Attachment(s): 

Imagecraft compiler user