A Little about the blog.....

This blog contains all the interview questions that i face during my interviews with various MNC's. I am trying to post the solutions for almost all the questions and i have covered few important topics which would be frequent topics in interviews. I hope the blog would be useful not only for the job aspirants but also to the one who tries to upgrade his/her knowledge in C and Embedded concepts......

please enter your mail address in the above mail address box to get the immediate updates of the new interview questions.....

Thursday, May 26, 2011

A small Example Program for clock using internal Timer1 in 89s52

i have calculated earlier that it takes the 8051, 1/20th of a second to count from 0 to 46,079. However, the TFx flag is set when the timer overflows back to 0. Thus, if we want to use the TFx flag to indicate when 1/20th of a second has passed we must set the timer initially to 65536 less 46079, or 19,457.

If we set the timer to 19,457, 1/20th of a second later the timer will overflow. Thus we come up with the following code to execute a pause of 1/20th of a second:

TH0=0x076;High byte of 19,457 (76 * 256 = 19,456)
TL0=0x001;Low byte of 19,457 (19,456 + 1 = 19,457)

#include(stdio.h)
#include(at89c51xd2.h)
void delay(void);

void main()
{ int j=0,s=0,m=0,h=0;
SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 0x076; /* TH1: reload value */
TL1 = 0x001;
TR1 = 1; /* TR1: timer 1 run */
TI = 1;

while(1)
{
if(TF1==1)
j++;
if(j==20)
{
s++;
if(s==60)
{
s=0;
m++;
if(m==60)
{
h++;
m=0;
}
}
printf("the time is %d:%d:%d\n",h,m,s);
j=0;
}
}
}


void delay(void)
{
long int i;
for(i=0;i<50000;i++)
{
;
}}

Wednesday, May 25, 2011

Interrupts Handling in Brief: Tutorial by Trinadh

Interrupts in embedded systems play a crucial role in efficient programming saving a lot of time and memory in most of the applications.

An interrupt is nothing but “A Pause or Hold” in the current running function or program and execution of a Task which an Interrupt handler is intended to do. Immediately returns back to the original function after the completion of the interrupt handler.

These following are a few Technical words that are to be remembered while dealing with Interrupts:

Interrupt Handler: A Routine function to be executed when an interrupt is called.

Interrupt Handler address: The address where the interrupt handler is to be placed for execution

Generally in 89s52 micro controller, there are 6 six different causes that can call an Interrupt.

1. Timer 0 overflow
2. Timer 1 overflow
3. External 0 Interrupt
4. External 1 Interrupt
5. Receiving a bit in serial Terminal
6. Transmission of a bit in a serial Terminal

In any of the above cases, an interrupt is generated by the corresponding flag.

To differentiation between different interrupts can be made by observing the corresponding flags.

General procedure for using an Interrupt in an Assembly Language Program

1. Write your program logic as per your needs.
2. At the starting of the Program don’t forget to initialize the Interrupt Enable pin without which no interrupt call can be notice by the micro controller. This can be done by using the command “SETB EA”.
3. After initializing, now choose the interrupt that you want to use in your program and enable it. For example if you want to use an external interrupt 1(EX1), use the command “SETB EX1”.
4. Now the microcontroller realizes that you are going to use the EX1 interrupt and responds whenever the interrupt is called and directs to the corresponding Interrupt Handler.
5. Place the Interrupt handler at any location in your program mentioning the interrupt handler address. Care should be taken such that the logic of the program should not be spoiled by misplacing the interrupt handler.
6. Don’t forget to end the interrupt handler with the command RETI instead of usual return command RET.



The sample assembly code for using the interrupts is here below:

org 000h //starting address of the program
sjmp main //jumping to the main program
mov p2,#000h //initializing the PORT2 as an output port
mov P1,#000h //initializing the PORT1 as an output port

org 030h //starting address of the main program
main: setb EA //setting Interrupt Enable =1
setb EX1 // initializing the External Interrupt 0 to use
mov a,#0ffh
mov r4,#08h
here: mov P1,a //continuous loop
delay1: lcall delay // toggling all the bits in P1
djnz r4,delay1//using a small delay routine
cpl a
sjmp here

Interrupt Routine:

org 0013h //Interrupt Handler addrees for EX1
setb P3.3 //Reset the external interrupt 1 bit to 1
PUSH Acc // protecting the value present in the accumulator
mov P2,#0fh //changing the value in PORT2 to observe the routine
POP Acc // sending back the value in accumulator safely
RETI // returning back from the interrupt routine


delay: //Delay Routine
mov R1,#01ch
mov R2,#0ffh
mov R3,#15h
here1: djnz R1,here1
djnz R2,here1
RET
End //end of the program

Sunday, May 22, 2011

Interrrupts in Detail : PART1

