Saturday, 29 March 2014

StellarisTiva C Series cortex M4123G LaunchPad 16x2 LCD & 4x4 Keypad Drivers with simple calculator code

This drivers is a cooperation work between me and Eng. Osama Ghanem and Eng Mennat Allah Hosny

#############################
### This code based on Keil IDE ###
#############################


#####################
##### 4x4 KEYPAD ####
#####################
key pad is connected to PORTA and PORTE as :  4 columns in  PA2, PA3, PA4, PA5
and 4 rows in PE0, PE1, PE2, PE3

===== KeyPad.h  file=====


#include "tm4c123gh6pm.h"

#define N_col 4
#define N_row 4

unsigned char Keypad_Read(void);
void Keypad_Init(void);
char key_pressed(unsigned char value);

========KeyPad.c file=====
#include"KEYPAD.h"

void NDelay_ms(unsigned long time)
{
time = ((time/375)*1000000);
while(time)
{
time--;
}
}

unsigned char Keypad_Read(){

unsigned char col_count =0,row_count=0;
while(1)
{
for(col_count = 0;col_count < N_col;col_count++)
{
GPIO_PORTE_DATA_R = 1<<col_count;
for(row_count = 0;row_count < N_row;row_count++)
{
if((GPIO_PORTA_DATA_R &(1<<(row_count+2))) != 0)
{
NDelay_ms(400);
return ((row_count*4)+col_count+1);
}
}
}
}
}
char key_pressed(unsigned char value)
{
char key;
switch(value)
{
case 1:key = 1;
break;
case 2:key = 2;
break;
case 3:key = 3;
break;
case 4:key = -5;
break;
case 5:key = 4;
break;
case 6:key = 5;
break;
case 7:key = 6;
break;
case 8:key = -3;
break;
case 9:key = 7;
break;
case 10:key = 8;
break;
case 11:key = 9;
break;
case 12:key = -6;
break;
case 13:key = -1;
break;
case 14:key = 0;
break;
case 15:key = 15;
break;
case 16:key = 13;
break;
}
return key;
}

void Keypad_Init(){
  volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x00000010;     // 1) activate clock for Port E
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
  GPIO_PORTE_AMSEL_R = 0x00;        // 3) disable analog on PF
  GPIO_PORTE_PCTL_R = 0x00000000;   // 4) PCTL GPIO on PF4-0
  GPIO_PORTE_DIR_R = 0xFF;          // 5) PE as output
  GPIO_PORTE_AFSEL_R = 0x00;        // 6) disable alt funct on PF7-0
  GPIO_PORTE_PUR_R = 0x00;          // enable pull-up on PF0 and PF4
  GPIO_PORTE_DEN_R = 0xFF;          // 7) enable digital I/O on PF4-0


  SYSCTL_RCGC2_R |= 0x00000001;     // 1) activate clock for Port A
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
  GPIO_PORTA_AMSEL_R = 0x00;        // 3) disable analog on PF
  GPIO_PORTA_PCTL_R = 0x00000000;   // 4) PCTL GPIO on PF4-0
  GPIO_PORTA_DIR_R = 0x00;          // 5) PF4,PF0 in, PF3-1 out
  GPIO_PORTA_AFSEL_R = 0x00;        // 6) disable alt funct on PA7-0
  GPIO_PORTA_PDR_R = 0xFF;          // enable pull-up on PA4,5,6,7
  GPIO_PORTA_DEN_R = 0xFF;          // 7) enable digital I/O on PFA-0

}



                                      ####################
                                       ##16x2 alphnum LCD ##
                                      ####################

LCD is connected with PORTF and PORTB as:
D0...D7 -->PB0..PB7
RS -->PF1
RW-->PF2
EN -->PF3
VSS --> GND
VDD --> VBUS


===== LCD.h file ====

#include <stdio.h>
#include "tm4c123gh6pm.h"
#include "PIN_PORTS_DEFIENATIONS.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char uint8;

void LCD_init(void);
void LCD_Send_Command(uint8 command);
void LCD_Goto(uint8 x, uint8 y);
void LCD_Send_Character(uint8 character);
void LCD_Send_String(char *str);
void Delay_ms(unsigned long time);
void LCD_Clear(void);
void LCD_Send_Integer(int number);
void LCD_Send_Float(float f);
//void Delay_5_ms(void);
===================




==================
=====LCD .c file =====
==================


#include "LCD.h"

#define LCD_DATA_PORT GPIO_PORTB_DATA_R

#define LCD_CONTROL_PORT GPIO_PORTF_DATA_R

#define LCD_RS_PIN PF1
#define LCD_RW_PIN PF2
#define LCD_E_PIN  PF3


