Understanding Timers in MSP430 Launch pad



In this tutorial, I assume that you have an idea about the basic timers in 8051 or any other microcontroller. I am not going to define the timer’s definition and its applications. Here I just concentrate on programming aspects of the timers in MSP430 microcontroller.

Generally, first question arises in our mind about the timer’s is “How many timers are there in MSP430G2553”?
There are 16-bit two timers are available in MSP430G2553.


code:

A program generate 1 sec time day using Timers in MSP430 launch pad.

#include 

void Config_TimerA(void);
void Config_GPIO(void);


void main(void)
{

  WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog timer

 BCSCTL1 = CALBC1_1MHZ;
 DCOCTL = CALDCO_1MHZ;
 BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
 IFG1 &= ~OFIFG;                           // Clear OSCFault flag
 BCSCTL2 |= SELM_0 + DIVM_3 + DIVS_3;               // MCLK = DCO/8 , SMCLK = DCO/8
 Config_GPIO();
 Config_TimerA();
 __bis_SR_register(GIE);           // Stop DCO


 while(1);
}


void Config_GPIO(void)
{
 P1DIR = 0x01;                             // MAKE P1.0 as output port
 P1OUT = 0x00;                             // MAKE ALL pins to logic low
}

void Config_TimerA(void)
{
 // Configure the TimerA to operate with ACLK which is source from VLO (12KHz) - (TASSEL = 1) and in up mode (MC = 1)
 TACTL = TASSEL_1 + MC_1;
 CCTL0 = CCIE;  // Enable compare register interrupt in the CCTLO (capture compare control register)
 CCR0 = 12000;  // load the count 12000 in counter compare register  to generate 1 second delay (12000 * T) = 12000 * (1/12000) = 1sec;
 // T = 1/F = 1/12khz

}


#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
 CCR0 =+ 12000;
 P1OUT |= 0x01;
 _delay_cycles(1000);
 P1OUT &= ~0x01;
}

Understanding of Basic Clock System in MSP430 Launch pad


A clock system is a heart of microcontroller. If we know the functioning of this heart system then it is easier to study remaining modules (like Timers, communication interface, etc.,) of the microcontroller. You people may have an idea about the clock system in 8051 and other microcontrollers, off course they are simple and easy to configure. But in MSP430 there is a highly sophisticated and accurate clock generation system is available. This clock system makes the CPU (of MSP430) may operate in different  speeds  and also helps to reduce the power consumption of it by operating in different low power modes. The aim of this tutorial is to make the clock system as simple as that easily understandable for the beginners.
Basically the MSP430 device contains four clock sources (oscillators) that are used to generate three different clock signals. Because the MSP430 classifies the peripherals into two categories (slow and fast) based upon their operating speeds. This categorization of peripherals is mainly to reduce the power consumption of CPU and the peripherals, i.e., high frequency operations require more power that compared with low frequency.

MSP430G2553 Clock Sources:
·         VLOCLK –    VERY LOW FREQUENCY – LOW POWER OSCILLATOR.
·         LFXT1CLK – LOW FREQUENCY OR HIGH FREQUENCY OSCILLATOR.
·         DCOCLK –    DIGITALLY CONTROLLED OSCILLATOR.
·         XT2CLK (optional) – HIGH FREQUENCY OSCILLATOR.

MSP430G2553 Clock signals:
·         ACLK  –    for Slow Peripherals.
·         MCLK  --  to CPU and few peripherals.
·         SMCLK -- for Fast Peripherals.





FIGURE 1.1 MSP430 CLOCK SYSTEMS WITH FOUR CLOCK SOURCES AND THREE CLOCK SIGNALS.

·         VLO: Very low power – low frequency oscillator. It is especially for to generate low frequency signals and comes as internal feature to MSP430. It provides a frequency of 12KHz without any need of external crystal. It provides 500nA as stand by current.

·          LFXT1:  Low frequency or High frequency oscillator. This is operated in two modes.
o   Low Frequency (LF) mode – (XTS = 0) – 32768KHz.
o   High Frequency (HF) mode – (XTS = 1) – 400KHz – 16MHz.
o   There is an in-built OSC-Fault mechanism available in MSP430. If OSC – fails to work then it switches to alternate clock source available in the device.
o   The frequency can change by the changing the programmable capacitors present internally in the MSP430.

