8051 interrupts

Discussion in 'Embedded Systems and Microcontrollers' started by Chalma, Oct 14, 2013.

  1. Chalma

    Thread Starter Member

    May 19, 2013
    54
    2
    Hello it's me again asking more simple questions. I'm still trying to get the hang of this 8051 stuff. I bought the c8051f020 development board, it has an onboard LED (on P1.6) that I use along with a switch SW2 (on P3.7). My goal was to have a PWM (on P1.0) line that I can turn on and off with the SW2. The PWM line I gave about a 10-15% Duty Cycle and for now I just hooked it up to some LEDs and my scope so that I can see that it is indeed outputting the PWM signal. I have the onboard LED (P1.6) as an indicator that it is indeed recognizing my push button response. you may think that the push button is silly for input the PWM but I don't know the 8051 and as I get better SW2 will be replaced with input from a different PWM source. What happens is that my program is getting stuck and I do not understand why, mainly because interrupts are not really easy to use (compared with the arduino). What I intend to happen is on bootup nothing will happen, when SW2 is pressed [mode 1] the PWM will turn on, if the button is pressed again it will turn off. Later I also intend to have the pushbutton change the PWM (i.e. no push is off, one push is 10%DC, two pushes is 50%DC, three pushes back to off ....you get it). I am posting my code below and any help would be appreciated. I would also appreciate any recommended materials to read as I am a hands on visual learner and I learn better from looking at code and building the circuit. I.E. my buddy told me to go to this place and it started talking about the 3rd bit in some register and how you cycle it but not before you call all this fancy hex code(I'm a dummy I don't understand things that way)

    Code ( (Unknown Language)):
    1.  
    2. #include <c8051f020.h>
    3.  
    4. #define OFF 0 //off
    5. #define ON 1 //on
    6. #define PWMPIN P1_0 //PWM pin is port 1 pin 1 definition
    7.  
    8. sbit button = P3^7; //Onboard Devkit SW2
    9. sbit light = P1^6;  //onboard LED D3
    10. sbit PWMPIN = P1^0; //PWMPIN 1 is set as pin1
    11. int buttoncycle = 0;  //buttons status for mode of operiation 0 == OFF
    12. unsigned char pwm_width;  //pwm 0-255 DutyCycle i.e. 217 is |[(217/255) * 100]-100|
    13. bit pwm_flag = 0; //pwm_active?
    14.  
    15. //++++++++ Predefined functions
    16. void pwm_setup();
    17. void initialization(); //setting of lines
    18. //void INT0_ISR() interrupt 19; //button Int acting like pulse in detect
    19. void delay_in_ms(unsigned int); //delay function based on cycles per second
    20. void pwm_setup(); //pwm predefinition
    21. //void timer0() interrupt 1; //timer interrupt for pwm
    22. void listen_loop(); // "listen" for the pulse
    23. void light_it(); //SW2 LED on
    24. void unlight_it(); //SW2 LED off
    25. void listen_loop(); //infinite loop testing for interrupt trips etc.
    26. void buttoncount(int); //on, off cycle ( for now... maybe add other modes)
    27.  
    28. //++++++++
    29.  
    30.  
    31.  
    32. void light_it() //function for SW2 LED (on)
    33. { light = ON; }
    34.  
    35. void unlight_it()  //function for SW2 LED (off)
    36. { light = OFF; }
    37.  
    38. void delay_in_ms(unsigned int count)
    39. { //mSec Delay 22.1Mhz, delay based on clock cycle
    40. unsigned int i;
    41. while (count)
    42. {
    43.     i = 221;
    44.     while(i>0) i--; //count down 221 cycles 1ms X cycles
    45.     count--;
    46. }
    47. return;
    48. }
    49.  
    50. void pwm_setup()
    51. { //predef for PWM
    52. TMOD = 0; //timer count mode
    53. pwm_width = 217; //pwm 0-255 DutyCycle i.e. 217 is |[(217/255) * 100]-100|
    54. EA = 1;    //global interrupts enabled
    55. ET0 = 1;    //Timer interrupt 0 enabled
    56. TR0 = 1;    //Timer 0 on
    57. }
    58.  
    59. void timer0() interrupt 1
    60. {
    61.  
    62. if(!pwm_flag) //high
    63. {
    64. pwm_flag = 1; //setflag
    65. PWMPIN = 1; //set PWM o/p pin
    66. TH0 = pwm_width; //load timer
    67. TF0 = 0;    //clear interrupt flag
    68. return;
    69. }
    70.  
    71. else //LOW
    72. {
    73. pwm_flag = 0;    //clearflag
    74. PWMPIN = 0;    //clear PWM o/p pin
    75. TH0 = 255 - pwm_width;    //load timer
    76. delay_in_ms(300);  //BAD don't do use in non interrupt mode
    77. TF0 = 0;    //clear interrupt flag
    78. return;
    79. }
    80.  
    81. }
    82.  
    83. void initialization()
    84. {
    85. P3IF |= 0x08;    //Port 3 interrupt flag
    86. P3MDOUT &= ~0x80;    //Port 3 output mode
    87. P3 |= 0x80;            //Latch it
    88. EIE2 |= 0x20;        //enable interrupt 2
    89. EA = 1;        //enable global variables
    90.  
    91. WDTCN = 0xde;    //disable watchdog timer
    92. WDTCN = 0xad;    //must be winthin 4 clock cycles
    93. light = OFF;    //initial start light off
    94.  
    95. XBR2 = 0x40;    //Enable crossbar
    96. P1MDOUT |= 0x41;    //Enable P1^0 and P1^6 as outputs (transistor pwm and green D3 LED)
    97. P1MDIN = 0xFE;        //Port 1 input mode (p3.7 SW2 switch)
    98. PWMPIN = 0;            //disable PWM
    99. }
    100.  
    101. void buttoncount(int temp) // mode 0 off mode 1 ON mode 2+ back to off
    102. {
    103.  
    104. if (temp == 0)
    105. {
    106. ET0 = 0;
    107.  
    108. }
    109.  
    110. if (temp == 1)
    111. {
    112. ET0 = 1;
    113. }
    114.  
    115. if (temp >= 2)
    116. {
    117. buttoncycle == 0;
    118. }
    119. buttoncount(buttoncycle); //repeat this forever
    120. }
    121.  
    122. void INT0_ISR() interrupt 19
    123. {
    124. light_it();        //turn D3 on to show button is pressed
    125. buttoncycle ++;    //cycle switch
    126. delay_in_ms(50); //delay 50ms to show light
    127. unlight_it();    //turn D3 off
    128.  
    129. }
    130.  
    131. main()
    132. {
    133. pwm_setup();    //init pwm
    134. initialization();    //init everything else
    135.  
    136. buttoncount(0);    //continuously monitor SW2 (P3.7)
    137. }
     
    Last edited: Oct 14, 2013
  2. MrChips

    Moderator

    Oct 2, 2009
    12,414
    3,353
    You have in the function buttoncount() calling itself.
    That is a no-no.
     
  3. Chalma

    Thread Starter Member

    May 19, 2013
    54
    2
    you are def. right and in my frantic state to try and get the code working I goofed. I removed the offending call unto and instead inserted
    Code ( (Unknown Language)):
    1. while (1){
    2. buttoncount(buttoncycle);    //continuously monitor SW2 (P3.7)
    3. }
    I still need help however as the code still get's stuck. either in repeating the flashing and not listening to my button states or the LED (green one on P1.6) being held down. I even tried inserting return; into my void functions to no avail.
     
  4. Arm_n_Legs

    Active Member

    Mar 7, 2007
    183
    10
    Why are there "return" statements in timer interrupt routine? Return (RETI) instruction in assembly language for interrupt routine to go return to the calling routine, but they are not needed in C.

    Try removing both the return statements.

    cheers~:)
     
  5. MrChips

    Moderator

    Oct 2, 2009
    12,414
    3,353
    The return statement is a valid C statement that returns to the calling program.
    An interrupt routine cannot use the return statement since it requires a return from interrupt.

    Remove all return statements.
     
  6. Chalma

    Thread Starter Member

    May 19, 2013
    54
    2
    Thanks to everyone. I finally discovered the source of all my heartache. I did remove the returns in other versions of my code. I KNEW what the problem was (with the button interrupt) but I did not have enough experience or know how to really understand it. I worked through it really slow and discovered that I needed to clear the flag bit of the interrupt on P3IF. being unfamiliar I found other tutorials on how to clear the flag bit of other registers then mimiced that in my code with great sucess. My code isn't perfect but at least I have a basis to work off of in getting familiar with the 8051. Thanks to all. I would still appreciate any input on books or such to help me. I love my arduino but it really holds my hand (I've never had to clear inturrupts on it 'cause it did so automatically). below is my code in case a newbie like me needs to use it as reference.
    Code ( (Unknown Language)):
    1.  #include <c8051F020.h>
    2.  
    3. #define OFF 0 //off
    4. #define ON 1 //on
    5. #define PWMPIN P1_0 //PWM pin is port 1 pin 1 definition
    6.  
    7. sbit button = P3^7; //Onboard Devkit SW2
    8. sbit light = P1^6; //onboard LED D3
    9. sbit PWMPIN = P1^0; //PWMPIN 1 is set as pin1
    10. int buttoncycle = 0; //buttons status for mode of operiation 0 == OFF
    11. unsigned char pwm_width; //pwm 0-255 DutyCycle i.e. 217 is |[(217/255) * 100]-100|
    12. bit pwm_flag = 0; //pwm_active?
    13.  
    14.  
    15. //++++++++ Predefined functions
    16. void pwm_setup();
    17. void initialization(); //setting of lines
    18. //void INT0_ISR() interrupt 19; //button Int acting like pulse in detect
    19. void delay_in_ms(unsigned int); //delay function based on cycles per second
    20. void pwm_setup(); //pwm predefinition
    21. //void timer0() interrupt 1; //timer interrupt for pwm
    22. //void listen_loop(); // "listen" for the pulse
    23. void light_it(); //SW2 LED on
    24. void unlight_it(); //SW2 LED off
    25. //void listen_loop(); //infinite loop testing for interrupt trips etc.
    26. void buttoncount(int); //on, off cycle ( for now... maybe add other modes)
    27. //++++++++
    28.  
    29.  
    30. void light_it() //function for SW2 LED (on)
    31. { light = ON;}
    32.  
    33. void unlight_it() //function for SW2 LED (off)
    34. { light = OFF;}
    35.  
    36. void delay_in_ms(unsigned int count)
    37. { //mSec Delay 22.1Mhz, delay based on clock cycle
    38. unsigned int i;
    39. while (count)
    40. {
    41. i = 221;
    42. while(i>0) i--; //count down 221 cycles 1ms X cycles
    43. count--;
    44. }
    45. }
    46.  
    47.  
    48. void pwm_setup()
    49. { //predef for PWM
    50. TMOD = 0; //timer count mode
    51. pwm_width = 217; //pwm 0-255 DutyCycle i.e. 217 is |[(217/255) * 100]-100|
    52. EA = 1; //global interrupts enabled
    53. ET0 = 1; //Timer interrupt 0 enabled
    54. TR0 = 1; //Timer 0 on
    55. }
    56.  
    57. void timer0() interrupt 1
    58. {
    59. if(!pwm_flag) //high
    60. {
    61. pwm_flag = 1; //setflag
    62. PWMPIN = 1; //set PWM o/p pin
    63. TH0 = pwm_width; //load timer
    64. TF0 = 0; //clear interrupt flag
    65. }
    66. else //LOW
    67. {
    68. pwm_flag = 0; //clearflag
    69. PWMPIN = 0; //clear PWM o/p pin
    70. TH0 = 255 - pwm_width; //load timer
    71. //delay_in_ms(300); //BAD don't do use in non interrupt mode
    72. TF0 = 0; //clear interrupt flag
    73. }
    74. }
    75.  
    76. void initialization()
    77. {
    78. P3IF = 0x08;
    79. P3MDOUT &= ~0x80; //Port 3 output mode
    80. P3IF |= 0x08; //Port 3 interrupt flag
    81.  
    82. P3 |= 0x80; //Latch it
    83. EIE2 |= 0x20; //enable interrupt 2
    84. EA = 1; //enable global variables
    85.  
    86.  
    87. WDTCN = 0xde; //disable watchdog timer
    88. WDTCN = 0xad; //must be winthin 4 clock cycles
    89. light = OFF; //initial start light off
    90. XBR2 = 0x40; //Enable crossbar
    91. P1MDOUT |= 0x41; //Enable P1^0 and P1^6 as outputs (transistor pwm and green D3 LED)
    92. P1MDIN = 0xFE; //Port 1 input mode (p3.7 SW2 switch)
    93. PWMPIN = 0; //disable PWM
    94. }
    95.  
    96. void buttoncount(int temp)
    97. {
    98. if (temp == 0) //mode 0 == off
    99. {
    100. ET0 = OFF; //turn clock off
    101. };
    102. if (temp == 1) //mode 1 == button pressed once
    103. {
    104. ET0 = ON; //turn clock on
    105. delay_in_ms(800);
    106. };
    107. if (temp > 1) //mode 2+ back to off
    108. {
    109. buttoncycle = 0;
    110. };
    111. }
    112.  
    113. void button_ISR() interrupt 19
    114. {
    115. P3IF = ~0x80; //clear interrupt
    116. light_it(); //turn D3 on to show button is pressed
    117. buttoncycle ++; //cycle switch
    118. delay_in_ms(50); //delay 50ms to show light
    119. unlight_it(); //turn D3 off
    120. //buttoncount(buttoncycle);
    121. }
    122.  
    123. main()
    124. {
    125. pwm_setup(); //init pwm
    126. initialization(); //init everything else
    127. while (1){
    128.  
    129. buttoncount(buttoncycle); //continuously monitor SW2 (P3.7)
    130.  
    131.  
    132.  
    133. };
    134. }
    Thanks again.
     
Loading...