void LCD_init(void)
{
/* initialization for lcd data and command (ALL PINS OF PORT B)*/
volatile unsigned long delay;
SYSCTL_RCGC2_R |=SYSCTL_RCGC2_GPIOB; //ative clock for PORT B
delay = SYSCTL_RCGC2_R;

GPIO_PORTB_AMSEL_R = 0x00; //DISABLE ANLOG ON PORT B
GPIO_PORTB_PCTL_R = 0x00000000; //
GPIO_PORTB_DIR_R = 0xFF; // MAKE PORTB IS OUTPUT PORT
GPIO_PORTB_AFSEL_R = 0x00; //DISABLE ALTERNATIVE FUNCTION
GPIO_PORTB_DEN_R =0xFF; // ENABLE DIGITAL I/O FOR PORT B

/*initialization for lcd control ()*/
/*SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOF;
delay = SYSCTL_RCGC2_R;
GPIO_PORTF_LOCK_R = GPIO_LOCK_KEY;
GPIO_PORTF_CR_R = 0x0E;
GPIO_PORTF_AMSEL_R = 0x00;
GPIO_PORTF_PCTL_R = 0x00000000;
GPIO_PORTF_DIR_R = 0x0E;
GPIO_PORTF_AFSEL_R = 0x00;
GPIO_PORTF_DEN_R = 0x0E;*/

LCD_Send_Command(0x38);
Delay_ms(100);
LCD_Send_Command(0x0C);
Delay_ms(100);
LCD_Send_Command(0x01);
Delay_ms(100);
LCD_Send_Command(0x06);
}


void LCD_Send_Command(uint8 command)
{
LCD_DATA_PORT = command;

LCD_RS_PIN = 0x00;
LCD_RW_PIN = 0x00;
LCD_E_PIN = 0xFF;
Delay_ms(100);
LCD_E_PIN = 0x00;
}


void LCD_Goto(uint8 x, uint8 y)
{
uint8 firstAddress[]={0x80,0xC0};
LCD_Send_Command(firstAddress[x-1] + y-1);
Delay_ms(100);
}


void LCD_Send_Character(uint8 character)
{
LCD_DATA_PORT = character;

LCD_RS_PIN = 0xFF;
LCD_RW_PIN = 0x00;
LCD_E_PIN = 0xFF;
Delay_ms(100);
LCD_E_PIN = 0x00;
}


void LCD_Send_String(char *str)
{
while(*str)
{
LCD_Send_Character(*str++);

}
}
/*
void LCD_Send_Integer(unsigned long number){// This function prints integer on LCD
unsigned char thousands,hundreds,tens,ones;
 if (number>=1000)
  thousands = ((number/1000)%10);
 if (number>=100)
  hundreds = ((number/100)%10);
 if (number>=10)
  tens = ((number/10)%10);

  ones = ((number/1)%10);

  if (number>=1000)
LCD_Send_Character(thousands+48);
if (number>=100)
LCD_Send_Character(hundreds+48);
 if (number>=10)
LCD_Send_Character(tens+48);

LCD_Send_Character(ones+48);
}*/
//void LCD_Send_Integer(unsigned long result)
//{
// if(result <= 9) //check if number consists of ONLY ONE digit
// LCD_Send_Character(result+'0');
// else if((result >= 10)&&((result <= 99))) //check if number consists of  TWO digits
// {
// LCD_Send_Character((result/10)+'0');
// LCD_Send_Character((result%10)+'0');
// }
// else if((result >= 100)&&((result <= 999))) //check if number consists of  THREE digits
// {
// LCD_Send_Character((result/100)+'0');
// LCD_Send_Character(((result%100)/10)+'0');
// LCD_Send_Character(((result%100)%10)+'0');
// }
// else if((result >= 1000)&&((result <= 9999))) //check if number consists of  FOUR digits
// {
// LCD_Send_Character((result/1000)+'0');
// LCD_Send_Character(((result%1000)/100)+'0');
// LCD_Send_Character((((result%1000)%100)/10)+'0');
// LCD_Send_Character((((result%1000)%100)%10)+'0');
// }
//}
void Delay_ms(unsigned long time)
{
time = 145448;  // 0.1sec
  while(time){
time--;
  }
}
//void Delay_ms(unsigned long time)
//{
// time = ((time/375)*1000000);
// while(time)
// {
// time--;
// }
//}
void LCD_Clear()
{
LCD_Send_Command(0x01);
}
void LCD_Send_Float(float f)
{
unsigned int v,p;
long int num;
num=f*10000;
p=num%10000;

v=num/10000;

LCD_Send_Integer(v);
LCD_Send_Character('.');
LCD_Send_Integer(p);

}
/*
void LCD_Send_String(char word[]){
unsigned char i=0; // iterating variable
unsigned char length = (unsigned char)strlen(word); // length of the word

// Printing the word
for(i=0;i<length;i++)
{
LCD_Send_Character(word[i]);
}
}*/

