Conflicts with interrupts

General discussion on mikroC.
Post Reply
Author
Message
lukes
Posts: 5
Joined: 24 Dec 2011 16:20

Conflicts with interrupts

#1 Post by lukes » 19 Mar 2012 21:50

Hello,

I'm trying to command two servomotors using the compare module. (Pic 16f877)

1) I start counting the Timer1 at a minimum value.
2) Then I turn the pins (RB3 and RB4 but it doesn't matter) to 1.
3) I configure the CCP1L and CCP1H with a value bigger than the minimum value of the Tmr1 (to get 1 ms)
4) An interrupt occured and I turn off the pins RB3 and Rb4
4) The tmr1 continues counting until the overflow wich also creates an interrutp and re-turns on the pins
And so on..

With a single one servo, it work great. But When I connect the two servomotors, ther is a little conflict when the value of the two CCP1H/L and CCP2H/L are closed.
I think the fact that interrupts are generated during a very small time generates conflicts.

Am I right ?

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Conflicts with interrupts

#2 Post by janko.kaljevic » 20 Mar 2012 13:17

Hello,

Please can you explain this issue in more details.
I am afraid that I have not understood you well.

Best regard.

lukes
Posts: 5
Joined: 24 Dec 2011 16:20

Re: Conflicts with interrupts

#3 Post by lukes » 26 Mar 2012 18:34

I'm going to rephrase it,

I'm using the SPI protocol with the ENC28J60. At the same time I want to control two servomotors using the two CCP module (compare).
It works but I find some bugs (the servos change their position sometime without asking anything..).
Then I found out that the pin RC1 (CCP2) is also used by the SPI function (I configured it on PORTC as it was in the example), so maybe it's because of that despite that the outputs used to control the servos are on the PORTB..

I tried to change the PORTC in PORTD in the function SPI_INIT, but it didn't work at all..

Here is my code :

Code: Select all

/*
 * Project Name:
     httpserver_example (Ethernet Library http server demo for ENC28J60 mcu)
 * Target Platform:
     PIC
 * Copyright:
     (c) mikroElektronika, 2006.
 *
 * description  :
 *      this code shows how to use the ENC28J60 mini library :
 *              the board will reply to ARP & ICMP echo requests
 *              the board will reply to HTTP requests on port 80, GET method with pathnames :
 *                      /               will return the HTML main page
 *                      /s              will return board status as text string
 *                      /t0 ... /t7     will toggle RC0 to RC7 bit and return HTML main page
 *                      all other requests return also HTML main page
 *
 * target devices :
 *      any PIC with integrated SPI and more than 4 Kb ROM memory
 *      32 to 40 MHz clock is recommended to get from 8 to 10 Mhz SPI clock,
 *      otherwise PIC should be clocked by ENC clock output due to ENC silicon bug in SPI hardware
 *      if you try lower PIC clock speed, don't be surprised if the board hang or miss some requests !
 *      tested with PIC16F877A@10Mhz on EasyPIC4 board
 *
 * EP settings :
 *      RA2 & RA3 pots jumper : closed
 *      PORTB : pull-down
 *      PORTC : pull-down
 *      BUTTONS : pull-up
 *
 *      RC0 : !RESET    to ENC reset input pin
 *      RC1 : !CS       to ENC chip select input pin
 *      the ENC28J60 SPI bus CLK, SO, SI must be connected to the corresponding SPI pins of the PIC
 *      the INT and WOL signals from the ENC are not used
 *
 * Test configuration:
     MCU:             PIC16F877A
     Dev.Board:       EasyPIC4
     Oscillator:      HS, 10.000MHz
     Ext. Modules:    mE Serial Ethernet board
     SW:              mikroC v6.2.0.0.
 * NOTES:
     None.
 */

#define SPI_Ethernet_HALFDUPLEX     0
#define SPI_Ethernet_FULLDUPLEX     1

/************************************************************
 * ROM constant strings
 */
const unsigned char httpHeader[] = "HTTP/1.1 200 OK\nContent-type: " ;  // HTTP header
const unsigned char httpMimeTypeHTML[] = "text/html\n\n" ;              // HTML MIME type
const unsigned char httpMimeTypeScript[] = "text/plain\n\n" ;           // TEXT MIME type
unsigned char httpMethod[] = "GET /";
                                                                        // supported http method
                                                                        
int compteur = 0;

int impulsionServoV = 56254; //position neutre du servomoteur vertical = 1,4ms
int impulsionServoH = 56233; //position neutre du servomoteur horizontal= 1,4ms
                             //butées gauche = 1ms = 56 035 - butée droite = 2ms = 56 535
/*
 * web page, splited into 2 parts :
 * when coming short of ROM, fragmented data is handled more efficiently by linker
 *
 * this HTML page calls the boards to get its status, and builds itself with javascript
 */
