Forums MPLAB XC8 Project Discussions Ping pong game in C

Tagged: 

This topic contains 12 replies, has 2 voices, and was last updated by  Bitahwa Bindu 5 months, 1 week ago.

  • Author
    Posts
  • #3023

    Viga uk
    Participant

    I have been struggling to create a code with interrupts on the pic18f8722 for a ping pong project .The game allows two plays operating a button RA5 and RB0  and PORTD is where you play.Game starts when when first player presses the button and serves the ball .Player must press the ball when it is on their end which is RD0 and RD8 if you are player 2.Any button presses at any other time results in losing the game.If the ball leaves the tables (goes beyond LED  at either end),player who misses loses the game .When game is over Led for the winning player flashes 5 times.I am doing it in C ,how do you do it  interrupt way?

    Kind regards

  • #3024

    Bitahwa Bindu
    Keymaster

    Hi:

    Please watch this video to learn how to use External interrupts:

  • #3025

    Viga uk
    Participant

    I watched the video but how do you have the game start with a button press(interrupt) and not main function?

  • #3027

    Bitahwa Bindu
    Keymaster

    You could put your game functions in an IF STATEMENT in the while (1) loop. Only when this statement evaluates to true (After an interrupt has occurred), then you can play.

  • #3028

    Viga uk
    Participant

    #define LED1 PORTDbits.RD0
    #define LED8 PORTDbits.RD7

    void My_ISR(void); // Function prototype for our ISR
    void main(void){

    unsigned char direction=0; // 0 = right to left, 1 = left to right
    unsigned char player1 =0;
    unsigned char player2 =0;
    unsigned char i;

    // Set up ports and bits as required
    TRISBbits.RB2 = 1; // PORTB, RB2 as input
    TRISBbits.RB0 = 1; // PORTB, RB0 as input
    TRISD = 0; // PORTD as output
    PORTD = 0;

    INTCONbits.INT0IF = 0; // Clear RB0 interrupt flag
    INTCONbits.INT0IE = 1; // Enable RB0 as interrupt source
    INTCON2bits.INTEDG0 = 0; // Make RB0 negative edge – remember button press high to low
    INTCONbits.GIE = 1; // Enable all interrupts globally

    INTCON3bits.INT2IF = 0; // Clear RB2 interrupt flag
    INTCON3bits.INT2IE = 1; // Enable RB2 as interrupt source
    INTCON2bits.INTEDG2 = 0; // Make RB2 negative edge – remember button press high to low
    INTCONbits.GIE = 1; // Enable all interrupts globally

    while(1){

    if(PORTD == 0b00000001){
    direction = 0; //right to left
    player2 = 0; //player 2 hasnt won just yet
    }

    if(PORTD == 0b10000000){
    direction = 1; //left to right
    player1 = 0; //player 1 hasnt won just yet
    }
    //wait on start of game
    if(PORTD > 0){

    //if no one has won, delay before moving
    if(player1 == 0 && player2 == 0){

    for(i = 0; i < 4; i++){
    Delay10KTCYx(50);
    }
    }
    }
    //MOVEMENT
    //if moves right to left
    if(direction == 0){

    if(PORTD != 0b10000000){
    PORTD = PORTD << 1; //move right to left
    }
    else{

    player1 =1; //ball has flown off, player 1 wins
    }
    }
    //if moves left to right
    if(direction == 1){

    if(PORTD != 0b00000001){
    PORTD = PORTD >> 1; //move left to right
    }
    else{

    player2 =1; //ball has flown off, player 2 wins
    }
    }
    //check to see if a player has won
    if(player1 == 1){

    PORTD = 0;

    //flash LED1 to signify win for player 1
    for(i = 0; i < 10; i++){
    LED1 ^= 1;
    Delay10KTCYx(250);
    }
    //clear the result
    PORTD = 0;
    player1 = 0;

    }

    if(player2 ==1){

    PORTD = 0;

    //flash LED8 to signify win for player 2
    for(i = 0;i < 10; i++){
    LED8 ^= 1;
    Delay10KTCYx(250);
    }
    //clear the result
    PORTD = 0;
    player2 = 0;
    }
    }
    }

    #pragma code My_HighPriority_Interrupt=0x08
    void My_HighPriority_Interrupt(void){

    _asm
    GOTO My_ISR
    _endasm
    }
    #pragma interrupt My_ISR
    void My_ISR(void){

    volatile unsigned char player1=0;

    volatile unsigned char player2=0;
    volatile unsigned char direction=0;

    if(INTCON3bits.INT2IF == 1){
    // If Button0 has caused interrupt
    INTCON3bits.INT2IF = 0; // Clear RB0 interrupt flag
    // Turn off LED
    player2 = 1; //player 2 wins if none of the conditions before are met
    if(PORTD == 0){
    PORTD = 0b00000001;
    direction = 0; //right to left
    player2 = 0; //player 2 hasnt won just yet

    }
    }
    if(INTCONbits.INT0IF == 1){
    // If Button0 has caused interrupt
    INTCONbits.INT0IF = 0; // Clear RB0 interrupt flag

    player1 = 1; //player 1 wins if none of the conditions before are met
    if(PORTD == 0){
    PORTD = 0b10000000;
    direction = 1; //left to right
    player1 = 0; //player 1 hasnt won just yet

    }
    }
    }

  • #3029

    Viga uk
    Participant

    Here is what I attempted to do but the program when I press the button LED moves from one end to the other back and forth and does not respond to buttons anymore.

  • #3030

    Bitahwa Bindu
    Keymaster

    How are your buttons and LEDs connected? To which PORT? with pull-up resistors? How?

  • #3031

    Viga uk
    Participant
    1. Two interrupt sources RB2(portb) connected by a wire to button RA5 and RB0 which is button RB0(portb).Leds are on portd(8 of them)
  • #3032

    Bitahwa Bindu
    Keymaster

    How are they connected that was the question? Can you post a screenshot or the circuit?

  • #3033

    Viga uk
    Participant

    I have attached the picture

    Attachments:
    You must be logged in to view attached files.
  • #3035

    Bitahwa Bindu
    Keymaster

    In your code you didn’t enable internal pull-up resistors and you are not using external pull-up resistors, how are you going to read the status of the buttons to generate interrupts? You are just connecting them to ground!!! What will drive them high?

    You said you are using 2 interrupts, INTO and INT2. INTO is on PORTB0 where you connected one button but INT2 is on PORTB2 and nothing is connected to it, why did you connect your other button to PORTA.5 ? Not all pins have interrupts features, you must only connect your buttons to those pins with interrupts.

    What is the purpose of this code: GOTO My_ISR?

    You don’t jump to an ISR from your code, and you don’t define an interrupt like that.

    This clearly shows that you don’t understand how interrupts work and you said you have already watched the Interrupt video, it shows either you ignored it you didn’t watch it or you did not understand anything in it.

    Please learn first how interrupts and how to connect push buttons to PIC before you continue with your project. You can’y jump steps.

  • #3036

    Viga uk
    Participant

    On the Pic18f8722 which  uses the pin for Rb2 is also the pin for INTO2.the two buttons on the board are rb0 and ra5 so i  used rb2 and connected it two ra5 with a wire.so the two buttons now work as interrupt source.Ra5 has no interrupt feature,on this board only rb0 ,rb1 and rb2 can be  used for interrupt .</p>
    In the isr  the go to my isr is assembly language used on this board to jump to isr once either of the buttons are pressed.

     

    If(intconbits.INTOIF==1)  ONCE interrupt occurs flag is 1 and the flag is immediately cleared.by INTCONbits.INTOIF=0

     

    • This reply was modified 5 months, 1 week ago by  Viga uk.
    • This reply was modified 5 months, 1 week ago by  Viga uk.
  • #3039

    Bitahwa Bindu
    Keymaster

    If you think that’s how you can call an interrupt routine, then go ahead we can’t comment or assist on that. We don’t program in assembly. There is no language specific for a board, the language is used to program the Microcontroller.

You must be logged in to reply to this topic.