void LCD_Send_Integer(int number){// This function prints integer on LCD
char buffer[10];
Delay_ms(10);
sprintf(buffer,"%d",number); // function sprintf converts integer to string
LCD_Send_String(buffer);
}




#################################################################
==== And this is a simple calculator code for testing the Keypad code and LCD ===
#################################################################

====calc.h=====

#include "KEYPAD.h"
#include "LCD.h"
#include <math.h>

#define PLUS 4
#define MINUS 8
#define TIMES 12
#define DIVIDE 13
#define CLEAR 15

void  get_number1(void);
 int  get_number2(void);
 int x_settings(int x);
 int Get_sign(void);
void _delay_ms(unsigned long time);
void Calc(void);
===========================

==== calc.c =======

#include "Calc.h"

void _delay_ms(unsigned long time)
{
time = ((time/375)*1000000);
while(time)
{
time--;
}
}

void Calc(){
char input[16] = {0};
char read = 0;
unsigned long num1 = 0,num2 = 0,result = 0;
unsigned char count = 0,operator ;
unsigned char i = 0,operator_index,equal_index;
while((read =Keypad_Read())!= 16) //read opearnds and operator from user
{
input[count] = key_pressed(read); //save inputs
LCD_Send_Character(key_pressed(Keypad_Read())+48); //display inputs on LCD display
if(read == PLUS) //check the opearator
{
operator = PLUS;
operator_index = count;
}
else if(read == MINUS)
{
operator = MINUS;
operator_index = count;
}
else if(read == TIMES)
{
operator = TIMES;
operator_index = count;
}
else if(read == DIVIDE)
{
operator = DIVIDE;
operator_index = count;
}
count++;
}
LCD_Send_Character('=');
equal_index = count;
//get the first operand
for(i=0;i<operator_index;i++)
num1 += (input[i])*(pow(10,(operator_index-i-1)));
}
//get the second operand
for(i=operator_index+1;i<equal_index;i++)
num2 += (input[i])*(pow(10,(equal_index-i-1)));
}
switch(operator)
{
case PLUS:
result = num1+num2;
break;
case MINUS:
if(num1>num2)
result = num1-num2;
else 
{
Delay_ms(100);
LCD_Send_Character('-');
result = num2-num1;
}
break;
case TIMES:
result = num1*num2;
break;
case DIVIDE:
result = num1/num2;
break;
}
Delay_ms(100);
LCD_Send_Integer(result); //Display the result
Delay_ms(1000);
if(Keypad_Read() == CLEAR)
{
count = 0;
operator_index = 0;
equal_index = 0;
num1 = 0;
num2 = 0;
result = 0;
LCD_Clear();
}
Delay_ms(100);
}
===================================


======PIN_PORTS_Definations.h=====

// Author Ahmed Karam Mansour

/* PINS OF PORT A*/

#define PA2 (*((volatile unsigned long *)0x40004010))
#define PA3 (*((volatile unsigned long *)0x40004020))
#define PA4 (*((volatile unsigned long *)0x40004040))
#define PA5 (*((volatile unsigned long *)0x40004080))
#define PA6 (*((volatile unsigned long *)0x40004100))
#define PA7 (*((volatile unsigned long *)0x40004200))


/* PINS OF PORT B*/

#define PB0 (*((volatile unsigned long *)0x40005004))
#define PB1 (*((volatile unsigned long *)0x40005008))
#define PB2 (*((volatile unsigned long *)0x40005010))
#define PB3 (*((volatile unsigned long *)0x40005020))
#define PB4 (*((volatile unsigned long *)0x40005040))
#define PB5 (*((volatile unsigned long *)0x40005080))
#define PB6 (*((volatile unsigned long *)0x40005100))
#define PB7 (*((volatile unsigned long *)0x40005200))


/* PINS OF PORT C*/

#define PC4 (*((volatile unsigned long *)0x40006040))
#define PC5 (*((volatile unsigned long *)0x40006080))
#define PC6 (*((volatile unsigned long *)0x40006100))
#define PC7 (*((volatile unsigned long *)0x40006200))


/* PINS OF PORT D*/