·    DCO: Digital Controlled Oscillator – It generates a frequency range from 1MHz – 16MHz. generally beginners may like this, because it’s easy configure than compared to other.

·         XT2: it is an optional high frequency oscillator similar to LFXT1 in HF mode. The frequency range is 400 KHz – 16MHz.  Generally some device these optional clock sources

You can use any one of the oscillator to generate the three different clock sources based on the power and speed requirement.
·         ACLK – used for slower devices and it can generate from one of either two clock sources (LFXT1 or VLO).
·         MCLK – used for CPU and some peripherals. It can generate from either DCO or VLO or Low/High frequency crystals. Hence a mux is used to multiplex both oscillators as shown in the figure 1.1.
·         SMCLK – used for High speed peripherals and it can generate from DCO oscillator only.

·     Up on reset, MCLK and SMCLK are source from 1.1MHz DCO clock source. And ACLK is sourced from LFXT1 oscillator in LF mode with 6pF load capacitance.
·         If LFXT1 fails, then the ACLK is source from the VLO oscillator as shown in the figure 1.1.
·    Clock speed should match with the required operating VCC to achieve the very lower power possible otherwise unreliable execution results if Vcc < the minimum required value for the selected frequency.

Coming to the MSP430 programming, there are three special Basic Clock Control registers are available to configure the different clocks to different modules in the MSP430 microcontroller.

BASIC CLOCK SYSTEM CONTROL REGISTERS:

·         BCSCTL1 – Used to ACLK frequency select (DIVAx bits) and LFXT1 mode select (LF and HF).
·         BCSCTL2 – Used to select MCLK and SMCLK sources (either DCO or LFXT1 or VLO).
      And also provides frequency range selection bits for MCLK (DIVMx bits) and SMCLK (DIVSx bits).
·         BCSCTL3 – used to select LFXT1 oscillator frequency range.
·         DCOCTL – DCO control register – used to select DCO frequency (1MHz, 4MHz, 8MHz, and 16MHz).

Status register contains some control bits (SCG0, SCG1, OSCOFF, and CPUOFF) used to enable or disable some portions of the Basic clock module and also used to configure the MSP430 operating modes.

C Program to generate 1 sec delay using low frequency oscillator (VLO). Here in this program LED blinks for every one second and also we can see the lowest frequency of operation. This can be achieved by taking the VLO oscillator which is the very low frequency oscillation (~12KHz) and divide it with maximum dividend which is 8 in this context.

Step 1: Stop the watch dog timer, to avoid unnecessary resets of the microcontroller. 
            We will discuss more on watch dog timer later
                WDTCTL = WDTPW + WDTHOLD; // stop watch dog timer

Step 2: Select the VLO as clock source.
                BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO, check out theMSP430x2xx family 
                                                         // user  guide page number 290.

Step 3: In the basic clock system by default OFIFG (oscillator-fault flag) bit is set and force the 
           MCLK to use DCO as its source. But our intension is to make the MCLK should use VLO 
           as its source. So we need to clear the OFIFG bit.
                IFG1 &= ~OFIFG;                           // Clear OSCFault flag

Step 4: The OSC_Fault flag takes 50 milliseconds to react, so single instruction is enough to produce 
            that delay since the clock speed is 12KHz. That single instruction is used to block the DCO 
            source for MCLK. It is better to disable the DCOCLK and this can be done by setting the  
            bits ‘SCG0’ and ‘SCG1’ in the status register.
__bis_SR_register(SCG1 + SCG0);  // Stop DCO clock and this ‘__’ indicates that                                                      
                                                     // this instruction is an assembly level call from c language.

                Step 5: Now source the MCLK with the VLO oscillator and divide the value by 8 why because 
                            here we are trying to achieve the lowest frequency of operation in MSP430 (~ 1.5KHz)
                                BCSCTL2 |= SELM_3 + DIVM_3;               // MCLK = LFXT1/8 = VLO/8

   Step 6: Make port1 bit 0 as output, which is connected to RED LED on the LAUNCH PAD 
               board. This can be done by placing 1 on direction register (P1DIR)
                P1DIR = 0x01; // (output – 1, input – 0)

    Step 7: place zero on the P1.0 pin, to make output zero.
                P1OUT = 0x00; // all port1 pins are at logic low.

     Step 8: Blinking LED code using _delay_cycles() functions, this function produces delay equal to 
               that the number passed to that function. For example, if the operating clock frequency is 
               1MHz then _delay_cycles(1) produce 1microsecond delay. Likewise _delay_cycles(10) 
               produce 10 microseconds. In this program, we are operating with 1.5KHz, hence one 
               _delay_cycles(1) may take (1/1.5KHz = 0.666 milliseconds) Here one question arises that   
            how many delay cycles that are needed to produce 1 second with our clock source. Answer 
             is 1500 (1/0.66m = 1500).