As the name implies, an interrupt is some event which interrupts normal program execution.

As stated earlier, program flow is always sequential, being altered only by those instructions which expressly cause program flow to deviate in some way. However, interrupts give us a mechanism to "put on hold" the normal program flow, execute a subroutine, and then resume normal program flow as if we had never left it. This subroutine, called an interrupt handler, is only executed when a certain event (interrupt) occurs. The event may be one of the timers "overflowing," receiving a character via the serial port, transmitting a character via the serial port, or one of two "external events." The 8051 may be configured so that when any of these events occur the main program is temporarily suspended and control passed to a special section of code which presumably would execute some function related to the event that occured. Once complete, control would be returned to the original program. The main program never even knows it was interrupted.

The ability to interrupt normal program execution when certain events occur makes it much easier and much more efficient to handle certain conditions. If it were not for interrupts we would have to manually check in our main program whether the timers had overflown, whether we had received another character via the serial port, or if some external event had occured. Besides making the main program ugly and hard to read, such a situation would make our program inefficient since wed be burning precious "instruction cycles" checking for events that usually dont happen.

For example, lets say we have a large 16k program executing many subroutines performing many tasks. Lets also suppose that we want our program to automatically toggle the P3.0 port every time timer 0 overflows. The code to do this isnt too difficult:

JNB TF0,SKIP_TOGGLE
CPL P3.0
CLR TF0
SKIP_TOGGLE: ...

Since the TF0 flag is set whenever timer 0 overflows, the above code will toggle P3.0 every time timer 0 overflows. This accomplishes what we want, but is inefficient. The JNB instruction consumes 2 instruction cycles to determine that the flag is not set and jump over the unnecessary code. In the event that timer 0 overflows, the CPL and CLR instruction require 2 instruction cycles to execute. To make the math easy, lets say the rest of the code in the program requires 98 instruction cycles. Thus, in total, our code consumes 100 instruction cycles (98 instruction cycles plus the 2 that are executed every iteration to determine whether or not timer 0 has overflowed). If were in 16-bit timer mode, timer 0 will overflow every 65,536 machine cycles. In that time we would have performed 655 JNB tests for a total of 1310 instruction cycles, plus another 2 instruction cycles to perform the code. So to achieve our goal weve spent 1312 instruction cycles. So 2.002% of our time is being spent just checking when to toggle P3.0. And our code is ugly because we have to make that check every iteration of our main program loop.

Luckily, this isnt necessary. Interrupts let us forget about checking for the condition. The microcontroller itself will check for the condition automatically and when the condition is met will jump to a subroutine (called an interrupt handler), execute the code, then return. In this case, our subroutine would be nothing more than:

CPL P3.0
RETI

First, youll notice the CLR TF0 command has disappeared. Thats because when the 8051 executes our "timer 0 interrupt routine," it automatically clears the TF0 flag. Youll also notice that instead of a normal RET instruction we have a RETI instruction. The RETI instruction does the same thing as a RET instruction, but tells the 8051 that an interrupt routine has finished. You must always end your interrupt handlers with RETI.

Thus, every 65536 instruction cycles we execute the CPL instruction and the RETI instruction. Those two instructions together require 3 instruction cycles, and weve accomplished the same goal as the first example that required 1312 instruction cycles. As far as the toggling of P3.0 goes, our code is 437 times more efficient! Not to mention its much easier to read and understand because we dont have to remember to always check for the timer 0 flag in our main program. We just setup the interrupt and forget about it, secure in the knowledge that the 8051 will execute our code whenever its necessary.

The same idea applies to receiving data via the serial port. One way to do it is to continuously check the status of the RI flag in an endless loop. Or we could check the RI flag as part of a larger program loop. However, in the latter case we run the risk of missing characters--what happens if a character is received right after we do the check, the rest of our program executes, and before we even check RI a second character has come in. We will lose the first character. With interrupts, the 8051 will put the main program "on hold" and call our special routine to handle the reception of a character. Thus, we neither have to put an ugly check in our main code nor will we lose characters.

What Events Can Trigger Interrupts, and where do they go?

We can configure the 8051 so that any of the following events will cause an interrupt:

Timer 0 Overflow.
Timer 1 Overflow.
Reception/Transmission of Serial Character.
External Event 0.
External Event 1.

In other words, we can configure the 8051 so that when Timer 0 Overflows or when a character is sent/received, the appropriate interrupt handler routines are called.

Obviously we need to be able to distinguish between various interrupts and executing different code depending on what interrupt was triggered. This is accomplished by jumping to a fixed address when a given interrupt occurs.

Interrupt Flag Interrupt Handler Address
External 0 -->IE0--> 0003h
Timer 0 -->TF0--> 000Bh
External 1 -->IE1--> 0013h
Timer 1 -->TF1--> 001Bh
Serial -->RI/TI-->0023h

