Embedded Programming in C language

Thread Starter

iana264

Joined Oct 14, 2014
6
Hello!
Can you help me please.
I am a student and i have some problems with one task.
I had to write a program for an embedded system which will have 8 buttons and will show on 7-segment display the number of the button pressed last.
I wrote the program but the teacher said that i must use external interrupts and that i can't use polling.I can't quite figure out what should i do next and how to fix my code so that it will fit the teachers demands.
Here is the code that i wrote and the scheme in proteus.
Thanks in advance,hope you can help me.






Here is the code i came up with:

Code:
// Program to display number by taking input from the user

#include <reg51.h>

sbit in1=P1^0;        // input pins
sbit in2=P1^1;
sbit in3=P1^2;
sbit in4=P1^3;
sbit in5=P1^4;
sbit in6=P1^5;
sbit in7=P1^6;
sbit in8=P1^7;


sbit ou1=P2^0;        // output pins
sbit ou2=P2^1;
sbit ou3=P2^2;
sbit ou4=P2^3;
sbit ou5=P2^4;
sbit ou6=P2^5;
sbit ou7=P2^6;

void main()
{
  in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = 1;  // Initialize the input pin
  ou1 = ou2 = ou3 = ou4 = ou5 = ou6 = ou7 = 1;
  while(1)
    {
        if (in1==0)
        {
        ou2 = ou3 = 0;
        ou1 = ou4 = ou5 = ou6 = ou7 = 1;
        }
        if (in2==0)
        {
        ou1 = ou2 = ou4 = ou5 = ou7 = 0;
        ou3 = ou6 = 1;
        }   
        if (in3==0)
        {
        ou1 = ou2 = ou4 = ou3 = ou7 = 0;
        ou5 = ou6 = 1;
        }
        if (in4==0)
        {
        ou3 = ou2 = ou6 = ou7 = 0;
        ou1 = ou4 = ou5 = 1;
        }
        if (in5==0)
        {
        ou1 = ou3 = ou4 = ou6 = ou7 = 0;
        ou2 = ou5 = 1;
        }


        if (in6==0)
        {
        ou1 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
        ou2 = 1;
        }

        if (in7==0)
        {
        ou1 = ou3 = ou2 = 0;
        ou4 = ou5 = ou6 = ou7 = 1;
        }

        if (in8==0)
        {
        ou1 = ou2 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
        }

    }
}
 

Attachments

Last edited by a moderator:

Papabravo

Joined Feb 24, 2006
21,225
Tell me how you think an interrupt works on an 8051 architecture part. Then we can talk about how you might use one to solve your problem.
 

Thread Starter

iana264

Joined Oct 14, 2014
6
Tell me how you think an interrupt works on an 8051 architecture part. Then we can talk about how you might use one to solve your problem.
I think when a specific event happens the interrupt occurs ,executes a subroutine, and then it returns to the main program execution.I also know that an interrupt can be caused by :Timer 0 Overflow,Timer 1 Overflow,Reception/Transmission of Serial Character,External Event 0 or External Event 1.
I just don't understand how to implement this in my task ...
 

Thread Starter

iana264

Joined Oct 14, 2014
6
I did something like this, but it doesn't work anyway, what i did wrong?

Code:
#include<reg51.h>


sbit in1=P1^0;        // input pins
sbit in2=P1^1;
sbit in3=P1^2;
sbit in4=P1^3;
sbit in5=P1^4;
sbit in6=P1^5;
sbit in7=P1^6;
sbit in8=P1^7;


sbit ou1=P2^0;        // output pins
sbit ou2=P2^1;
sbit ou3=P2^2;
sbit ou4=P2^3;
sbit ou5=P2^4;
sbit ou6=P2^5;
sbit ou7=P2^6;
          // Pin P1.0 is named as LED

//Function declarations
void cct_init(void);
void InitINT0(void);