While(1)              
{
P1OUT = 0X01;
_delay_cycles(1);
P1OUT = 0X00;
_delay_cycles(1);
}
               

 code:


#include  

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  __bis_SR_register(SCG1 + SCG0);           // Stop DCO and to wait 50 milliseconds
  BCSCTL2 |= SELM_3 + DIVM_3;               // MCLK = LFXT1/8
  P1DIR = 0x01                              // make P1.0 as output and remaing all are output
  P1OUT = 0x00;                             // All P1.x reset
  
  for (;;)
  {
    P1OUT |= 0x01;                          // P1.0 set
    _delay_cycles(100);
    P1OUT &= ~0x01;                         // P1.0 reset
    _delay_cycles(1400);
  }
}


video:

IR sensor based Distance measurement system


In this tutorial, I am going show how we can measure the distance over a short range using infrared sensors. Such application is very much useful in robotics, transportation, etc.,

For example, A robotic car which take diversions based upon the distance measure between the obstacle and the car. An application like, snake robot can measure the diameter of the hole and make a decision according to that. Similarly in transportation, inter-vehicular-distance is very important for a safe driving. The inter-vehicular-distance can be measured by using IR or UV rays sensors.

1.      Construction:

1.1  simple IR transmitter:
The IR transmitter can be designed by using simple IR diode and a 220 ohms resistor, which is shown on the circuit diagram figure 1.

1.2  Simple IR receiver:
In this application, the main objective is to measure the distance between obstacle and the IR receiver. Due to that the analog variation of the IR receiver output is taken and then connected it to an Analog to Digital converter. Here the receiver diode and a 10k ohms resistor are connected in series between supply and ground to form a voltage divider network which is shown in the circuit diagram. The principle of operation is very simple; whenever the IR light is falls on the receiver diode, the resistance offered by the IR receiver is decreases and allow more current through it. The IR receiver offers more resistance when no IR light is falls on it. Keep in mind that both IR transmitter and receiver is connected side by side, so that the reflected light from the obstacle is easily catch by the receiver.

1.3  Analog to Digital converter connections:
The IR receiver produces different voltage variations as output, depend upon the amount of IR light is reflected back by the obstacle. By using an Analog to digital converter the analog voltage variations of the IR receiver are converted into digital values. Here I used a single channel ADC (ADC0804) which contains single input channel. The output of the IR receiver is connected to pin6 (input channel VIN (+)) of the ADC0804 IC and digital output is taken from the pin 11(LSB) to 18(MSB). And pin7 VIN (-) is connected to ground.
A clock circuit is made by using simple resistor and capacitor connected to 4th and 9th pins of IC, similarly an external clock can be connected instead of R and C circuit between 4 and 19th pins of the ADC IC. Here, the product of R and C values should result 600 kHz at 5V check the data sheet, hence R = 10k and c = 150pF is used in the clock circuit. The maximum clock frequency that ADC0804 can operate at 5V is 800 kHz, whereas at 6v the clock frequency is 1200khz.

Frequency      F = 1/(1.1RC).

A 10k pot is used as external reference voltage for the ADC IC, if no external reference is used then the reference voltage = VREF/2 (or Vcc/2). This is useful to adjust the step size. If the VREF = 5V (vcc) then the step size is VREF/MAXIMUM DIGITAL OUTPUT value.

                                                            Step size = 5v/255 = 19.33mV.

The internal conversion process is completed in 64 clock cycles, but 1 to 8 clock periods are used after the write pin low to high transition and before conversion starts. And also 1 clock period is taken before INTR pin goes low. Approximately the maximum conversion time taken by the ADC is equal to (t conversion = 8 clock cycles+ 64 clock cycles + 1 clock cycle = 73 clock cycles).

Therefore in this example, t conversion = 73 * 1/(606khz) = 120 microseconds.