const   char    *indexPage = "<HTML><HEAD></HEAD><BODY>\
<h1 id=\"fileContent\">PIC + ENC28J60 Mini Web Server !!</h1>\
<a href=/>Reload</a>\
<script src=/s></script>\
<p id=\"keyCode\"></p>\
<table><tr><td valign=top><table border=1 style=\"font-size:20px ;font-family: terminal ;\">\
<tr><th colspan=2>ADC</th></tr>\
<tr><td>AN2</td><td><script>document.write(AN2)</script></td></tr>\
<tr><td>AN3</td><td><script>document.write(AN3)</script></td></tr>\
</table></td><td><table border=1 style=\"font-size:20px ;font-family: terminal ;\">\
<tr><th colspan=2>PORTB</th></tr>\
<script>\
var str,i;\
str=\"\";\
for(i=0;i<8;i++)\
{str+=\"<tr><td bgcolor=pink>BUTTON #\"+i+\"</td>\";\
if(PORTB&(1<<i)){str+=\"<td bgcolor=red>ON\";}\
else {str+=\"<td bgcolor=#cccccc>OFF\";}\
str+=\"</td></tr>\";}\
document.write(str) ;\
</script>\
" ;

const   char    *indexPage2 =  "</table></td><td>\
<table border=1 style=\"font-size:20px ;font-family: terminal ;\">\
<tr><th colspan=3>PORTD</th></tr>\
<script>\
var str,i;\
str=\"\";\
for(i=0;i<8;i++)\
{str+=\"<tr><td bgcolor=yellow>LED #\"+i+\"</td>\";\
if(PORTD&(1<<i)){str+=\"<td bgcolor=red>ON\";}\
else {str+=\"<td bgcolor=#cccccc>OFF\";}\
str+=\"</td><td><a href=/t\"+i+\">Toggle</a></td></tr>\";}\
document.write(str) ;\
</script>\
</table></td></tr></table>\
This is HTTP request #<script>document.write(REQ)</script></BODY></HTML>\
" ;

/***********************************
 * RAM variables
 */
unsigned char   myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f} ;   // MAC address
unsigned char   myIpAddr[4] = {172, 17, 123, 50} ;                      // IP address
unsigned char   getRequest[15] ;                                        // HTTP request buffer
unsigned char   dyna[31] ;                                              // buffer for dynamic response
unsigned long   httpCounter = 0 ;                                       // counter of HTTP requests

/*******************************************
 * functions
 */

/*
 * put the constant string pointed to by s to the ENC transmit buffer
 */
unsigned int    putConstString(const char *s)
        {
        unsigned int ctr = 0 ;

        while(*s)
                {
                SPI_Ethernet_putByte(*s++) ;
                ctr++ ;
                }
        return(ctr) ;
        }

/*
 * put the string pointed to by s to the ENC transmit buffer
 */
unsigned int    putString(char *s)
        {
        unsigned int ctr = 0 ;

        while(*s)
                {
                SPI_Ethernet_putByte(*s++) ;
                ctr++ ;
                }
        return(ctr) ;
        }

        void interrupt ()
        {
             if (PIR1.CCP1IF == 1)
             {
                PORTB.F1 = 0;
                
                PIR1.CCP1IF = 0;
             }
             if (PIR2.CCP2IF == 1)
             {
                PORTB.F0 = 0;

                PIR2.CCP2IF = 0;
             }
             if (PIR1.TMR1IF == 1)
             {
                PORTB.F1 = 1;
                PORTB.F0 = 1;
                
                PIR1.TMR1IF = 0;
                
                TMR1L = 0xEF;
                TMR1H = 0xD8;
                      /* initialisation du TMR1 à 55 535 */
             }

        }



