Esempio n. 1
0
// Interrupt Service Routine for TIMER 3. This is used to switch between the
// buzzing and quiet periods when ON_CYCLES or OFF_CYCLES are reached.
extern "C" void __ISR (_TIMER_3_VECTOR, ipl5) T3_IntHandler (void)
{
  alarm--;
  if (alarm == 0) {
    buzzing = !buzzing;
    if (is_buzzer_on && buzzing) {
      switch(BUZZER_PIN) {
        case 9:
          OpenOC4(OC_ON | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, DUTY_CYCLE, 0);
          break;
        case 10:
          OpenOC5(OC_ON | OC_TIMER3_SRC | OC_PWM_FAULT_PIN_DISABLE, DUTY_CYCLE, 0);
          break;
      }
      alarm = ON_CYCLES;
    } else {
      switch(BUZZER_PIN) {
        case 9:  CloseOC4(); break;
        case 10: CloseOC5(); break;
      }
      alarm = OFF_CYCLES;
      pin_write(BUZZER_PIN, LOW);
    }
  }
  // Clear interrupt flag
  // This will break other interrupts and millis() (read+clear+write race condition?)
  //   IFS0bits.T3IF = 0; // DON'T!! 
  // Instead:
  mT3ClearIntFlag();
}
Esempio n. 2
0
// 20kHz PWM signal, duty from 0-1000, pin D3
void initTimer2Interrupt(void)
{
    OpenTimer2(T2_ON | T2_PS_1_4, 1000);
    OpenOC4(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
    HBridgeDuty = 0;
    SetDCOC4PWM(HBridgeDuty);
}
Esempio n. 3
0
File: PWM.c Progetto: gpeal/Sherman
void setupPWM(int outputControlX)
{

    switch(outputControlX)
    {
        case 1:
            OpenOC1(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
        case 2:
            OpenOC2(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
        case 3:
            OpenOC3(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
        case 4:
            OpenOC4(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
        case 5:
            OpenOC5(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
        default:
            OpenOC1(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0); // PWM output on Pin D0, 0 duty cycle
            break;
    }

}
Esempio n. 4
0
File: PWM.c Progetto: sdajani/sdp
/****************************************************************************
 Function
     PWM_init

 Parameters
    Channels, used #defined PWM_PORTxxx OR'd together for each PWM Channel
    Period, An integer representing the frequency in hertz


 Returns
     SUCCESS or ERROR

 Description
 Initializes the OC channels into PWM mode and sets up the channels at frequncy given
 Notes
     None.

 Author
 Max Dunne, 2011.11.12
 ****************************************************************************/
char PWM_init(unsigned char Channels, unsigned int Period) {
    if ((Channels < 1) || (Channels > 0x1F) || (usedChannels != 0))
        return ERROR;
    if (Period <= 1000) {
        OpenTimer2(T2_ON | T2_PS_1_32, F_PB / 32 / Period);
        dbprintf("Period less than 1KHz, setting prescaler to 32");
    } else {
        OpenTimer2(T2_ON | T2_PS_1_1, F_PB / Period);
        dbprintf("Period greater than 1KHz, setting prescaler to 1");
    }
    usedChannels = Channels;
    if (PWM_PORTZ06 & Channels) {
        OpenOC1(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        dbprintf("Port Z6 Initialized\r\n");
    }
    if (PWM_PORTY12 & Channels) {
        OpenOC2(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        dbprintf("Port Y12 Initialized\r\n");
    }
    if (PWM_PORTY10 & Channels) {
        OpenOC3(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        dbprintf("Port Y10 Initialized\r\n");
    }
    if (PWM_PORTY04 & Channels) {
        OpenOC4(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        dbprintf("Port Y4 Initialized\r\n");
    }
    if (PWM_PORTX11 & Channels) {
        OpenOC5(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
        dbprintf("Port X11 Initialized\r\n");
    }
}
Esempio n. 5
0
//////////////////////////////////////////////////////////////////////////////////
/// name: initialization
/// params: none
/// return: void
/// desc: contains the configuration of hardware and clock, as well as
///       the initialization of variables
void intialization(void)
{
    // button input pin
    PORTSetPinsDigitalIn(IOPORT_E, BUTTON); 
    // LED output pin
    PORTSetPinsDigitalOut(IOPORT_E, LED_1); 
    // motor direction pin
    PORTSetPinsDigitalOut(IOPORT_B, DC_MOTOR_1);  
	

    // configuring timer  
    OpenTimer2(T2_ON | T2_PS_1_1, TERMINAL_COUNT);
    OpenOC4(OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0x80, 0x60); 
  
    // start these values at 0
    _risetime = 0;
    _falltime = 0;
    _hitime = 0;
  
    // motor starts stationary
    _motorState = STOP;	
    _motorGo = 0;
  
    // start arm fully retracted
    _faketach = 0;
  
    // set these values to 1, as they should start out not
    // equal to _risetime and _falltime for initial pwm read
    _store = 1;
    _ftore = 1;
  
}
Esempio n. 6
0
/**
 * Backlight is open drain on pin D2, controlled by OC4, using Timer 3
 * Contrast uses normal CMOS with OC3, also driven by Timer 3
 */
void lcd_init(void) {
	//Set backlight to open drain
	mPORTDOpenDrainOpen( BIT_2 );

	//Start the timer for contrast/brightness PWM
	OpenTimer3(T3_ON, LCD_PWMPERIOD);

	//Enable contrast control
	OpenOC3( OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , LCD_PWMPERIOD, 0x500 );

	//Enable brightness control
	OpenOC4( OC_ON | OC_TIMER_MODE16 | OC_TIMER3_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , LCD_PWMPERIOD, 0x500 );
}
Esempio n. 7
0
void Initialize_OC()
{
    UnlockRP;
    _RP10R = 0b10010; //Tie OC1 to RP10 (PWM1)
    _RP11R = 0b10011; //Tie OC2 to RP11 (PWM2)
    _RP12R = 0b10100; //Tie OC3 to RP12 (PWM3)
    _RP13R = 0b10101; //Tie OC4 to RP13 (PWM4)
    LockRP;

    OpenOC1(OC_IDLE_CON & OC_TIMER3_SRC & OC_OFF, 1000, 0);
    OpenOC2(OC_IDLE_CON & OC_TIMER3_SRC & OC_OFF, 1000, 0);
    OpenOC3(OC_IDLE_CON & OC_TIMER3_SRC & OC_OFF, 1000, 0);
    OpenOC4(OC_IDLE_CON & OC_TIMER3_SRC & OC_OFF, 1000, 0); //dans l'ordre OCxRS et OCxR

    ConfigIntOC1(OC_INT_OFF & OC_INT_PRIOR_2);
    ConfigIntOC2(OC_INT_OFF & OC_INT_PRIOR_2);
    ConfigIntOC3(OC_INT_OFF & OC_INT_PRIOR_2);
    ConfigIntOC4(OC_INT_OFF & OC_INT_PRIOR_2);
}
Esempio n. 8
0
void initPIC() {
    SYSTEMConfig(SYS_FREQ, SYS_CFG_ALL);

    initLEDs();
    initSerialNU32v2();

    // Setup and turn off electromagnets
    EMAG1 = 0;
    EMAG2 = 0;
    TRISEbits.TRISE7 = 0;
    TRISCbits.TRISC1 = 0;

    // Direction Output
    DIR = 1;
    TRISAbits.TRISA9 = 0;

    setup_counters();

    CloseADC10();
#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF
#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31
#define PARAM4  ENABLE_AN0_ANA | ENABLE_AN1_ANA | ENABLE_AN2_ANA | ENABLE_AN3_ANA | ENABLE_AN5_ANA | ENABLE_AN15_ANA
    OpenADC10(PARAM1, PARAM2, PARAM3, PARAM4, 0);
    EnableADC10();

    // 20kHz PWM signal, duty from 0-1000, pin D3
    OpenTimer2(T2_ON | T2_PS_1_4, MAX_DUTY);
    OpenOC4(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
    SetDCOC4PWM(0);

    // 200 Hz ISR
    OpenTimer3(T3_ON | T3_PS_1_256, (6250/4 - 1));
    //OpenTimer3(T3_ON | T3_PS_1_256, (62500 - 1));
    mT3SetIntPriority(1);
    mT3ClearIntFlag();
    mT3IntEnable(1);

    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
    INTEnableSystemMultiVectoredInt();
}
Esempio n. 9
0
void setup() {
    SYSTEMConfigPerformance(SYSCLK);

    // Initialize hardware UART2 and establish communication at 9600 bps
    UARTInit(9600);

    // Init i2c
    I2CInit();
//    if (I2CInit((uint32_t) I2CMASTER) == 0) {
//        printf("Fatal error!\n");
//        while (1);
//    }

    ov7670_init();
    

    // включить таймер
    //T1CON = 0x8030;

    //OpenTimer2( T2_ON | T2_SOURCE_INT | T2_PS_1_8, 0x0008);
    //OpenTimer2( T2_ON | T2_SOURCE_INT | T2_PS_1_256, 0xFFFF);
    // This statement says: turn on timer2 | have it use an internal clock source | have it
    // use a prescaler of 1:256, and use a period of 0xFFFF or 2^16 cycles

    // Timer2 as configured would trigger an interrupt at a frequency of (80MHZ/256/65535), or 4.77
    // times a second.

    //ConfigIntTimer2( T2_INT_ON | T2_INT_PRIOR_2);
    // This statement configured the timer to produce an interrupt with a priority of 2

    //INTEnableSystemMultiVectoredInt();
    // Use multi-vectored interrupts

    OpenTimer2(T2_ON | T2_PS_1_8, 0);
    OpenOC4( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , 0, 0 );
}
Esempio n. 10
0
int main(void) {
	timesec=0;
	// set PIC32 to max computing power
	SYSTEMConfig(SYS_FREQ, SYS_CFG_ALL);
	INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
	INTEnableSystemMultiVectoredInt();   
    initLEDs(); 	
    LED0 = 1;
    LED1 = 1;
    initSerialNU32v2();
	setup_counters();

  	CloseADC10();
  	#define PARAM1  ADC_MODULE_ON | ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON
  	#define PARAM2  ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF
  	#define PARAM3  ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31
  	#define PARAM4  ENABLE_AN0_ANA | ENABLE_AN1_ANA | ENABLE_AN2_ANA | ENABLE_AN3_ANA | ENABLE_AN5_ANA | ENABLE_AN15_ANA
  	OpenADC10( PARAM1, PARAM2, PARAM3, PARAM4,0);
  	EnableADC10();


    // Setup and turn off electromagnets
    EMAG1 = 0; EMAG2 = 0; 
    TRISEbits.TRISE7 = 0; TRISCbits.TRISC1 = 0;
	//Direction Output
	DIR = 1;
  	TRISAbits.TRISA9 = 0;
	//g-select Outputs
	GSEL1 = 0; GSEL2 = 0;
  	TRISEbits.TRISE2 = 0; TRISCbits.TRISC13= 0;
  	//0g Inputs
  	TRISAbits.TRISA0 = 1;
  	TRISAbits.TRISA4 = 1;

  	// 20kHz PWM signal, duty from 0-1000, pin D3
  	OpenTimer2(T2_ON | T2_PS_1_4, 1000);
  	OpenOC4(OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, 0, 0);
  	HBridgeDuty = 0;
  	SetDCOC4PWM(HBridgeDuty);

    // 20Hz ISR
    OpenTimer3(T3_ON | T3_PS_1_256, 15625);
    mT3SetIntPriority(1);
    mT3ClearIntFlag();
    mT3IntEnable(1);


	while(1) {
		if(start){
			EMAG2=0;
			SetDCOC4PWM(100);
			delaysec(delay1);
			SetDCOC4PWM(1000);		
			delaysec(delay2);
			SetDCOC4PWM(500);
			delaysec(delay3);
			EMAG2=1;
			SetDCOC4PWM(0);	

//			EMAG1=0;
//			SetDCOC4PWM(900);
//			DIR = 0;
//			delaysec(delay1);
//			SetDCOC4PWM(0);
//			delaysec(delay2);
//			SetDCOC4PWM(700);
//			delaysec(delay1);
//			SetDCOC4PWM(1000);
//			EMAG1=1;

			start=0;
		}
	}
}
Esempio n. 11
0
//*********************************************************************
//*	PWM output only works on the pins with hardware support. 
//*	These are defined in the appropriate pins_*.c file.
//*	For the rest of the pins, we default to digital output.
//*********************************************************************
void analogWrite(uint8_t pin, int val)
{

	// We need to make sure the PWM output is enabled for those pins
	// that support it, as we turn it off when digitally reading or
	// writing with them.  Also, make sure the pin is in output mode
	// for consistenty with Wiring, which doesn't require a pinMode
	// call for the analog output pins.
	pinMode(pin, OUTPUT);
	if (val == 0)
	{
		digitalWrite(pin, LOW);
	}
	else if (val == 255)
	{
		digitalWrite(pin, HIGH);
	}
	else
	{
		switch(digitalPinToTimer(pin))
		{
		#ifdef _OCMP1
			case TIMER_OC1:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC1( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, (PWM_TIMER_PERIOD*val)/256, (PWM_TIMER_PERIOD*val)/256  );
				//Set duty cycle on fly
				SetDCOC1PWM((PWM_TIMER_PERIOD*val)/256);
				break;
		#endif

		#ifdef _OCMP2
			case TIMER_OC2:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC2( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, (PWM_TIMER_PERIOD*val)/256, (PWM_TIMER_PERIOD*val)/256  );
				//Set duty cycle on fly
				SetDCOC2PWM((PWM_TIMER_PERIOD*val)/256);
				break;
		#endif

		#ifdef _OCMP3
			case TIMER_OC3:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC3( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, (PWM_TIMER_PERIOD*val)/256, (PWM_TIMER_PERIOD*val)/256  );
				//Set duty cycle on fly
				SetDCOC3PWM((PWM_TIMER_PERIOD*val)/256);
				break;
		#endif

		#ifdef _OCMP4
			case TIMER_OC4:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC4( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, (PWM_TIMER_PERIOD*val)/256, (PWM_TIMER_PERIOD*val)/256  );
				//Set duty cycle on fly
				SetDCOC4PWM((PWM_TIMER_PERIOD*val)/256);
				break;
		#endif

		#ifdef _OCMP5
			case TIMER_OC5:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC5( OC_ON | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE, (PWM_TIMER_PERIOD*val)/256, (PWM_TIMER_PERIOD*val)/256  );
				//Set duty cycle on fly
				SetDCOC5PWM((PWM_TIMER_PERIOD*val)/256);
				break;
		#endif

#if 0
//*	this is the original code, I want to keep it around for refernce for a bit longer
		#ifdef _OCMP1
			case TIMER_OC1:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC1( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 256, (256 - val) );

//			    SetDCOC1PWM((PWM_TIMER_PERIOD * val) / 256);
				break;
		#endif

		#ifdef _OCMP2
			case TIMER_OC2:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC2( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 256, (256 - val) );

//			    SetDCOC2PWM((PWM_TIMER_PERIOD * val) / 256);
				break;
		#endif

		#ifdef _OCMP3
			case TIMER_OC3:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC3( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 256, (256 - val) );

//			    SetDCOC3PWM((PWM_TIMER_PERIOD * val) / 256);
				break;
		#endif

		#ifdef _OCMP4
			case TIMER_OC4:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC4( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 256, (256 - val) );

//			    SetDCOC4PWM((PWM_TIMER_PERIOD * val) / 256);
				break;
		#endif

		#ifdef _OCMP5
			case TIMER_OC5:
				//* Open Timer2 with Period register value
				OpenTimer2(T2_ON | T2_PS_1_256, PWM_TIMER_PERIOD);
				OpenOC5( OC_ON | OC_TIMER_MODE32 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 256, (256 - val) );

//			    SetDCOC5PWM((PWM_TIMER_PERIOD * val) / 256);
				break;
		#endif
#endif

			case NOT_ON_TIMER:
			default:
				if (val < 128)
				{
					digitalWrite(pin, LOW);
				}
				else
				{
					digitalWrite(pin, HIGH);
				}
		}
	}
}
Esempio n. 12
0
static void lcd_setup(void)
{
    //mPORTDSetPinsDigitalOut(BIT_3);
    //mPORTDClearBits(BIT_3);

    mPORTDSetPinsDigitalOut( BIT_2 );

    //Set backlight to open drain
    mPORTDOpenDrainOpen( BIT_2 );

    //Enable contrast control
    OpenTimer2(T2_ON, LCD_PWMPERIOD);
    OpenOC4( OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , LCD_PWMPERIOD, 0x0458 );

    //Start the timer for contrast/brightness PWM
    //OpenTimer3(T3_ON | T3_PS_1_1 | T3_SOURCE_INT, LCD_PWMPERIOD);
    //PR3 = LCD_PWMPERIOD - 1;
    //OC3R = 0;
    //mT3SetIntPriority(4);
    //mT3ClearIntFlag();
    //mT3IntEnable(1);
    //SetDCOC3PWM(LCD_PWMPERIOD >> 2);
    //SetDCOC3PWM(1);

    //Enable brightness control
    OpenOC3( OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH , LCD_PWMPERIOD, 0x500 );

    // Open ENABLE line as output
    LCD_EN_CLR();
    PORT_DIR_OUT(LCD_EN_P, LCD_EN);
    LCD_EN_CLR();

    // Open RW and RS lines as output
    LCD_RS_CLR();
    PORT_CLR(LCD_RW_P, LCD_RW);

    PORT_DIR_OUT(LCD_RS_P, LCD_RS);
    PORT_DIR_OUT(LCD_RW_P, LCD_RW);

    LCD_RS_CLR();
    PORT_CLR(LCD_RW_P, LCD_RW);

    // Set data lines as output
    PORT_CLR(LCD_DATA_P, LCD_DATA_MASK);
    PORT_DIR_OUT(LCD_DATA_P, LCD_DATA_MASK);
    PORT_CLR(LCD_DATA_P, LCD_DATA_MASK);

    // Wait for proper power up
    task_delay(LCD_LONG_DELAY);
    task_delay(LCD_LONG_DELAY);
    task_delay(LCD_LONG_DELAY);
    task_delay(LCD_LONG_DELAY);

    // Wait for the LCD to power up correctly
    lcd_command(LCD_FUNCTION_SET_CMD | LCD_FUNCTION_SET_8_BITS);
    task_delay(LCD_SHORT_DELAY);
    lcd_command(LCD_FUNCTION_SET_CMD | LCD_FUNCTION_SET_8_BITS);
    task_delay(LCD_VERY_SHORT_DELAY);
    lcd_command(LCD_FUNCTION_SET_CMD | LCD_FUNCTION_SET_8_BITS);
    task_delay(LCD_VERY_SHORT_DELAY);

    // Set up the LCD function
    lcd_command(LCD_FUNCTION_SET_CMD | LCD_FUNCTION_SET_8_BITS | LCD_FUNCTION_SET_2_LINES);
    task_delay(LCD_VERY_SHORT_DELAY);

    // Turn the display on
    lcd_command(LCD_DISPLAY_CTRL_CMD | LCD_DISPLAY_CTRL_CURSOR_ON | LCD_DISPLAY_CTRL_BLINK_ON);
    task_delay(LCD_VERY_SHORT_DELAY);

    // Clear the display
    lcd_command(LCD_CLEAR_DISPLAY_CMD);
    task_delay(LCD_SHORT_DELAY);

    // Increase the cursor
    lcd_command(LCD_ENTRY_MODE_CMD | LCD_ENTRY_MODE_INCREASE);
    task_delay(LCD_SHORT_DELAY);

    lcd_command(LCD_DISPLAY_CTRL_CMD | LCD_DISPLAY_CTRL_DISPLAY_ON);
    task_delay(LCD_SHORT_DELAY);
}