Finally we three control pins for the ADC operation Read (2nd pin of ADC), Write (3rd pin of ADC), INTR (5th pin of ADC). All these three pins are active low signals. By providing a high to low logic on the Write pin will START the conversion process. If a low to high logic will eventually set the INTR pin to high. The INTR pin is used to indicate the END of conversion process. Finally a low signal on Read pin will latch the internal converted data on to the data port of the ADC.


1.4  Steps to perform the conversion process on ADC:

·      Provide a high to low logic (>200ns) on write pin to start the conversion process.
·      Again provide a low to high logic on write pin to set the INTR pin to high.
·      Check for INTR pin, if it is low means the conversion process is completed.
·     Finally provide a logic low on the read pin, to read the converted data from the ADC.
·       After all the steps are completed make read pin.
·    Make sure that CS, AGND, v- and GND are grounded before performing all the above steps.


1.5  16x2 LCD interface:
The LCD connections and its interfacing programming with 8051 is already discussed on this website. Therefore, here I encourage you to read the related topics on LCD provided in this site.


1.6  Ciruit Diagram for IR sensor based Distance measurement system:

Figure1  Ciruit Diagram for IR sensor based Distance measurement system



Note: 1. White color reflects more IR light than any other colour 
          2. One major problem with the IR distance measure is going below the minimum sensor          range means  an object is so close the sensor cannot get an accurate reading. And this theory is better explained in the URL http://www.societyofrobots.com/sensors_sharpirrange.shtml



1.7 software code:
/******************************************************************************************************************************/
// http://www.npeducations.com
// IR_Distance_Measurement.c - measuring the obstacle distance using infrared sensors. the output will show the distance upto 9 cm, the video is taken during testing
// so don't confuse with the video output.
// Author - lovakiranvarma, M.tech
/******************************************************************************************************************************/
#include

#define LCD_PORT P2 
#define ADC_DATA P1

// function prototypes
void converttochar(void);
void lcd_data_string(unsigned char *);
void delay(unsigned int );
void lcd_cmd(unsigned char );
void lcd_data(unsigned char );
void LCD_Init(void);

// LCD control pins declaration
sbit RS = P3^7;     // Register Select line
sbit RW = P3^5;  // Read/ADC_WRITEite line
sbit ENABLE = P3^6; // Enable line

// ADC control pins declaration
sbit ADC_READ= P3^0;
sbit ADC_WRITE= P3^1;
sbit ADC_INTR= P3^2;

int value1=0;

void main()
{
ADC_DATA = 0xff; // make P1 as input port
LCD_PORT = 0x00; //make P2 as outport

LCD_Init();
lcd_cmd(0x85);  // Setting cursor location at 5th position of the first line
delay(2);

lcd_data_string("IR BASED DISTANCE MEASURE");
delay(100);
lcd_cmd(0x01);
delay(5);
lcd_cmd(0x80);
delay(5);
lcd_data_string("DISTANCE:");
while(1)
{
  delay(5);
  ADC_READ=1;
  ADC_WRITE=0;  // make WRITE to high to low for start of conversion
  delay(5);
  ADC_WRITE=1;
  while(ADC_INTR==1); // check for END of conversion
  ADC_READ=0;         // read the converted digital data form the ADC port
  value1=ADC_DATA;
  delay(5);
  ADC_INTR=1;
  converttochar();
}
}



void LCD_Init()
{
lcd_cmd(0x38);  //2 Line, 5X7 Matrix
delay(5);
lcd_cmd(0x0E);  //Display On, CuRSor Blink
delay(5);
lcd_cmd(0x06);
delay(5);
lcd_cmd(0x01);  // Clear Screen
delay(5);
}

void lcd_cmd(unsigned char Command) // LCD Command Sending Function declaration
{
LCD_PORT = Command;
RS= 0;
RW=0;
ENABLE = 1;
delay(1);
ENABLE = 0;
return;
}

void lcd_data(unsigned char data_value)  // LCD data Sending Function declaration
{
LCD_PORT = data_value;
RS= 1;
RW=0;
ENABLE = 1;
delay(1);
ENABLE = 0;
return;
}

void lcd_data_string(unsigned char *string) // LCD Command Sending String declaration
{
int i=0,j=0;
while(string[i]!='\0')
{
 if(i>=9)
 { 
  // If the number of characters in the string > 16, then the below command automatically 
 lcd_cmd(0xc0+j++);  // Shift the display right side 
 }
  lcd_data(string[i]);
  i++;
  delay(2);
}
return;
}