// Main function
void main(void)
{
  in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = 1;  // Initialize the input pin
  ou1 = ou2 = ou3 = ou4 = ou5 = ou6 = ou7 = 1;

   cct_init();       // Make all ports zero
   InitINT0();      // Intialize INT0 interrupts

   while(1)
   {}
}

// Init CCT function
void cct_init(void)
{
    P0 = 0x00;    // Make all pins zero
    P1 = 0x00;    // Make all pins zero
    P2 = 0x00;    // Make all pins zero
    P3 = 0x04;    // Make P3.2 (INT0) pin high only
}

// External INT0 pin interrupt init function
void InitINT0(void)
{
    IT0 = 1;      //Edge triggered interrupt mode (Neg Edge)
    EX0 = 1;      //Enable external interrupt INT0
    EA  = 1;      //Enable global interrupts
}

// INT0 ISR
void external0_isr(void) interrupt 0
{
           if (in1==0)
        {
        ou2 = ou3 = 0;
        ou1 = ou4 = ou5 = ou6 = ou7 = 1;
        }
        if (in2==0)
        {
        ou1 = ou2 = ou4 = ou5 = ou7 = 0;
        ou3 = ou6 = 1;
        }
        if (in3==0)
        {
        ou1 = ou2 = ou4 = ou3 = ou7 = 0;
        ou5 = ou6 = 1;
        }
        if (in4==0)
        {
        ou3 = ou2 = ou6 = ou7 = 0;
        ou1 = ou4 = ou5 = 1;
        }
        if (in5==0)
        {
        ou1 = ou3 = ou4 = ou6 = ou7 = 0;
        ou2 = ou5 = 1;
        }


        if (in6==0)
        {
        ou1 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
        ou2 = 1;
        }

        if (in7==0)
        {
        ou1 = ou3 = ou2 = 0;
        ou4 = ou5 = ou6 = ou7 = 1;
        }

        if (in8==0)
        {
        ou1 = ou2 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
        }

    }

}
 
Last edited by a moderator:

Papabravo

Joined Feb 24, 2006
21,225
Well that is a start. Look at the description in the datasheet and see if you can understand the difference between an edge-triggered interrupt and a level triggered interrupt. Interrupts have to be configured and they have to be enabled. There is also a global interrupt enable that must be dealt with. In the 8051 architecture there are also two priority levels to deal with.

Lastly you must find and understand the mechanism that connects an absolute address in low program memory to the interrupt subroutine and you have to tell the C compiler to treat the interrupt subroutine differently by using a return from interrupt instead of a standard return instruction. If you have not done so already you need to get your compiler to give you an assembly listing of the compiled code. That way you can check these little details. As you have already noted things are not working and they are not working because you have not dug into the documentation deeply enough. It might help if you did the assignment in assembly language, then you'd know what to look for in the compiler generated code.

Knowing stuff like this is what gets you paid Big Bucks.

Good Luck
 

Papabravo

Joined Feb 24, 2006
21,225
i dont know can you help me? i did what i know
What you currently know is obviously not good enough to solve the problem. I've given you a large number of clues. Are you telling me you cannot read the datasheet and the applications notes in such a way as to make progress on the problem? Of course I could do everything for you, but then you wouldn't learn anything. I would rather have you struggle and learn something.

So we have hardware in the 8051 that recognizes the presence of an interrupt. Let's take External Interrupt 0. When the hardware detects External Interrupt 0 it sets a flag (a bit in a register), it saves the program counter on the stack, and the next instruction is fetched from an absolute location in the lowest page of Program Memory.

Q: What absolute location in the lowest page of Program Memory does the processor fetch an instruction from when External Interrupt 0 is recognized? Express the value in hexidecimal notation.
A:

Q: What absolute location in the lowest page of Program Memory does the processor fetch an instruction from when it comes out of RESET? Express the value in hexidecimal notation.
A:

Answer these questions and we'll proceed to the next issue.

In case you don't even have a datasheet -- let's use this one
http://www.atmel.com/images/doc4316.pdf