#define PD0 (*((volatile unsigned long *)0x40007004))
#define PD1 (*((volatile unsigned long *)0x40007008))
#define PD2 (*((volatile unsigned long *)0x40007010))
#define PD3 (*((volatile unsigned long *)0x40007020))
#define PD6 (*((volatile unsigned long *)0x40007100))
#define PD7 (*((volatile unsigned long *)0x40007200))


/* PINS OF PORT E*/

#define PE0 (*((volatile unsigned long *)0x40024004))
#define PE1 (*((volatile unsigned long *)0x40024008))
#define PE2 (*((volatile unsigned long *)0x40024010))
#define PE3 (*((volatile unsigned long *)0x40024020))
#define PE4 (*((volatile unsigned long *)0x40024040))
#define PE5 (*((volatile unsigned long *)0x40024080))


/* PINS OF PORT F*/

#define PF0 (*((volatile unsigned long *)0x40025004))
#define PF1 (*((volatile unsigned long *)0x40025008))
#define PF2 (*((volatile unsigned long *)0x40025010))
#define PF3 (*((volatile unsigned long *)0x40025020))
#define PF4 (*((volatile unsigned long *)0x40025040))
#define PF5 (*((volatile unsigned long *)0x40025080))
#define PF6 (*((volatile unsigned long *)0x40025100))
#define PF7 (*((volatile unsigned long *)0x40025200))



================================================================

=============Main Program   main.c file======
#include "tm4c123gh6pm.h"
#include"LCD.h"
#include"KEYPAD.h"
#include "Calc.h"

void PortE_Init(void){ volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x00000010;     // 1) activate clock for Port E
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
  GPIO_PORTE_AMSEL_R = 0x00;        // 3) disable analog on PF
  GPIO_PORTE_PCTL_R = 0x00000000;   // 4) PCTL GPIO on PF4-0
  GPIO_PORTE_DIR_R = 0xFF;          // 5) PE as output
  GPIO_PORTE_AFSEL_R = 0x00;        // 6) disable alt funct on PF7-0
  GPIO_PORTE_PUR_R = 0x00;          // enable pull-up on PF0 and PF4
  GPIO_PORTE_DEN_R = 0xFF;          // 7) enable digital I/O on PF4-0
}

void PortA_Init(void){ volatile unsigned long delay;
  SYSCTL_RCGC2_R |= 0x00000001;     // 1) activate clock for Port A
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
  GPIO_PORTA_AMSEL_R = 0x00;        // 3) disable analog on PF
  GPIO_PORTA_PCTL_R = 0x00000000;   // 4) PCTL GPIO on PF4-0
  GPIO_PORTA_DIR_R = 0x00;          // 5) PF4,PF0 in, PF3-1 out
  GPIO_PORTA_AFSEL_R = 0x00;        // 6) disable alt funct on PA7-0
  GPIO_PORTA_PDR_R = 0xFF;          // enable pull-up on PA4,5,6,7
  GPIO_PORTA_DEN_R = 0xFF;          // 7) enable digital I/O on PFA-0
}


void PortF_Init(void){ volatile unsigned long delay;
SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOF;  // 1) activate clock for Port F
  delay = SYSCTL_RCGC2_R;           // allow time for clock to start
  GPIO_PORTF_LOCK_R = 0x4C4F434B;   // 2) unlock GPIO Port F
  GPIO_PORTF_CR_R = 0x1F;           // allow changes to PF4-0
  // only PF0 needs to be unlocked, other bits can't be locked
  GPIO_PORTF_AMSEL_R = 0x00;        // 3) disable analog on PF
  GPIO_PORTF_PCTL_R = 0x00000000;   // 4) PCTL GPIO on PF4-0
  GPIO_PORTF_DIR_R = 0x0E;          // 5) PF4,PF0 in, PF3-1 out
  GPIO_PORTF_AFSEL_R = 0x00;        // 6) disable alt funct on PF7-0
  GPIO_PORTF_PUR_R = 0x11;          // enable pull-up on PF0 and PF4
  GPIO_PORTF_DEN_R = 0x1F;          // 7) enable digital I/O on PF4-0
}

/*void _delay_ms(unsigned long time)
{
time = ((time/375)*1000000);
while(time)
{
time--;
}
}*/



int main()
{
PortF_Init();
PortA_Init();
PortE_Init();
LCD_init();
Keypad_Init();
LCD_Clear();
LCD_Goto(1,1);

LCD_Send_String("Calculator");
_delay_ms(5000);
while(1){
LCD_Clear();
 Calc();
Delay_ms(2000);
}
}



=================================
                     End of First Project
your comments will be appreciated :) 








1 comment:

  1. Why don't you use some functions such as GPIOIntTypeSet, GPIOPinIntEnable,...?

    ReplyDelete