void converttochar()
{
int M;

M=value1/100;
M=M/10;
value1=value1%100;
value1=value1%10;

lcd_cmd(0x8a);
if(M!=0)
lcd_data(M+48);
else
lcd_cmd(0x06);
M=value1/10;
value1=value1%10;
lcd_data(M+48);
lcd_data(value1+48);
lcd_data(' ');
delay(5);
}

void delay(unsigned int DELAY_VALUE ) // delay function
{
int i ,j ;
for(i=0;i<=DELAY_VALUE;i++)
  for(j=0; j<1000 data-blogger-escaped-j="" data-blogger-escaped-pre="">


Interfacing 16x2 character LCD display with MSP430 Launch pad


Interfacing 16x2 character LCD display with MSP430 Launch pad is quite simple. You just need a separate 5V power supply to drive the LCD. One of the main advantages of MSP430 Launch pad is its in-built debugging feature and its pin configuration. In this tutorial, I am not going to start from the scrap of LCD. But I encourage you to read my previous tutorials about introduction to LCD and its interfacing to microcontroller, where you can find the LCD commands, LCD functions, LCD interface mechanism etc.  In this post, I just show the connections between the LCD and MSP430 Launch pad, A test program to  display a string of characters on it, and finally a small video is presented in which output of the program is shown.

1. Construction:
Generally 16x2 character LCD displays requires eight data lines, three control lines (RS, EN, R/W) and 5v power supply and common ground. Here the microcontroller belongs to MSP430 family which runs worth 3.3v USB power supply. But the 16x2 LCD requires 5v power supply which should be provided separately. Generally, when we interface the same LCD with 8051 microcontroller there is no need of separate power supply. Why because both LCD and 8051 microcontroller works with the same 5v supply.

A small important note for you “don’t use USB power supply taken from MSP430 launch pad for LCD display” which may damage your pc USB port, so be careful about that.

All the data lines of the LCD are connected to Port 2 pins of the MSP430G2553 microcontroller and the control lines connected to Port1 pins (RS - P1.6 and EN - P1.7). Another more import thing is that connect the ground pin MSP430 Launch Pad with LCD ground pin in order form the closed loop circuit. If you won’t connect the two grounds, then you notice some garbage characters appear on the LCD display while executing the program. One more important point in this tutorial that I connected the R/W pin of the LCD to ground, because I am not performing read operation on LCD, just write operation only. For write operation the LCD R/W pin should be connected to the ground.

2. Circuit Diagram to interface 16x2 LCD with MSP430 microcontroller:

Circuit Diagram to interface 16x2 LCD with MSP430 microcontroller

Note:
      1.   Don’t use USB power supply for LCD display which is taken from the MSP430 launch pad board.      Otherwise your pc USB port may damage by drawing more current from it. 
        2.   Join MSP430 launch pad ground point with LCD ground pin in order to form a closed circuit. Otherwise garbage characters will display.



/******************************************************************************************************************************/ // http://www.npeducations.com // MSP430_LCD.c // Author - lovakiranvarma, M.tech /******************************************************************************************************************************/ #include "msp430g2553.h" #include "stdio.h" #include "string.h" #include "stdlib.h" #define delay_value 500 void LCD_Init(void) { send_cmd(0x38); // configure LCD as 2 lined 5x7 matrix delayms(delay_value); send_cmd(0x0E); //display on, cursor blink delayms(delay_value); send_cmd(0x06); // auto increment of cursor delayms(delay_value); send_cmd(0x01); // clear display delayms(delay_value); } void send_cmd(unsigned char command) { P1OUT &= 0X00; P2OUT &= 0X00; P2OUT = command; P1OUT &= 0X00; P1OUT &= ~0x40; // RS = 0 for command, P1.6 0x40 //RW is grounded P1OUT &= ~0x80; //EN = 0, P1.7, 0x80 delayms(delay_value); P1OUT |= 0x80; // EN = 1, P1.7, 0x80 delayms(delay_value); P1OUT &= ~0x80; //EN = 0, P1.7, 0x80 delayms(delay_value); } void send_char(unsigned char character) { P1OUT &= 0X00; P2OUT &= 0X00; P2OUT = character; // P1OUT &= 0x00; P1OUT |= 0x40; // RS = 0 for command, P1.6 // RW is grounded P1OUT &= ~0x80; //EN = 0, P1.7 delayms(delay_value); P1OUT |= 0x80; // EN = 1, P1.7 delayms(delay_value); P1OUT &= ~0x80; //EN = 0, P1.7 delayms(delay_value); } void send_string(char *String) { unsigned char i=0; while(String[i]!='\0') { P1OUT &= 0X00; P2OUT &= 0X00; P2OUT = String[i]; P1OUT |= 0x40; // RS = 0 for command, P1.6 // RW is grounded P1OUT &= ~0x80; //EN = 0, P1.7 delayms(delay_value); P1OUT |= 0x80; // EN = 1, P1.7 delayms(delay_value); P1OUT &= ~0x80; //EN = 0, P1.7 delayms(delay_value); if(i>=16) // If the number of characters in the string > 16, then the below command automatically send_cmd(0x18); // Shift the display right side delayms(40000); // 100 millisec delay i++; } } void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; BCSCTL2 &= ~(DIVS_3); //This line of code ensures that the SMCLK divider is 0, // so we have SMCLK=DCO=1MHz (in fact if we are to have a /8 divider, it should be BCSCTL2 |= DIVS_3;). P1DIR = 0xFF; // make P1 as output P2DIR = 0xFF; // make P2 as output P2SEL = 0; // These two are "Function Select Registers PxSEL and PxSEL2", P2SEL2 = 0; // If both are zero's means simple I/O function is selected. P1DIR |= 0x01; // Set P1.0 to output direction P1REN |= 0x01; delayms(1500); // wait for more than 15ms after supply rises to 4.5V send_cmd(0x30); delayms(400); // wait more than 4.1ms send_cmd(0x30); delayms(100); // wait more than 100us, but delayms(1) will provide 1ms send_cmd(0x30); delayms(100); send_cmd(0x02); // return to home delayms(100); LCD_Init(); // LCD initialization while(1) { send_cmd(0x01); // clear display delayms(delay_value); send_cmd(0x81); // clear display delayms(delay_value); send_string("NPEDUCATIONS"); delayms(delay_value); send_cmd(0xC0); // clear display delayms(delay_value); send_string("http://www.npeducations.com"); delayms(delay_value); } }
You tube video:

Interfacing 4x3 keypad with 8051 Microcontroller


Basically, the 4x3 keypad contains push buttons that are arranged in four rows and three columns produce twelve characters as shown in the figure1.Sometimes this called as “4x3 switch matrix” due to the arrangement of switches in a matrix form. The internal construction of these keypads includes metal dome contacts and conductive rubber. Ok! Construction of keypad is out of scope the tutorial. In this tutorial I am only concentrating on interfacing of keypad with 8051 microcontroller.

1. CONNECTIONS:

The three column lines of the keypad as shown in the figure 1 are connected to the PORT 1 upper pins (P1.0 – COL1, P1.1 – COL2, P1.2 – COL3)  and the four row lines are connected to PORT1 lower pins (P1.4 – ROW1, P1.5 – ROW2, P1.6 – ROW3, P1.7 – ROW7). Three resistors of 10k are connected between the column lines and power supply, to make the column lines are always high. Here one thing should be clear, that the column lines connected to the microcontroller should act as input lines and the row lines acts as output lines.

2. WORKING:

2.1 INITIALIZATION:

Remember that, the column lines of keypad are connected to port1 pins and these pins should be configured as input by placing logic high (‘LOGIC 1’) during port initialization. Similarly, the row lines of keypad are connected to port1 pins and configured them as output by placing logic zero (‘LOGIC 0’) during port initialization.

ROW1 = 0; //MAKE ALL ROW LINES OF KEY TO ZERO
ROW2 = 0; // TO MAKE THEM AS OUTPUT LINES
ROW3 = 0;
ROW4 = 0;                
COL1 = 1; // MAKE ALL COL'S AS HIGH
COL2 = 1; // TO MAKE THEM AS INPUT LINES
COL3 = 1;



2.2 SCANNING MECHANISM:

The scanning mechanism starts by making the first row (ROW1) of keypad to LOW (LOGIC ‘0’) and all column lines should be high (LOGIC ‘1’). Now check any one of the column lines goes low. If any column line goes low means that particular button is pressed, otherwise nothing is pressed.
Now the question in our mind is “which button is pressed”. This can be identified by checking which column is goes low.

If ROW1 = 0, COL1 = 0, remaining all lines are high means BUTTON1 is pressed.
If ROW1 = 0, COL2 = 0, remaining all lines are high means BUTTON2 is pressed.
If ROW1 = 0, COL3 = 0, remaining all lines are high means BUTTON3 is pressed.
If ROW2 = 0, COL1 = 0, remaining all lines are high means BUTTON4 is pressed.

Likewise we can identify the remaining buttons also and the logic is shown in the figure1. This can be done by repeatedly, that why use a infinite loop in the routine “key()” – check out the c program.
Figure1 shows the keypad connection and its logic to interface with MCU.



3. PROGRAM DESCRIPTION:

Firstly create an 2-D array (look up table) of numbers like below. This array holds the numbers represented by the keypad. Off course you can change the data as you need, means you define characters, special symbols, numbers, etc..,

char keypad[4][3]=     {         
'1','2','3',
                                                '4','5','6',
                                                '7','8','9',
                                                '*','0','#'
 };          //look up table

Now in the subroutine “key()”, first make first row lines to zero one and scan for the column status. And next make the next row and scan for the column and so on.

ROW1 = 0; //MAKE FIRST ROW IN KEYPAD TO ZERO
ROW2 = 1;
ROW3 = 1;
ROW4 = 1;                
COL1 = 1; // MAKE ALL COL'S AS HIGH
COL2 = 1;
COL3 = 1;

If any one of the column line is low then wait until it back to logic high by continuously checking the col line (while(COL1 == 0)). If col line goes high then place column and row values to get the correct value from the keypad array. Finally place a break statement to get out of the loop, otherwise it stay in infinite loop.

if (COL1 == 0){while(COL1 == 0);row=1;col=1;break;}.

For LCD interface I encourage you to read the tutorial to interface 16x2 LCD with 8051.



Circuit Diagram of 4x3 keypad interface with 8051 along with 16x2 LCD.


Figure2 shows the circuit diagram for 4x3 keypad interface with 8051 along with LCD


4. Keypad interface code:

#include
#include
#include "LCD.h"

sbit COL1=P1^0;
sbit COL2=P1^1;
sbit COL3=P1^2;

sbit ROW1=P1^4;
sbit ROW2=P1^5;
sbit ROW3=P1^6;
sbit ROW4=P1^7;

unsigned char ROW=0,COL=0;
char value='\0', temp=0;
char keypad[4][3]=	{	'1','2','3',
				'4','5','6',
				'7','8','9',
				'*','0','#' };	  //look up table

char key(void);
void main(void)
{	
	P2 = 0x00;
        ROW1 = 0; //MAKE ALL ROWs IN KEYPAD TO ZERO
        ROW2 = 0;
	ROW3 = 0;
	ROW4 = 0;		
	COL1 = 1; // MAKE ALL COL'S AS HIGH
	COL2 = 1;
	COL3 = 1;

       LCD_init();

	while(1)
	{
		send_cmd(0x01);
		delayms(50);
		send_cmd(0x80);
		delayms(50);
		send_data("Enter keys....");
		delayms(600);
		send_cmd(0x01);
		delayms(50);
		send_cmd(0x80);
		delayms(50);
		while(1)		
		{
			value =  key();
			delayms(50);				
			send_char(value);
			delayms(100);
		 }
	}

} 

char key()
{
	
	while(1)
	{

		ROW1 = 0; //MAKE FIRST ROW IN KEYPAD TO ZERO
		ROW2 = 1;
		ROW3 = 1;
		ROW4 = 1;		
		COL1 = 1; // MAKE ALL COL'S AS HIGH
		COL2 = 1;
		COL3 = 1;
		if(COL1 == 0){while(COL1 == 0);ROW=1;COL=1;break;}  
		if(COL2 == 0){while(COL2 == 0);ROW=1;COL=2;break;}  
		if(COL3 == 0){while(COL3 == 0);ROW=1;COL=3;break;}  
		ROW1 = 1; 
		ROW2 = 0; //MAKE SECOND ROW IN KEYPAD TO ZERO
		ROW3 = 1;
		ROW4 = 1;		
		COL1 = 1; // MAKE ALL COL'S AS HIGH
		COL2 = 1;
		COL3 = 1;
		if(COL1 == 0){while(COL1 == 0);ROW=2;COL=1;break;}  
		if(COL2 == 0){while(COL2 == 0);ROW=2;COL=2;break;}  
		if(COL3 == 0){while(COL3 == 0);ROW=2;COL=3;break;}
		ROW1 = 1; 
		ROW2 = 1; 
		ROW3 = 0;//MAKE THIRD ROW IN KEYPAD TO ZERO
		ROW4 = 1;		
		COL1 = 1; // MAKE ALL COL'S AS HIGH
		COL2 = 1;
		COL3 = 1;
		if(COL1 == 0){while(COL1 == 0);ROW=3;COL=1;break;}  
		if(COL2 == 0){while(COL2 == 0);ROW=3;COL=2;break;}  
		if(COL3 == 0){while(COL3 == 0);ROW=3;COL=3;break;}
		ROW1 = 1; 
		ROW2 = 1; 
		ROW3 = 1;
		ROW4 = 0;//MAKE 4TH ROW IN KEYPAD TO ZERO		
		COL1 = 1; // MAKE ALL COL'S AS HIGH
		COL2 = 1;
		COL3 = 1;
		if(COL1 == 0){while(COL1 == 0);ROW=4;COL=1;break;}  
		if(COL2 == 0){while(COL2 == 0);ROW=4;COL=2;break;}  
		if(COL3 == 0){while(COL3 == 0);ROW=4;COL=3;break;}
		delayms(500);
	}

	return	keypad[ROW-1][COL-1];
}

Inter-Vehicle Communication for Safety Driving


In Highways and Streets, traffic is increasing in exponential manner, so that accident rates also increases. According to the World Health Organization, road traffic injuries lead to an estimated 1.26 million deaths worldwide.  The main reasons for these traffic accidents are due to reckless driving of drivers or vehicle owner (Driver behavior) who doesn't maintain necessary distance between vehicles, drunken drivers, over taking, traffic rules violation, break failure, poor roadway maintenance, and Hazard visibility (failed to Look properly). Collision of four wheel vehicles and other big vehicles lead to more death rate than compared with other small vehicles.

 To avoid such accidents, it is necessary to maintain certain distance between vehicles – “Inter-Vehicular Distance”.  A warning system should be employed inside the vehicle, so that the vehicle could sense the distance between other vehicles and intimate to driver. And this warning systems will also shows presence of other vehicles around it with their speeds and other necessity information. This system also provides information regarding any Hazard conditions (Brake failure, door lock failure, etc) happened inside the vehicle body.

 In order to maintain minimum distance between vehicles, each vehicle is employed with some distance measure sensors (Infrared based or ultra-sonic sensors). Sensors send information to a graphical LCD via controller. Not only distance, has LCD also displayed the fuel consumption, speed of the vehicle, brake failure status, etc. Each vehicle shares this information to other vehicles and vice versa by using an Ad-hoc wireless network. In this project, ZIGBEE/ blue-tooth based wireless Ad-hoc network will be used for Inter- Vehicular communication.


Block Diagram

Inter-Vehicle Communication for safety driving

Digital Stethoscope for digital doctors



             Stethoscope has been used for many years, and has been very effective to diagnose certain cardiologic and pulmonologic sounds. For many years healthcare professionals would listen quietly to patients internal organs so    they could diagnose from specific sounds of such internal organs. The problems faced with the ordinary stethoscope are:

ü  Two other sounds (s3&s4) which also exist along with the two classic sounds (lub & dub) cannot be detected by the graphical recording.
ü  Does not allow early detection of heart diseases.
ü  Does not provide graphical plot of the heart sound with respect to time.
ü  Permanent record of analysis cannot be maintained.

             The objective is to develop a peripheral interface controller based digital stethoscope to capture the heart sounds. The proposed designed device consists of the following hardware stages:

ü  Front-end pickup circuitry
ü  microcontroller
ü  graphical display
ü  Serial EEPROM

            The software time and frequency domain analysis of the heart sound is done using MATLAB. A digital stethoscope would help healthcare professional record their findings on a serial EEPROM. Once the data is stored, the healthcare professionals can hear and plot the graph. This would be a quick and more effective since there is a visual and audio representation to diagnose such cardiologic sounds.

If you really like this tutorial, Don't forget to give the comment or please subscribe to the RSS feed by submitting your E-mail.
Related Posts Plugin for WordPress, Blogger...
Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Powered by Blogger