See Section 2.16
 
Last edited:

Thread Starter

iana264

Joined Oct 14, 2014
6
What you currently know is obviously not good enough to solve the problem. I've given you a large number of clues. Are you telling me you cannot read the datasheet and the applications notes in such a way as to make progress on the problem? Of course I could do everything for you, but then you wouldn't learn anything. I would rather have you struggle and learn something.
Please do it for me! I promise i will learn it after that, i need it for tomorrow, could you please do it for me, if you can. It will take a lot of time to understand this, but i promise to make effort for understanding all what you came up. Thx in advance
 

shteii01

Joined Feb 19, 2010
4,644
Papa I am somewhat curious about the 8 buttons/triggers. I just checked my 8051 textbook (from my uC class) and 8051 has two external hardware interrupts. So, for example, I can use External Hardware Interrupt 1 to with Button 1, I can use External Hardware Interrupt 2 with Button 2. What do I use for Buttons 3-8?
 

Papabravo

Joined Feb 24, 2006
21,225
I would generate a signal that triggers when any button is pushed. Then I would look to see which one it was. This can easily be done with a wire-OR and a pullup
 

Papabravo

Joined Feb 24, 2006
21,225
The schematic shows exactly that: it seems that everything hardware is in place.
I don't think it does. Maybe I'm missing something. Are you talking about the port line that is connected to the diodes and a pulldown resistor? I thought that was to pull up all of the lines except the one that is grounded when the port pin was high. 8051 pins won't source much current, they are not true CMOS outputs. I can't tell from the unreadable diagram which port pin it is connected to. Is it Port 2.2?

I still want to know where interrupt 0 goes. How's about it.
 

tindel

Joined Sep 16, 2012
936
Papabravo, bravo on enlightening this soon to be engineer (or not) on the value of hard work and digging in to a problem.

I am currently working with a software engineer that was afraid to dig in and figure out why his software wasn't communicating properly over a USB/RS232... I ended up doing the work for him because I didn't have time to argue with him. I'm smarter now... Turns out his software wasn't sending a 'ready to send' command.
 

Papabravo

Joined Feb 24, 2006
21,225
I've spent half a century digging in and solving problems. I'd like to think that I can still track down and read a datasheet.
 

JWHassler

Joined Sep 25, 2013
306
I don't think it does. Maybe I'm missing something. Are you talking about the port line that is connected to the diodes and a pulldown resistor? I thought that was to pull up all of the lines except the one that is grounded when the port pin was high. 8051 pins won't source much current, they are not true CMOS outputs. I can't tell from the unreadable diagram which port pin it is connected to. Is it Port 2.2?

I still want to know where interrupt 0 goes. How's about it.
Quite true: the schematic is maddeningly indistinct, but the diodes seem to be tied to INT0, and they will pull that pin down via R15? ( assuming the symbol to which R15? connects is VCC.)
 

Papabravo

Joined Feb 24, 2006
21,225
Quite true: the schematic is maddeningly indistinct, but the diodes seem to be tied to INT0, and they will pull that pin down via R15? ( assuming the symbol to which R15? connects is VCC.)
It actually looks like ground, but maybe not. We know that ports 1, 2, and 3 have internal weak pullups due the design of the "quasi-bi-directional" ports of the architecture. In any case one diode drop above ground is not exactly a well defined logic low. As you also know the "quasi-bi-directional" port structure of the 8051 is really really bad at sourcing current into a pulldown. There is also the matter of using a mechanical switch on a negative edge triggered interrupt without some debouncing. You can do it in the firmware but you have to be aware of the problem.

What is the semantic meaning of the trailing 0 in the following declaration?
Code:
void external0_isr(void) interrupt 0
In some compilers (IAR), it should be the address of the interrupt vector. As we know 0 is the RESET Vector.

I still can't see confirmation that the interrupt ISR is correctly linked to the proper location in page 0 of Code Memory.
 
Last edited:
Top