void main(void) { unsigned char data = 0; signed char err0 = 0, err1 = 0, err2 = 0; Delay100TCYx(10); //let the device startup //initialize uart usart_init(); spi_init(); printf("Var is %i\r\n", data); printf("Starting\r\n"); printf("SSPCON1 is x%x\r\n", SSPCON1); printf("SSPADD is x%x\r\n", SSPADD); printf("SSPSTAT is x%x\r\n", SSPSTAT); PORTCbits.RC2 = 1; // pin high while(1){ PORTCbits.RC2 = 0; // CS low Delay1TCY(); // delay at least 5 ns WriteSPI(0x80); // b'10000000, read single byte 000000 //WriteSPI(0xB2); // b'10101100, read single byte data = ReadSPI(); PORTCbits.RC2 = 1; // CS high Delay1TCY(); // delay at least 5 ns //data = data>>1; printf("Data is 0x%02X \r\n", data); } }
void DelayFor18TCY(void) { //Delay10TCYx(0x2); //delays 20 cycles Delay10TCYx(1); Delay1TCY();Delay1TCY();Delay1TCY();Delay1TCY(); Delay1TCY();Delay1TCY();Delay1TCY();Delay1TCY(); Delay1TCY();Delay1TCY(); return; }
void Pas(){ CLOCK =0; // On attend 1 µs, 12 cycles Delay1TCY(); Delay1TCY(); Delay10TCYx(1); // On repasse à 1 CLOCK =1; }
// 38KHz のデューティー比 33% の HI で待つ // HI:105.263157894737[cycle] == 8.77192982456142[us] // 38KHz のデューティー比 50% の 場合 // HI:157.894736842105[cycle] == 13.1578947368421[us] void DelayIRFreqHi(void) { // duty 1/3 Delay10TCYx(10); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); }
void DelayTXBitUART( void ){ //Delay4TCYx( (TX_BIT_UART / 4) - 3 ); #if ( FOSC == 18432000 ) #if ( SWBAUD == 19200 ) // DelayTXBitUART == 228 Delay10TCYx( 22 ); // 220 ciclos + 2 de chamada e + 2 de retorno Delay1TCY(); // 1 ciclo Delay1TCY(); // 1 ciclo Delay1TCY(); // 1 ciclo Delay1TCY(); // 1 ciclo #endif #else #endif }
void main(void) { //This uses a 10 MHz clock to // generate a 416 kHz square wave signal // for I2C communication CLOCK_LOW; // data pin output //DATA_LOW; while(1){ SCLK_PIN = 1; // pin high Delay1TCY(); // delay SCLK_PIN = 0; // pin low Delay1TCY(); // delay } }
unsigned int getDistance_mm(){ // On emet une impulsion TRIS_SONIC = 0; // Patte en sortie SONIC = 1; // Etat haut Delay10TCYx(12); // On arrete l'impulsion SONIC = 0; // Etat bas // On écoute le port TRIS_SONIC = 1; // Patte en entrée Delay1TCY(); // On attend que le capteur commence son echelon while(SONIC == 0); // On compte le temps pendant lequel le capteur attend distance_cs = getTemps_cs(); distance_micro_s = getTemps_micro_s(); // On attends que l'echellon se termine while(SONIC == 1); distance_micro_s = getTemps_micro_s() - distance_micro_s ; if(distance_cs != getTemps_cs()){ distance_micro_s = 10000 * (getTemps_cs()-distance_cs)+ distance_micro_s; } return (unsigned int) (distance_micro_s / 6.4); }
void ADXL345_multiByteWrite(unsigned char startAddress, char* buffer, unsigned char size) { #if I2C unsigned char i; StartI2C(); WriteI2C(ADXL343_ADDR_WRITE); WriteI2C(startAddress); for (i = 0; i < size; i++) { WriteI2C(buffer[i]); } StopI2C(); #elif SPI unsigned char tx = (ADXL345_SPI_WRITE | ADXL345_MULTI_BYTE | (startAddress & 0x3F)); unsigned char i; SPI_CS_PIN = 0; //CS pin low, ie enable chip Delay1TCY(); // delay at least 5 ns WriteSPI(tx); //Send starting write address. for (i = 0; i < size; i++) { WriteSPI(buffer[i]); } SPI_CS_PIN = 1; //CS pin high, ie disable chip #endif }
void ADXL345_oneByteWrite(unsigned char address, unsigned char data) { #if I2C StartI2C(); WriteI2C(ADXL343_ADDR_WRITE); // control byte WriteI2C(address); // word address WriteI2C(data); // data StopI2C(); #elif SPI SPI_CS_PIN = 0; //CS pin low, ie enable chip Delay1TCY(); // delay at least 5 ns address = address | ADXL345_SPI_WRITE; WriteSPI(address); // write bit, multibyte bit, A5-A0 address WriteSPI(data); SPI_CS_PIN = 1; //CS pin high, ie disable chip Delay1TCY(); // delay at least 5 ns #endif }
void Delay10TCYx(unsigned char unit) { int i; while(unit > 0) { for(i = 0; i < 10; i++) { Delay1TCY(); } unit--; } };
unsigned char ADXL345_oneByteRead(unsigned char address) { unsigned char data = 0; #if I2C StartI2C(); WriteI2C(ADXL343_ADDR_WRITE); WriteI2C(address); RestartI2C(); WriteI2C(ADXL343_ADDR_READ); data = ReadI2C(); NotAckI2C(); StopI2C(); return data; #elif SPI SPI_CS_PIN = 0; //CS pin low, ie enable chip Delay1TCY(); // delay at least 5 ns address = address | ADXL345_SPI_READ; WriteSPI(address); // read bit, multibyte bit, A5-A0 address data = ReadSPI(); SPI_CS_PIN = 1; //CS pin high, ie disable chip Delay1TCY(); // delay at least 5 ns return data; #endif }
// Delay for: ((((2*FOSC) / (4*baud)) + 1) / 2) - 12 cycles // not sure if a cycle is a clock cycle or instruction cycle (= 4 clocks) void DelayTXBitUART(void) { // for 57600 baud, main clock running at 4 MIPs (million INSTRUCTIONS / sec), ~56 Nops // seems to work. each bit should be 1/57600 = 1.73e-5, and 56 Nops is .25uS*56 = // 14uS, or 1.4e-5... the rest of the delay is from the mechanics of calling a function // and other delays within the UART code. Delay10TCYx(5); Delay1TCY(); // equiv to Nop() Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); }
void ADXL345_multiByteRead(unsigned char startAddress, char* buffer, unsigned char size) { #if I2C unsigned char i; StartI2C(); WriteI2C(ADXL343_ADDR_WRITE); WriteI2C(startAddress); RestartI2C(); WriteI2C(ADXL343_ADDR_READ); for (i = 0; i < size; i++) { buffer[i] = ReadI2C(); //keep the clock pulsing // if not last byte, send ack // if last byte, send nack if(i < size-1) { AckI2C(); } else { NotAckI2C(); } } StopI2C(); #elif SPI unsigned char tx = (ADXL345_SPI_READ | ADXL345_MULTI_BYTE | (startAddress & 0x3F)); // the &0x3F restricts reading from only the XYZ data registers unsigned char i; SPI_CS_PIN = 0; //CS pin low, ie enable chip Delay1TCY(); // delay at least 5 ns WriteSPI(tx); //Send address to start reading from. for (i = 0; i < size; i++) { buffer[i] = ReadSPI(); //keep the clock pulsing } SPI_CS_PIN = 1; //CS pin high, ie disable chip #endif }
void high_isr(void) { //Timer for servo if(INTCONbits.TMR0IF) { PORTBbits.RB3 = 1; if(servoState == 0){ Delay1TCY(); Delay1TCY(); //Delay10TCYx(6); }else{ Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay10TCYx(5); Delay100TCYx(4); } PORTBbits.RB3 = 0; INTCONbits.TMR0IF = 0; // Clear interrupt flag for timer 0 WriteTimer0(64911); } //code for servo state = 1 and regular timer if(PIR1bits.TMR1IF && servoState == 1){ valveCounter++; if(valveCounter == valveTotalTick){ closeValve(); valveCounter = 0; } PIR1bits.TMR1IF = 0; // Clear interrupt flag for timer 0 } else if(PIR1bits.TMR1IF && plantTimerCount == totalTimerCount){ //Waters all the plants moveToLocation(plantBeingWatered); openValve(); if(plantBeingWatered == totalplants){ plantTimerCount = 0; plantBeingWatered = -1; } plantBeingWatered++; PIR1bits.TMR1IF = 0; // Clear interrupt flag for timer 0 } //Timer for timed water sequence else if(PIR1bits.TMR1IF) { plantTimerCount++; PIR1bits.TMR1IF = 0; // Clear interrupt flag for timer 0 } // interupt for button to water plant 0 if(INTCONbits.INT0IF){ moveToLocation(0); openValve(); INTCONbits.INT0IF = 0; } // interupt for button to water plant 1 if(INTCON3bits.INT1IF){ moveToLocation(1); openValve(); INTCON3bits.INT1IF = 0; } // interupt for button to water plant 2 if(INTCON3bits.INT2IF){ moveToLocation(2); openValve(); INTCON3bits.INT2IF = 0; } }
void high_ISR(void) { //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. #if defined(USB_INTERRUPT) USBDeviceTasks(); #endif if (PIR1bits.TMR1IF) { // Clear the interrupt PIR1bits.TMR1IF = 0; TMR1L = TIMER1_L_RELOAD; // Set to 120 for 25KHz ISR fire TMR1H = TIMER1_H_RELOAD; // OutByte = CurrentCommand.DirBits; TookStep = FALSE; AllDone = TRUE; // Note, you don't even need a command to delay. Any command can have // a delay associated with it, if DelayCounter is != 0. if (CurrentCommand.DelayCounter) { CurrentCommand.DelayCounter--; } if (CurrentCommand.DelayCounter) { AllDone = FALSE; } else if (CurrentCommand.Command == COMMAND_MOTOR_MOVE) { // Only output DIR bits if we are actually doing something if (CurrentCommand.StepsCounter[0] || CurrentCommand.StepsCounter[1]) { if (UseBuiltInDrivers) { if (CurrentCommand.DirBits & DIR1_BIT) { Dir1IO = 1; } else { Dir1IO = 0; } if (CurrentCommand.DirBits & DIR2_BIT) { Dir2IO = 1; } else { Dir2IO = 0; } } else { if (CurrentCommand.DirBits & DIR1_BIT) { Dir1AltIO = 1; } else { Dir1AltIO = 0; } if (CurrentCommand.DirBits & DIR2_BIT) { Dir2AltIO = 1; } else { Dir2AltIO = 0; } } // Only do this if there are steps left to take if (CurrentCommand.StepsCounter[0]) { StepAcc[0] = StepAcc[0] + CurrentCommand.StepAdd[0]; if (StepAcc[0] > 0x8000) { StepAcc[0] = StepAcc[0] - 0x8000; OutByte = OutByte | STEP1_BIT; TookStep = TRUE; CurrentCommand.StepsCounter[0]--; } AllDone = FALSE; } if (CurrentCommand.StepsCounter[1]) { StepAcc[1] = StepAcc[1] + CurrentCommand.StepAdd[1]; if (StepAcc[1] > 0x8000) { StepAcc[1] = StepAcc[1] - 0x8000; OutByte = OutByte | STEP2_BIT; TookStep = TRUE; CurrentCommand.StepsCounter[1]--; } AllDone = FALSE; } if (TookStep) { if (UseBuiltInDrivers) { if (OutByte & STEP1_BIT) { Step1IO = 1; } if (OutByte & STEP2_BIT) { Step2IO = 1; } } else { if (OutByte & STEP1_BIT) { Step1AltIO = 1; } if (OutByte & STEP2_BIT) { Step2AltIO = 1; } } Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); if (UseBuiltInDrivers) { Step1IO = 0; Step2IO = 0; } else { Step1AltIO = 0; Step2AltIO = 0; } } } } // Check to see if we should change the state of the pen else if (CurrentCommand.Command == COMMAND_SERVO_MOVE) { if (gUseRCPenServo) { // Precompute the channel, since we use it all over the place UINT8 Channel = CurrentCommand.ServoChannel - 1; // This code below is the meat of the RCServo2_Move() function // We have to manually write it in here rather than calling // the function because a real function inside the ISR // causes the compiler to generate enormous amounts of setup/teardown // code and things run way too slowly. // If the user is trying to turn off this channel's RC servo output if (0 == CurrentCommand.ServoPosition) { // Turn off the PPS routing to the pin *(gRC2RPORPtr + gRC2RPn[Channel]) = 0; // Clear everything else out for this channel gRC2Rate[Channel] = 0; gRC2Target[Channel] = 0; gRC2RPn[Channel] = 0; gRC2Value[Channel] = 0; } else { // Otherwise, set all of the values that start this RC servo moving gRC2Rate[Channel] = CurrentCommand.ServoRate; gRC2Target[Channel] = CurrentCommand.ServoPosition; gRC2RPn[Channel] = CurrentCommand.ServoRPn; if (gRC2Value[Channel] == 0) { gRC2Value[Channel] = CurrentCommand.ServoPosition; } } } // If this servo is the pen servo (on g_servo2_RPn) if (CurrentCommand.ServoRPn == g_servo2_RPn) { // Then set its new state based on the new position if (CurrentCommand.ServoPosition == g_servo2_min) { PenState = PEN_UP; SolenoidState = SOLENOID_OFF; if (gUseSolenoid) { PenUpDownIO = 0; } } else { PenState = PEN_DOWN; SolenoidState = SOLENOID_ON; if (gUseSolenoid) { PenUpDownIO = 1; } } } } // If we're done with our current command, load in the next one if (AllDone) { CurrentCommand.Command = COMMAND_NONE; if (!FIFOEmpty) { CurrentCommand = CommandFIFO[0]; /* for (i = 0; i < NUMBER_OF_STEPPERS; i++) { StepAdd[i] = CommandFIFO[0].ToLoadStepAdd[i]; StepsCounter[i] = CommandFIFO[0].ToLoadStepsCounter[i]; } DirBits = CommandFIFO[0].ToLoadDirBits; Command = CommandFIFO[0].ToLoadCommand; DelayCounter = CommandFIFO[0].ToLoadDelayCounter; */ FIFOEmpty = TRUE; } } // Check for button being pushed if ( (!swProgram) || ( UseAltPause && !PORTBbits.RB0 ) ) { ButtonPushed = TRUE; } } }
// 38KHz のデューティー比 33% の LO で待つ // LO:210.526315789474[cycle] == 17.5438596491228[us] // 38KHz のデューティー比 50% の 場合 // LO:157.894736842105[cycle] == 13.1578947368421[us] void DelayIRFreqLo(void) { // duty 1/3 Delay10TCYx(21); Delay1TCY(); }
void YourLowPriorityISRCode() { // Service Timer2 interrupt (10us resolution note generator) if( PIR1bits.TMR2IF == 1 ) { PIR1bits.TMR2IF = 0; // Clear the interrupt flag Generator[0].Timer++; Generator[1].Timer++; Generator[2].Timer++; Generator[3].Timer++; // NOTE! In the following sections, I have Delay1TCY(); statements littered // about in an ugly fashion. I was conducting some timing experiments on my // floppy hardware... some drives are more tolerant than others when it comes // to timing. I'll put some easily adjustable knobs in later, but feel // free to mess around with it in the meantime. if( Generator[0].Active == TRUE ) { if( Generator[0].Timer >= Generator[0].Period ) { Generator[0].Timer = 0; DRIVE_0_SELECT = 0; // light on Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_0_STEP = 0; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_0_STEP = 1; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_0_DIRECTION = ~DRIVE_0_DIRECTION; } } else { DRIVE_0_SELECT = 1; // light off } if( Generator[1].Active == TRUE ) { if( Generator[1].Timer >= Generator[1].Period ) { Generator[1].Timer = 0; DRIVE_1_SELECT = 0; // light on Delay1TCY(); Delay1TCY(); DRIVE_1_STEP = 0; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_1_STEP = 1; Delay1TCY(); DRIVE_1_DIRECTION = ~DRIVE_1_DIRECTION; } } else { DRIVE_1_SELECT = 1; // light off } if( Generator[2].Active == TRUE ) { if( Generator[2].Timer >= Generator[2].Period ) { static unsigned char count = 0; Generator[2].Timer = 0; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); // test block Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_2_SELECT = 0; // light on Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); // test block Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_2_STEP = 0; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); // test block Delay1TCY(); Delay1TCY(); DRIVE_2_STEP = 1; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); //count++; //if( count >= 80 ) { DRIVE_2_DIRECTION = ~DRIVE_2_DIRECTION; //count = 0; } } } else { DRIVE_2_SELECT = 1; // light off } if( Generator[3].Active == TRUE ) { if( Generator[3].Timer >= Generator[3].Period ) { Generator[3].Timer = 0; DRIVE_3_SELECT = 0; // light on Delay1TCY(); Delay1TCY(); DRIVE_3_STEP = 0; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); DRIVE_3_STEP = 1; Delay1TCY(); DRIVE_3_DIRECTION = ~DRIVE_3_DIRECTION; } } else { DRIVE_3_SELECT = 1; // light off } } } //This return will be a "retfie", since this is in a #pragma interruptlow section
// Init code void EBB_Init(void) { char i; for (i = 0; i < NUMBER_OF_STEPPERS; i++) { CurrentCommand.StepAdd[i] = 1; CurrentCommand.StepsCounter[i] = 0; } FIFOEmpty = TRUE; // Set up TMR1 for our 25KHz High ISR for stepping T1CONbits.RD16 = 0; // Set 8 bit mode T1CONbits.TMR1CS1 = 0; // System clocked from Fosc/4 T1CONbits.TMR1CS0 = 0; T1CONbits.T1CKPS1 = 1; // Use 1:4 Prescale value T1CONbits.T1CKPS0 = 0; T1CONbits.T1OSCEN = 0; // Don't use external osc T1CONbits.T1SYNC = 0; TMR1L = TIMER1_L_RELOAD; // Set to 120 for 25KHz ISR fire TMR1H = TIMER1_H_RELOAD; // T1CONbits.TMR1ON = 1; // Turn the timer on IPR1bits.TMR1IP = 1; // Use high priority interrupt PIR1bits.TMR1IF = 0; // Clear the interrupt PIE1bits.TMR1IE = 1; // Turn on the interrupt // For debugging // PORTA = 0; RefRA0_IO_TRIS = INPUT_PIN; // PORTB = 0; // INTCON2bits.RBPU = 0; // Turn on weak-pull ups for port B // PORTC = 0; // Start out low // TRISC = 0x80; // Make portC output execpt for PortC bit 7, USB bus sense // PORTD = 0; // TRISD = 0; // PORTE = 0; // TRISE = 0; ANCON0 = 0xFE; // Let AN0 (RA0) be an analog input ANCON1 = 0x17; // Let AN11 (V+) also be an analog input MS1_IO = 1; MS1_IO_TRIS = OUTPUT_PIN; MS2_IO = 1; MS2_IO_TRIS = OUTPUT_PIN; MS3_IO = 1; MS3_IO_TRIS = OUTPUT_PIN; Enable1IO = 1; Enable1IO_TRIS = OUTPUT_PIN; Enable2IO = 1; Enable2IO_TRIS = OUTPUT_PIN; Step1IO = 0; Step1IO_TRIS = OUTPUT_PIN; Dir1IO = 0; Dir1IO_TRIS = OUTPUT_PIN; Step2IO = 0; Step2IO_TRIS = OUTPUT_PIN; Dir2IO = 0; Dir2IO_TRIS = OUTPUT_PIN; // For bug in VUSB divider resistor, set RC7 as output and set high // Wait a little while to charge up // Then set back as an input // The idea here is to get the schmidt trigger input RC7 high before // we make it an input, thus getting it above the 2.65V ST threshold // And allowing VUSB to keep the logic level on the pin high at 2.5V #if defined(USE_USB_BUS_SENSE_IO) tris_usb_bus_sense = OUTPUT_PIN; // See HardwareProfile.h USB_BUS_SENSE = 1; Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); Delay1TCY(); tris_usb_bus_sense = INPUT_PIN; USB_BUS_SENSE = 0; #endif gUseSolenoid = TRUE; gUseRCPenServo = TRUE; // Set up pen up/down direction as output /// TODO: This should be different based upon the board type, right? PenUpDownIO = 0; PenUpDownIO_TRIS = OUTPUT_PIN; SolenoidState = SOLENOID_ON; UseBuiltInDrivers = TRUE; PenState = PEN_UP; Layer = 0; NodeCount = 0; ButtonPushed = FALSE; // Default RB0 to be an input, with the pull-up enabled, for use as alternate // PAUSE button (just like PRG) // Except for v1.1 hardware, use RB2 TRISBbits.TRISB0 = 1; INTCON2bits.RBPU = 0; // Turn on all of PortB pull-ups UseAltPause = TRUE; TRISBbits.TRISB3 = 0; // Make RB3 an output (for engraver) PORTBbits.RB3 = 0; // And make sure it starts out off }
void EscI2CDelay(void) { Delay1TCY(); Delay1TCY(); }