/*
 * this function is called by the library
 * the user accesses to the HTTP request by successive calls to SPI_Ethernet_getByte()
 * the user puts data in the transmit buffer by successive calls to SPI_Ethernet_putByte()
 * the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit
 *
 * if you don't need to reply to HTTP requests,
 * just define this function with a return(0) as single statement
 *
 */
 unsigned int    SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength)
        {
        unsigned int    len = 0 ;                               // my reply length
        unsigned int    i ;                                     // general purpose integer

        if(localPort != 80)                                     // I listen only to web request on port 80
                {
                return(0) ;
                }

        // get 10 first bytes only of the request, the rest does not matter here
        for(i = 0 ; i < 10 ; i++)
                {
                getRequest[i] = SPI_Ethernet_getByte() ;
                }
        getRequest[i] = 0 ;

        if(memcmp(getRequest, httpMethod, 5))                   // only GET method is supported here
                {
                return(0) ;
                }

        httpCounter++ ;                                         // one more request done

                
        if(getRequest[5] == 'h')                           // if request path is incrdibly equal to 9
        {

                        if(impulsionServoV < 56405) //butée haute
                        {

                                impulsionServoV++;
                                //impulsionServoV = impulsionServoV+7;
                                CCPR1L = impulsionServoV;
                                CCPR1H = impulsionServoV>>8; // on place les 8 derniers bits dans le registre HIGHT du CCPR1
                        }



        }
        if(getRequest[5] == 'b')                           // if request path is incrdibly equal to 9
        {

                        if(impulsionServoV > 56085) //butée basse
                        {

                                impulsionServoV--;
                                //impulsionServoV = impulsionServoV-7;
                                CCPR1L = impulsionServoV;
                                CCPR1H = impulsionServoV>>8; // on place les 8 derniers bits dans le registre HIGHT du CCPR1


                 }


        }
        if(getRequest[5] == 'g')                           // if request path is incrdibly equal to 9
        {

                        if(impulsionServoH > 56085)
                        {

                                impulsionServoH++;
                                //impulsionServoH = impulsionServoH+7;
                                CCPR2L = impulsionServoH;
                                CCPR2H = impulsionServoH>>8; // on place les 8 derniers bits dans le registre HIGHT du CCPR1


                }


        }
        if(getRequest[5] == 'd')                           // if request path is incrdibly equal to 9
        {

                        if(impulsionServoH < 56485)
                        {

                                impulsionServoH--;
                                //impulsionServoH = impulsionServoH-7;
                                CCPR2L = impulsionServoH;
                                CCPR2H = impulsionServoH>>8; // on place les 8 derniers bits dans le registre HIGHT du CCPR1


                }
        }
        if(getRequest[5] == 'n')                           // if request path is incrdibly equal to 9
        {

                      impulsionServoH = 56233;
                      impulsionServoV = 56254;
                      CCPR2L = impulsionServoH;
                      CCPR2H = impulsionServoH>>8; // on place les 8 derniers bits dans le registre HIGHT du CCPR1
                      CCPR1L = impulsionServoV;
                      CCPR1H = impulsionServoV>>8;



        }

        if(len == 0)                                            // what do to by default
                {
                len =  putConstString(httpHeader) ;             // HTTP header
                len += putConstString(httpMimeTypeHTML) ;       // with HTML MIME type
                len += putConstString(indexPage) ;              // HTML page first part
                len += putConstString(indexPage2) ;             // HTML page second part
                }

        return(len) ;                                           // return to the library with the number of bytes to transmit
        }

/*
 * this function is called by the library
 * the user accesses to the UDP request by successive calls to SPI_Ethernet_getByte()
 * the user puts data in the transmit buffer by successive calls to SPI_Ethernet_putByte()
 * the function must return the length in bytes of the UDP reply, or 0 if nothing to transmit
 *
 * if you don't need to reply to UDP requests,
 * just define this function with a return(0) as single statement
 *
 */
unsigned int    SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength)
        {
        return 0 ;                      // back to the library with the length of the UDP reply
        }

/*
 * main entry
 */
void    main()
        {
        CCP1CON = 0b00001010;
                /* mode compare, bits 7 à 4 non utilisés,
                bits 3 à 0 = génération d'une interruption et flag CCP1IF = 1 à l'égalité */
        CCP2CON = 0b00001010;
                        // set PORTA as input for ADC
        TRISB = 0b00000000;

                         // set PORTB as input for buttons

        INTCON = 0b11000000;
               /* GIE = 1 : autoriser toutes les interruptions
                  PEIE = 1 : autoriser les interruptions causées par les périphériques
                  bits 5 à 0 non utilisés */
        T1CON = 0b00100001;
              /* bits 7-6 non implémentés
                 bit 5-4 = 10 : prédiviseur de 4
                 bits 3-1 = 000 : utilisation d'un quartz externe et mode timer activé
                 bit 0 = 1 : timer1 activé */

        PIE1 = 0b00000101;
             /* bits 7-3 et 1 à 0 : non utilisés
                bit 2 (CCP1IE)= 1 : autorisation des interruptions de CCP1
                bit 0 = 1 : autorise iterruption débordement TMR1 */
        PIE2 = 0b00000001;
        /* bits 7-1: non utilisés
                bit 0 (CCP2IE)= 1 : autorisation des interruptions de CCP2*/

       TMR1L = 0xEF;
       TMR1H = 0xD8;
              /* initialisation du TMR1 à 55 535 */

                   //Timer1 en service


PIR1.TMR1IF = 0;    // clear TMR1IF






        PORTB.F1 = 0;
        PORTB.F0 = 0;
        PORTB.F2 = 1;
        
         CCPR1L = impulsionServoV;
         CCPR1H = impulsionServoV>>8;
         CCPR2L = impulsionServoH;
         CCPR2H = impulsionServoH>>8;
        


        //PORTE = 0;
        //TRISE = 0;                    // set PORTD as output

        /*
         * initialize ethernet board
         * start ENC28J60 with :
         * reset bit on RC0
         * CS bit on RC1
         * my MAC & IP address
         * full duplex
         */
       Spi_Init();
        SPI_Ethernet_Init(&PORTD, 0, &PORTD, 1, myMacAddr, myIpAddr, SPI_Ethernet_FULLDUPLEX) ;

        while(1)                            // endless loop
                {
                SPI_Ethernet_doPacket() ;   // process incoming Ethernet packets




                /*
                 * add your stuff here if needed
                 * SPI_Ethernet_doPacket() must be called as often as possible
                 * otherwise packets could be lost
                 */
                }
        }

Thank you in advance

Post Reply

Return to “mikroC General”