By consulting the above chart we see that whenever Timer 0 overflows (i.e., the TF0 bit is set), the main program will be temporarily suspended and control will jump to 000BH. It is assumed that we have code at address 000BH that handles the situation of Timer 0 overflowing.

TImers and counters in embedded systems

Introduction to Counter/Timers

Counter/timer hardware is a crucial component of most embedded systems. In some cases a timer is needed to measure elapsed time; in others we want to count or time some external events. Here's a primer on the hardware.

Counter/timer hardware is a crucial component of most embedded systems. In some cases, a timer measures elapsed time (counting processor clock ticks). In others, we want to count or time external events. The names counter and timer can be used interchangeably when talking about the hardware. The difference in terminology has more to do with how the hardware is used in a given application.



Figure 1: A simple counter/timer

Figure 1 shows a simple timer similiar to those often included on-chip within a microcontroller. You could build something similar from a couple of 74HC161 counters or a programmable logic device. The timer shown consists of a loadable 8-bit count register, an input clock signal, and an output signal. Software loads the count register with an initial value between 0x00 and 0xFF. Each subsequent transition of the input clock signal increments that value.

When the 8-bit count overflows, the output signal is asserted. The output signal may thereby trigger an interrupt at the processor or set a bit that the processor can read. To restart the timer, software reloads the count register with the same or a different initial value.

If a counter is an up counter, it counts up from the initial value toward 0xFF. A down counter counts down, toward 0x00.

A typical counter will have some means to start the counter running once it is loaded, usually by setting a bit in a control register. This is not shown in the figure. A real counter would generally also provide a way for the processor to read the current value of the count register at any time, over the data bus.

Semi-automatic

A timer with automatic reload capability will have a latch register to hold the count written by the processor. When the processor writes to the latch, the count register is written as well. When the timer later overflows, it first generates an output signal. Then, it automatically reloads the contents of the latch into the count register. Since the latch still holds the value written by the processor, the counter will begin counting again from the same initial value.

Such a timer will produce a regular output with the same accuracy as the input clock. This output could be used to generate a periodic interrupt like a real-time operating system (RTOS) timer tick, provide a baud rate clock to a UART, or drive any device that requires a regular pulse.

A variation of this feature found in some timers uses the value written by the processor as the endpoint rather than the initial count. In this case, the processor writes into a terminal count register that is constantly compared with the value in the count register. The count register is always reset to zero and counts up. When it equals the value in the terminal count register, the output signal is asserted. Then the count register is reset to zero and the process repeats. The terminal count remains the same. The overall effect is the same as an overflow counter. A periodic signal of a pre-determined length will then be produced.

If a timer supports automatic reloading, it will often make this a software-selectable feature. To distinguish between a count that will not repeat automatically and one that will, the hardware is said to be in one of two modes: one-shot or periodic. The mode is generally controlled by a field in the timer's control register. Input capture



Figure 2: An input capture timer

An input capture timer, like the one shown in Figure 2, has a latch connected to the timer's count register. The timer is run at a constant clock rate (usually a derivative of the processor clock), so that the count register is constantly incrementing (or decrementing, for a down counter). An external signal latches the value of the free-running timer into the processor-visible register and generates an output signal (typically an interrupt).

One use for an input capture timer is to measure the time between the leading edge of two pulses. By reading the value in the latch and comparing it with a previous reading, the software can determine how many clock cycles elapsed. In some cases, the timer's count register might be automatically reset just after its value is latched. If so, the software can directly interpret the value it reads as the number of clock ticks elapsed. An input capture pin can usually be programmed to capture on either the rising or falling edge of the input signal.

Options abound

Many timers provide a means to prescale the input clock signal. For example, the 8-bit timer in Atmel's AT90S8515 microcontroller can be incremented with every processor clock cycle, every 8th, every 64th, every 256th, or every 1,024th. Selecting a less frequent update cycle is called prescaling the input clock. Similarly, each increment could occur on either the rising or falling edge of some other signal entirely. In the Atmel part, these features are software-selectable.

Some timers can directly control a general-purpose I/O pin. When an overflow occurs, the pin can be automatically set to 1, reset to 0, or toggled. This can be useful in, for example, generating a PWM signal.1 Using two different initial or terminal count values and a one-shot timer that toggles the I/O pin on overflow, the pin could be set to 1 for a desired amount of time, then 0 for a different amount of time, then 1 again, and so on. The period of the PWM signal would be a function of the sum of the two timer lengths. The duty cycle would then be the length of time that the pin is set to 1 as a percentage of the period.

Although the examples here have focused on 8-bit timers, the concepts apply to larger timers as well.

Ref: http://www.eetimes.com/discussion/beginner-s-corner/4024440/Introduction-to-Counter-Timers