/************************************************************************ RB0ReleasedWait Waits until the RB0/INT0 pin is no longer being pulled down. Uses Timer0 to filter out switch bounce. Parameters: None Return: None Side Effects: Timer0 will be used and left disabled by this routine. ************************************************************************/ void RB0ReleasedWait(void) { OpenTimer0(TIMER_INT_OFF & T0_8BIT & T0_SOURCE_INT & T0_PS_1_8); while (INTCONbits.T0IF == 0) { // wait for user to release RB0/INT0 if (PORTBbits.RB0 == 0) { TMR0L = 0; // reset timer if button is bouncing. } } CloseTimer0(); }
void pausa (unsigned int segundos) { if (segundos <= 0) return; OpenTimer0( TIMER_INT_OFF & T0_16BIT & T0_PS_1_32 & T0_SOURCE_INT & T0_EDGE_FALL ); //Enable TIMER Interrupt (Int_On) /* Calculo do Timer0 * * (1 seg * 8000000) / (4 * 32) ... 32 = 1/32 prescaler * 8.000.000 / 128 = 62500 * * Timer0 = 65536 - 62500 = 3035 ou 0xBDB */ WriteTimer0( 0xBDC ); LED_AMAR=1; LED_VERM=0; T0CONbits.TMR0ON = 1; // Ligue o Timer 0 //T0CONbits.PSA = 0; // Use valores atraves do Pre-Scaler //T0CONbits.T0CS=0; // A fonte clock eh Interna (CLKO/FOSC) T0_SOURCE_INT // Sem Interrupcoes INTCONbits.GIE = 0; // Interrupcoes Globais desligadas INTCONbits.PEIE = 0; // Interrupcoes dos Perifericos desligadas INTCONbits.TMR0IE = 0; // Interrupcoes do Timer0 desligadas INTCONbits.TMR0IF = 0; // Zera o contador do Timer0 while (segundos > 0) { while (!TMR0IF) ; // enquando o Timer0 nao tiver overflow, espere LED_AMAR=~LED_AMAR; // Led Amarelo pisca a cada segundo //segundos--; //WriteTimer0( 0xBDC ); INTCONbits.TMR0IF=0; // Zera o contador do Timer0 segundos--; } CloseTimer0(); // Feche o Timer0 //TMR0ON=0; LED_AMAR=0; LED_VERM=0; LED_VERD=0; }
int main(void) { //-------------- // Initialization char LCDinit[] = {0x33,0x32,0x28,0x01,0x0c,0x06,0x00}; //Array holding initialization string for LCD char Msg1[] = {0x84,'C','U','N','T','\0'}; char Msg2[] = {0xC5,'R','P','S','\0'}; char Msg3[10]; // Msg for displaying RPS to LCD (size 10 in case dealing with large numbers) InitApp(); // Initialize Ports DisplayLCD(LCDinit,1); // Initialize LCD //-------------- // Message on LCD DisplayLCD(Msg1,0); // Display message on LCD DisplayLCD(Msg2,0); // Display message 2 //-------------- // Initialize encoder variables CHA = PORTBbits.RB5; // Initialize channel A CHB = PORTBbits.RB4; // Initialize channel B OLD_ROT = 0; // Initialize state of rotation CCWTurn = 0; // Initialize CCW count CWTurn = 0; // Initialize CW count RPS = 0.0; // Initialize RPS value CHAcount = 0; // Channel A counter //-------------- // Setup PWM cycle to motor PR2 = 0x9B; // Open pwm1 at period = 1 ms CCP1CONbits.DC1B1 = 0; // Set duty cycle of pwm1 CCP1CONbits.DC1B0 = 0; // ... CCPR1L = 0b00000100; // ... //------------- // Set timer and interrupts TMR0count = 0; // Set counter for TMR0 WriteTimer0(EncoderCount);// Load Timer0 InitInterrupts(); // Initialize timer interrupts for Port B encoder //-------------- // Loop phase: Display RPS on LCD while(1) { WaitHalfSec(); WriteLCD(0xC0,5,RPS,Msg3); // Display RPS on LCD } //-------------- // Exit main CloseTimer0(); return (EXIT_SUCCESS); }
/************************************************************************ wait Waits for a period time. Used to avoid sending data out of the UART before the internal oscillator has stablized on start up. Parameters: None Return: None Side Effects: Timer 0 will be used and turned off. OSCCON.IDLEN will be set to 1. ************************************************************************/ void wait(void) { unsigned int i; OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); // Enter IDLE mode. Idle mode is used here so that the Timer 0 // can continue operating while the processor is powered down. OSCCONbits.IDLEN = 1; Sleep(); CloseTimer0(); }
void mPaP_int(){ if(INTCONbits.TMR0IF){ // Réinitialisation de l'interruption INTCONbits.TMR0IF = 0; // On avance d'un pas Pas(); // On ajuste nos positions pas_restant--; if(CW ==1){ pos_actuelle++; }else{ pos_actuelle--; } if(!HALF){ // Si on marche par pas complet, on passe un deuxieme demi-pas pas_restant--; if(CW ==1){ pos_actuelle++; }else{ pos_actuelle--; } } // Modulo 1 tour (on reste entre -400 et 400). if(pos_actuelle < (int)-400){ pos_actuelle += (int)800; }else if(pos_actuelle > (int)400){ pos_actuelle -= (int)800; } // On planifie le pas suivant if(pas_restant > 0){ WriteTimer0(0xFFFF - T_PAS); }else{ CloseTimer0(); depl_en_cours=0; } } }
void main(void) { TRISA = 0x0; TRISB = 0x0; TRISC = 0x0; PORTA = 0x0; PORTB = 0x0; PORTC = 0x0; LATA = 0x0; LATB = 0x0; LATC = 0x0; signed char length; unsigned char msgtype; uart_comm uc; i2c_comm ic; unsigned char msgbuffer[MSGLEN + 1]; uart_thread_struct uthread_data; // info for uart_lthread timer0_thread_struct t0thread_data; timer1_thread_struct t1thread_data; // info for timer1_lthread encoder_struct encoder_data; sensor_data sensors; #ifdef __USE18F2680 OSCCON = 0xFC; // see datasheet // We have enough room below the Max Freq to enable the PLL for this chip OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line #else OSCCON = 0x82; // see datasheeet OSCTUNEbits.PLLEN = 0; // Makes the clock exceed the PIC's rated speed if the PLL is on #endif #ifdef SENSORPIC i2c2_comm ic2; init_i2c2(&ic2); #endif // initialize everything init_uart_comm(&uc); init_i2c(&ic); init_encoder(&encoder_data); init_timer0_lthread(&t0thread_data); init_timer1_lthread(&t1thread_data); init_uart_lthread(&uthread_data); init_queues(); #ifdef MASTERPIC // Enable and set I2C interrupt to high i2c_configure_master(); IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; // initialize Timer0 to go off approximately every 10 ms //OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1); CloseTimer0(); INTCONbits.TMR0IE = 0; //Enable Timer0 Interrupt // Configure UART OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 9); // 19.2kHz (197910/t - 1 = target) IPR1bits.RCIP = 0; IPR1bits.TXIP = 0; uc.expected = 1; PORTB = 0x0; LATB = 0x0; TRISB = 0x0; #endif //MASTERPIC #ifdef SENSORPIC // Enable and set I2C interrupt to high i2c_configure_slave(SENSORPICADDR); IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; i2c2_configure_master(); IPR3bits.SSP2IP = 1; PIE3bits.SSP2IE = 1; // Open ADC on channel 1 ADCON0= 0x01; ADCON1=0x30; ADCON2=0xa1; TRISA=0x0F; PIE1bits.ADIE = 1; //Enabling ADC interrupts IPR1bits.ADIP = 0; //Setting A/D priority // initialize Timer0 to go off approximately every 10 ms OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_128); INTCONbits.TMR0IE = 1; //Enable Timer0 Interrupt INTCON2bits.TMR0IP = 0; //TMR0 set to Low Priority Interrupt #endif //SENSORPIC #ifdef MOTORPIC i2c_configure_slave(MOTORPICADDR); // Enable and set I2C interrupt to high IPR1bits.SSPIP = 1; PIE1bits.SSPIE = 1; // Configure UART OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 0x9); IPR1bits.RCIP = 0; IPR1bits.TXIP = 0; INTCONbits.TMR0IE = 0; // Disable Timer0 Interrupt PORTB = 0x0; LATB = 0x0; TRISB = 0x0; // Set up RB5 as interrupt TRISBbits.RB5 = 1; INTCON2bits.RBIP = 0; #endif //MOTORPIC #ifdef MASTERPIC //init_communication(MOTORPICADDR); //init_communication(SENSORPICADDR); #endif // Peripheral interrupts can have their priority set to high or low // enable high-priority interrupts and low-priority interrupts enable_interrupts(); while (1) { // Spins until a message appears block_on_To_msgqueues(); // Continuously check high priority messages until it is empty while((length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) { switch (msgtype) { case MSGT_I2C_RQST: { #ifdef SENSORPIC char command = msgbuffer[0]; char length = 0; char buffer[8]; switch(command) { case SHORT_IR1_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x11; } break; case SHORT_IR2_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x22; } break; case MID_IR1_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x33; } break; case MID_IR2_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x44; } break; case COMPASS_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x55; } break; case ULTRASONIC_REQ: { length = 2; buffer[0] = command; buffer[1] = 0x66; } break; default: { length = 2; buffer[0] = 0x0; buffer[1] = 0x0; } break; } if(length > 0) { start_i2c_slave_reply(length,buffer); } #endif #ifdef MOTORPIC unsigned char buffer[8]; unsigned char length = 0; char command = msgbuffer[0]; buffer[0] = command; switch(command) { case MOVE_FORWARD_CMD: { length = 1; motor_move_forward(10); INTCONbits.RBIE = 1; // Temporary } break; case MOVE_BACKWARD_CMD: { length = 1; motor_move_backward(10); } break; case TURN_RIGHT_CMD: { length = 1; motor_turn_right(10); } break; case TURN_LEFT_CMD: { length = 1; motor_turn_left(10); } break; case STOP_CMD: { length = 1; motor_stop(); } break; case DISTANCE_REQ: { INTCONbits.RBIE = 0; // Temporary buffer[1] = encoder_to_distance(); length = 2; } break; default: { buffer[0] = 0x0; length = 1; } break; } if(length > 0) { start_i2c_slave_reply(length,buffer); } #endif } break; case MSGT_I2C_DATA: { } break; case MSGT_I2C_MASTER_SEND_COMPLETE: { #ifdef MASTERPIC /* char command = msgbuffer[0]; switch(command) { case MOVE_FORWARD_CMD: case MOVE_BACKWARD_CMD: case TURN_RIGHT_CMD: case TURN_LEFT_CMD: case STOP_CMD: { i2c_master_recv(1,MOTORPICADDR); } break; case DISTANCE_REQ: { i2c_master_recv(2,MOTORPICADDR); } break; case SHORT_IR1_REQ: case SHORT_IR2_REQ: case MID_IR1_REQ: case MID_IR2_REQ: case COMPASS_REQ: case ULTRASONIC_REQ: { i2c_master_recv(2,SENSORPICADDR); } break; default: { } break; }*/ #endif #ifdef SENSORPIC // Start receiving data from sensor if(t0thread_data.currentState == readCompassState) { i2c2_master_recv(6,COMPASSADDR); } else if(t0thread_data.currentState == readUltrasonicState) { i2c2_master_recv(2,ULTRASONICADDR); } #endif } break; case MSGT_I2C_MASTER_SEND_FAILED: { } break; case MSGT_I2C_MASTER_RECV_COMPLETE: { #ifdef MASTERPIC char buffer[2]; char length = 0; char command = msgbuffer[0]; switch(command) { case MOVE_FORWARD_CMD: case MOVE_BACKWARD_CMD: case TURN_RIGHT_CMD: case TURN_LEFT_CMD: case STOP_CMD: { buffer[0] = command; length = 1; } break; case DISTANCE_REQ: { buffer[0] = command; buffer[1] = msgbuffer[1]; length = 2; } break; case SHORT_IR1_REQ: case SHORT_IR2_REQ: case MID_IR1_REQ: case MID_IR2_REQ: case COMPASS_REQ: case ULTRASONIC_REQ: { buffer[0] = command; buffer[1] = msgbuffer[1]; length = 2; } break; default: { length = 0; } break; } if(length > 0) { start_uart_send(length,buffer); } #endif #ifdef SENSORPIC // Received data from sensor if(t0thread_data.currentState == readCompassState) { sensors.compassData[0] = msgbuffer[0]; sensors.compassData[1] = msgbuffer[1]; sensors.compassData[2] = msgbuffer[2]; sensors.compassData[3] = msgbuffer[3]; sensors.compassData[4] = msgbuffer[4]; sensors.compassData[5] = msgbuffer[5]; } else if(t0thread_data.currentState == readUltrasonicState) { } #endif } break; case MSGT_I2C_MASTER_RECV_FAILED: { } break; case MSGT_I2C_DBG: { } break; default: { } break; } } // Error check if (length != MSGQUEUE_EMPTY) { // Handle Error } // Check the low priority queue if ((length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer)) >= 0) { switch (msgtype) { case MSGT_TIMER0: { timer0_lthread(&t0thread_data, msgtype, length, msgbuffer); } break; case MSGT_TIMER1: timer1_lthread(&t1thread_data, msgtype, length, msgbuffer); break; case ADCSC1_ADCH: ADC_lthread(&ADCthread_data, msgtype, length, msgbuffer,&t0thread_data); break; case MSGT_OVERRUN: case MSGT_UART_DATA: { uart_lthread(&uthread_data, msgtype, length, msgbuffer); } break; case MSGT_UART_SEND_COMPLETE: { } break; default: break; } } // Error check else if (length != MSGQUEUE_EMPTY) { // Handle error } } }
void main(void) { unsigned char i,j; /* Output configurations */ ADCON1 |= 0x0F; // All possible analog input pins config as digital I/O CMCON = 0x07; // Comparators disabled /* Natural interaction expansion port configuration */ TRISAbits.TRISA4 = 1; // A4 Botton 3 TRISAbits.TRISA3 = 1; // A3 Botton 2 TRISAbits.TRISA2 = 1; // A2 Botton 1 TRISAbits.TRISA1 = 1; // A1 Potentiometer 2 TRISAbits.TRISA0 = 1; // A0 Potentiometer 1 TRISB = 0; // B0..B6 Serial input for the Shift Registers TRISD = 0; // D0..D3 Shift Registers control inputs: SCK, RCK, _SCL, _G TRISEbits.TRISE0 = 1; //Input button PORTEbits.RE0 LATA = 0; // Disable expansion port _SCL = 1; // Disable Shift Register _SCL (Global Clear) _G = 0; // Enables Shift Regusters outputs _G // Resetting variables for (i = 0; i <= MAX_INDEX_G_BUFFER_GREYSCALE; i++) { gBufferGreyscale[i] = 0; gPreBufferGreyscale[i] = 0; } for (i = 0; i <= MAX_INDEX_M_BUFFER_MATRIX; i++) { mBufferMatrix[i] = RESET_M_BUFFER_MATRIX; } iGreyscale = 0; iTimer1 = 0; iMenu = 0; FIRST = 0; SECOND = 0; THIRD = 0; FOURTH = 0; FIFTH = 0; SIXTH = 0; pwm = 0; /* Timer 0 Configuration */ // Used to trigger the refresh matrix printed data routine OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_1); WriteTimer0(0); /* Timer 1 Configuration */ // Used to periodically check the input data (external buttons) OpenTimer1(TIMER_INT_ON & T1_SOURCE_INT & T1_PS_1_8 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF); WriteTimer1( 0x00 & 0x00 ); /* Timer 3 Configuration */ // Used to create delays within the different menus without blocking with delays OpenTimer3( TIMER_INT_ON & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_SYNC_EXT_OFF); WriteTimer3( 0x00 & 0x00 ); /* A/D configuration */ //ADCON1 ADCON1bits.VCFG1 = 0; // Voltage Reference Configuration bit (Vref-) = Vss ADCON1bits.VCFG0 = 0; // Voltage Reference Configuration bit (Vref+) = Vdd ADCON1bits.PCFG3 = 1; // PCFG = "1110" enables AN0 and AN1 ADCON1bits.PCFG2 = 1; ADCON1bits.PCFG1 = 1; ADCON1bits.PCFG0 = 0; //ADCON0 ADCON0bits.ADON = 1; // A/D converter module is enabled ADCON0bits.CHS0 = 0; // CHS = "0000" AN0 selected ADCON0bits.CHS1 = 0; ADCON0bits.CHS2 = 0; ADCON0bits.CHS3 = 0; //ADCON2 ADCON2bits.ADCS0 = 0; // A/D Adquisition Clock Select bits ADCON2bits.ADCS1 = 1; // Tad = conversion time per bit. The A/D conversion requires 11 Tad ADCON2bits.ADCS2 = 0; // "010" = 32 * Tosc ADCON2bits.ACQT0 = 0; // A/D Adquisition time bits "000" = Manual adquisition ADCON2bits.ACQT1 = 0; ADCON2bits.ACQT2 = 0; ADCON2bits.ADFM = 0; // Left justified . . .ADRESH . . : . . ADRESL. . . // 7 6 5 4 3 2 1 0 : 7 6 5 4 3 2 1 0 // X X X X X X X X . X X . . . . . . <-Left Justified /* Enabling interrups */ INTCONbits.TMR0IE = 1; // Enables interrupts for TIMER0 PIE1bits.TMR1IE = 1; // Enables interrupts for TIMER1 PIE2bits.TMR3IE = 1; // Enables interrupts for TIMER3 INTCONbits.PEIE = 1; // Peripherial interrupt enabled INTCONbits.GIE = 1; // Global interrupt enabled /* Main Loop */ while(1) { /* Main MENU includes the different modes that the table can show Switching between menus is done using external button(RE0): 0 - Fixed light dimmed with external control 1 - Slow square 2 - Slow chess board 3 - Message 4 - Invaders 5 - Party (Dirty) */ switch(iMenu) { /******************************************************************/ /* 0 - Fixed light dimmed with external control */ /******************************************************************/ case 0: if (FIRST == 0) { deleteMatrix(); (FIRST = 1); } drawLine(1,1,1,5,pwm); //dirty way to draw the all pixels at the same time drawLine(2,1,2,5,pwm); drawLine(3,1,3,5,pwm); drawLine(4,1,4,5,pwm); drawLine(5,1,5,5,pwm); break; /******************/ /* 1- Slow square */ /******************/ case 1: if (SECOND == 0) { deleteMatrix(); (SECOND = 1); } for(j = 130, i = 254; j<=254; j++, i--) { drawSquare(1,1,5,5,j); drawSquare(2,2,4,4,i); drawPoint(3,3,j); Delay10KTCYx(100); if(iMenu != 1) { break; } } if(iMenu != 1) { break; } for(j = 130, i = 254; j<=254; j++, i--) { drawSquare(1,1,5,5,i); drawSquare(2,2,4,4,j); drawPoint(3,3,i); Delay10KTCYx(100); if(iMenu != 1) { break; } } if(iMenu != 1) { break; // It allows to break the case during the executation } /***********************/ /* 2- Slow Chess board */ /***********************/ case 2: if (THIRD == 0) { deleteMatrix(); (THIRD = 1); } for(j = 130, i = 254; j<=254; j++, i--) { drawPoint(1,5,j); drawLine(1,3,3,5,j); drawLine(1,1,5,5,j); drawLine(3,1,5,3,j); drawPoint(5,1,j); drawLine(1,4,2,5,i); drawLine(1,2,4,5,i); drawLine(2,1,5,4,i); drawLine(4,1,5,2,i); Delay10KTCYx(100); if(iMenu != 2) { break; } } if(iMenu != 2) { break; } for(j = 130, i = 254; j<=254; j++, i--) { drawPoint(1,5,i); drawLine(1,3,3,5,i); drawLine(1,1,5,5,i); drawLine(3,1,5,3,i); drawPoint(5,1,i); drawLine(1,4,2,5,j); drawLine(1,2,4,5,j); drawLine(2,1,5,4,j); drawLine(4,1,5,2,j); Delay10KTCYx(100); if(iMenu != 2) { break; } } if(iMenu != 2) { break; // It allows to break the case during the executation } /**************/ /* 3- Message */ /**************/ case 3: if (FOURTH == 0) { deleteMatrix(); (FOURTH = 1); } //knightRider(4); scrollText((rom unsigned char *)&Nino[0], TRANS_RIGHT_2_LEFT); break; /***************/ /* 4- Invaders */ /***************/ case 4: if (FIFTH == 0) { deleteMatrix(); (FIFTH = 1); } for(i = 1; i <= INVADERS_PAIR_REPETITIONS; i++) { drawFrame((rom unsigned char *)&invaders[0]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } drawFrame((rom unsigned char *)&invaders[1]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } }// end for for(i = 1; i <= INVADERS_PAIR_REPETITIONS; i++) { drawFrame((rom unsigned char *)&invaders[2]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } drawFrame((rom unsigned char *)&invaders[3]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } }// end for for(i = 1; i <= INVADERS_PAIR_REPETITIONS; i++) { drawFrame((rom unsigned char *)&invaders[4]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } drawFrame((rom unsigned char *)&invaders[5]); Delay10KTCYx(DELAY_INVADERS); if(iMenu != 4) { break; } }// end for break; /********************/ /* 5- Party (Dirty) */ /********************/ case 5: if (SIXTH == 0) { deleteMatrix(); drawLine(1,5,5,5,254); } for(j = 100, i = 254; j<=254; j++, i--) { drawSquare(1,1,5,5,j); drawSquare(2,2,4,4,i); drawPoint(3,3,j); if(iMenu != 5) { break; } } if(iMenu != 5) { break; } for(j = 100, i = 254; j<=254; j++, i--) { drawSquare(1,1,5,5,i); drawSquare(2,2,4,4,j); drawPoint(3,3,i); if(iMenu != 5) { break; } } if(iMenu != 5) { break; // It allows to break the case during the executation } //SOLVES A BUG: because when TMR1F is called from this case, FIFTH is //reset but when we come back is set one because we are in case 4 not 1, if (iMenu == 5)(SIXTH = 1); break; default: drawPoint(3,3, 180); }// End switch iMenu }// End while CloseTimer0(); CloseTimer1(); }//end main