Embedded Programming in C language

Discussion in 'Embedded Systems and Microcontrollers' started by iana264, Oct 14, 2014.

  1. iana264

    Thread Starter New Member

    Oct 14, 2014
    6
    0
    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 ( (Unknown Language)):
    1.  
    2. // Program to display number by taking input from the user
    3.  
    4. #include <reg51.h>
    5.  
    6. sbit in1=P1^0;        // input pins
    7. sbit in2=P1^1;
    8. sbit in3=P1^2;
    9. sbit in4=P1^3;
    10. sbit in5=P1^4;
    11. sbit in6=P1^5;
    12. sbit in7=P1^6;
    13. sbit in8=P1^7;
    14.  
    15.  
    16. sbit ou1=P2^0;        // output pins
    17. sbit ou2=P2^1;
    18. sbit ou3=P2^2;
    19. sbit ou4=P2^3;
    20. sbit ou5=P2^4;
    21. sbit ou6=P2^5;
    22. sbit ou7=P2^6;
    23.  
    24. void main()
    25. {
    26.   in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = 1;  // Initialize the input pin
    27.   ou1 = ou2 = ou3 = ou4 = ou5 = ou6 = ou7 = 1;
    28.   while(1)
    29.     {
    30.         if (in1==0)
    31.         {
    32.         ou2 = ou3 = 0;
    33.         ou1 = ou4 = ou5 = ou6 = ou7 = 1;
    34.         }
    35.         if (in2==0)
    36.         {
    37.         ou1 = ou2 = ou4 = ou5 = ou7 = 0;
    38.         ou3 = ou6 = 1;
    39.         }  
    40.         if (in3==0)
    41.         {
    42.         ou1 = ou2 = ou4 = ou3 = ou7 = 0;
    43.         ou5 = ou6 = 1;
    44.         }
    45.         if (in4==0)
    46.         {
    47.         ou3 = ou2 = ou6 = ou7 = 0;
    48.         ou1 = ou4 = ou5 = 1;
    49.         }
    50.         if (in5==0)
    51.         {
    52.         ou1 = ou3 = ou4 = ou6 = ou7 = 0;
    53.         ou2 = ou5 = 1;
    54.         }
    55.  
    56.  
    57.         if (in6==0)
    58.         {
    59.         ou1 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
    60.         ou2 = 1;
    61.         }
    62.  
    63.         if (in7==0)
    64.         {
    65.         ou1 = ou3 = ou2 = 0;
    66.         ou4 = ou5 = ou6 = ou7 = 1;
    67.         }
    68.  
    69.         if (in8==0)
    70.         {
    71.         ou1 = ou2 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
    72.         }
    73.  
    74.     }
    75. }
    76.  
     
    Last edited by a moderator: Oct 14, 2014
  2. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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.
     
  3. iana264

    Thread Starter New Member

    Oct 14, 2014
    6
    0
    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 ...
     
  4. iana264

    Thread Starter New Member

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

    Code (Text):
    1.  
    2. #include<reg51.h>
    3.  
    4.  
    5. sbit in1=P1^0;        // input pins
    6. sbit in2=P1^1;
    7. sbit in3=P1^2;
    8. sbit in4=P1^3;
    9. sbit in5=P1^4;
    10. sbit in6=P1^5;
    11. sbit in7=P1^6;
    12. sbit in8=P1^7;
    13.  
    14.  
    15. sbit ou1=P2^0;        // output pins
    16. sbit ou2=P2^1;
    17. sbit ou3=P2^2;
    18. sbit ou4=P2^3;
    19. sbit ou5=P2^4;
    20. sbit ou6=P2^5;
    21. sbit ou7=P2^6;
    22.           // Pin P1.0 is named as LED
    23.  
    24. //Function declarations
    25. void cct_init(void);
    26. void InitINT0(void);
    27.  
    28. // Main function
    29. void main(void)
    30. {
    31.   in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = 1;  // Initialize the input pin
    32.   ou1 = ou2 = ou3 = ou4 = ou5 = ou6 = ou7 = 1;
    33.  
    34.    cct_init();       // Make all ports zero
    35.    InitINT0();      // Intialize INT0 interrupts
    36.  
    37.    while(1)
    38.    {}
    39. }
    40.  
    41. // Init CCT function
    42. void cct_init(void)
    43. {
    44.     P0 = 0x00;    // Make all pins zero
    45.     P1 = 0x00;    // Make all pins zero
    46.     P2 = 0x00;    // Make all pins zero
    47.     P3 = 0x04;    // Make P3.2 (INT0) pin high only
    48. }
    49.  
    50. // External INT0 pin interrupt init function
    51. void InitINT0(void)
    52. {
    53.     IT0 = 1;      //Edge triggered interrupt mode (Neg Edge)
    54.     EX0 = 1;      //Enable external interrupt INT0
    55.     EA  = 1;      //Enable global interrupts
    56. }
    57.  
    58. // INT0 ISR
    59. void external0_isr(void) interrupt 0
    60. {
    61.            if (in1==0)
    62.         {
    63.         ou2 = ou3 = 0;
    64.         ou1 = ou4 = ou5 = ou6 = ou7 = 1;
    65.         }
    66.         if (in2==0)
    67.         {
    68.         ou1 = ou2 = ou4 = ou5 = ou7 = 0;
    69.         ou3 = ou6 = 1;
    70.         }
    71.         if (in3==0)
    72.         {
    73.         ou1 = ou2 = ou4 = ou3 = ou7 = 0;
    74.         ou5 = ou6 = 1;
    75.         }
    76.         if (in4==0)
    77.         {
    78.         ou3 = ou2 = ou6 = ou7 = 0;
    79.         ou1 = ou4 = ou5 = 1;
    80.         }
    81.         if (in5==0)
    82.         {
    83.         ou1 = ou3 = ou4 = ou6 = ou7 = 0;
    84.         ou2 = ou5 = 1;
    85.         }
    86.  
    87.  
    88.         if (in6==0)
    89.         {
    90.         ou1 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
    91.         ou2 = 1;
    92.         }
    93.  
    94.         if (in7==0)
    95.         {
    96.         ou1 = ou3 = ou2 = 0;
    97.         ou4 = ou5 = ou6 = ou7 = 1;
    98.         }
    99.  
    100.         if (in8==0)
    101.         {
    102.         ou1 = ou2 = ou5 = ou3 = ou4 = ou6 = ou7 = 0;
    103.         }
    104.  
    105.     }
    106.  
    107. }
    108.  
     
    Last edited by a moderator: Oct 14, 2014
  5. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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
     
  6. iana264

    Thread Starter New Member

    Oct 14, 2014
    6
    0
    i dont know can you help me? i did what i know
     
  7. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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: Oct 14, 2014
  8. iana264

    Thread Starter New Member

    Oct 14, 2014
    6
    0
    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
     
  9. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    Sorry, I'd hate myself in the morning if I did it for you.
     
  10. iana264

    Thread Starter New Member

    Oct 14, 2014
    6
    0
    you said that you can do it for me, and then.... :( :'(
     
  11. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,395
    497
    I detect a language problem.
     
  12. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,395
    497
    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?
     
  13. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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
     
    Chalma likes this.
  14. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    I'd be more sympathetic if I saw you making an effort.
     
  15. JWHassler

    Member

    Sep 25, 2013
    201
    33
    The schematic shows exactly that: it seems that everything hardware is in place.
     
  16. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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.
     
  17. tindel

    Active Member

    Sep 16, 2012
    568
    193
    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 likes this.
  18. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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.
     
  19. JWHassler

    Member

    Sep 25, 2013
    201
    33
    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.)
     
  20. Papabravo

    Expert

    Feb 24, 2006
    10,152
    1,793
    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 (Text):
    1.  
    2. void external0_isr(void) interrupt 0
    3.  
    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: Oct 15, 2014
Loading...