void putsLCD(char *s) { char c; while (*s) { switch (*s) { case '\n': // point to second line setLCDC(0x40); break; case '\r': // home, point to first line setLCDC(0); break; case '\t': // advance next tab (8) positions c = addrLCD(); while (c & 7) { putLCD(' '); c++; } if (c > 15) // if necessary to move to second line setLCDC(0x40); break; default: // print character putLCD(*s); break; } s++; // point to next character delayTimer1(30);// Increase if characters are dropped } }
/** * reads in a character array and prints it to the screen * @param string - the string to write to the screen */ void writeLCD(char string[]) { int strlength = strlen(string); int i=0; for(i=0; i<strlength; i++) { putLCD(string[i]); } }
/*------------------MAIN FUNCTION------------------*/ int main(void) { __builtin_write_OSCCONL(2); // Enable secondary oscillator with unlock sequence T1CON = 0x8012; // Enable T1 from external oscillator (SECONDARY), pre-scaler of 8) T2CON = 0x8000; PR1 = 410; // this value generates an interrupt every 100 milliseconds (Primary) /*------------------CONFIGURE INTERRUPTS------------------*/ INTCON2bits.INT0EP = 0; // interrupt on positive edge INTCON2bits.ALTIVT = 0; // use primary IVT IPC0bits.T1IP = 4; // set priority level to 4 (100) IFS0bits.T1IF = 0; // initialize T1 flag to zero IEC0bits.T1IE = 1; // enable the T1 timer interrupt source TRISBbits.TRISB2 = 0; // Used as Register Select for LCD initPMP(); initLCD(); setLCDG(0); putLCD(0b00000); putLCD(0b10001); putLCD(0b00000); putLCD(0b00100); putLCD(0b00000); putLCD(0b10001); putLCD(0b01110); putLCD(0); putLCD(0b00000); putLCD(0b10001); putLCD(0b00000); putLCD(0b00100); putLCD(0b00000); putLCD(0b00000); putLCD(0b11111); putLCD(0); putLCD(0b00000); putLCD(0b10001); putLCD(0b00000); putLCD(0b00100); putLCD(0b00000); putLCD(0b01110); putLCD(0b10001); putLCD(0); int Buf = 0; initADC(); //TRISB = 0xFF00; // configure LED port as outputs char BufString[20]; char BufString2[5]; char BufString3[16]; double voltage, vAvg, avgTime; int i, time; unsigned long bufAvg; int nAvg = 100; TMR1 = 0; /*------------------INFINITE LOOP------------------*/ while(1) { vAvg = 0; voltage = 0; bufAvg = 0; time = 0; avgTime = 0; for(i=0;i<nAvg;i++) { TMR2 = 0; Buf = getADC(0); // read channel 1 of ADC time = TMR2; voltage = Buf*3.3/1023; vAvg = vAvg + voltage; bufAvg = bufAvg + Buf; avgTime = avgTime + time; } vAvg = vAvg/nAvg; bufAvg = bufAvg/nAvg; avgTime = avgTime/nAvg/16/1000; if(myBOOLs.timer_flag == TRUE) { setCursor(1,0); putsLCD("Voltage: "); sprintf(BufString,"%.02f",vAvg); sprintf(BufString2,"%lu",bufAvg); sprintf(BufString3,"%.05f",avgTime); setCursor(1,9); putsLCD(BufString); setCursor(1,16); putsLCD(BufString2); putsLCD(" "); setCursor(2,0); putsLCD("Time: "); setCursor(2,6); putsLCD(BufString3); setCursor(2,14); putsLCD("ms"); setCursor(2,19); if(bufAvg > 1023*2/3) putLCD(0); if(bufAvg < 1023*2/3 && bufAvg > 1023*1/3) putLCD(1); if(bufAvg < 1023*1/3 && bufAvg > 0) putLCD(2); myBOOLs.timer_flag = FALSE; } } return (EXIT_SUCCESS); }
/** LCD (Main Menu) **/ void mainMenu(void){ _INT1IF = LOW; //set INT1 flag back to zero _INT2IF = LOW; //set INT2 flag back to zero int i; clearLCD(); setCursor(1,1); putsLCD("Mode"); setCursor(1,15); putsLCD("C"); setCursor(2,1); putsLCD("RPM"); setCursor(2,9); sprintf(strRPM,"%lu",rpm); putsLCD(strRPM); mainMenuSelect = 32766; // this handles cursor position by means of modulus myBOOLs.mainMenuTrue = TRUE; // these determine which menu for ext interrupt 2 myBOOLs.modeMenuTrue = FALSE; // these determine which menu for ext interrupt 2 myBOOLs.rpmMenuTrue = FALSE; // these determine which menu for ext interrupt 2 while(myBOOLs.mainDecide){ if(mainMenuSelect % 2 == 0){ setCursor(1,0); putsLCD(">"); setCursor(2,0); putsLCD(" "); } else if(mainMenuSelect % 2 != 0){ setCursor(1,0); putsLCD(" "); setCursor(2,0); putsLCD(">"); } // Take 50 readings of tempC tempC = 0; for(i=0;i<50;i++){ tempC = tempC + thermoRead(); } // Find average tempC = tempC/50; sprintf(strTempC,"%.02f",tempC); if(tempC < 100 && tempC >= 10){ setCursor(1,15); putsLCD("C"); setCursor(1,7); putLCD(' '); setCursor(1,8); putLCD(' '); setCursor(1,9); putLCD(0); setCursor(1,10); } else if(tempC < 10 && tempC >= 0){ setCursor(1,15); putsLCD("C"); setCursor(1,8); putLCD(' '); setCursor(1,9); putLCD(' '); setCursor(1,10); putLCD(0); setCursor(1,11); } else{ setCursor(1,15); putsLCD("C"); setCursor(1,8); putLCD(0); setCursor(1,9); } // Show averaged temp on display putsLCD(strTempC); } }
/** Main **/ int main(void){ /** Declare Local Variables **/ /** Initialize State Variables **/ myBOOLs.mainMenuTrue = TRUE; // want program to enter into the main menu myBOOLs.mainDecide = TRUE; // want program to enter into the main menu myBOOLs.modeMenuTrue = FALSE; myBOOLs.modeDecide = FALSE; myBOOLs.rpmMenuTrue = FALSE; myBOOLs.rpmDecide = FALSE; /** Initialize Value Variables **/ rpm = 60; /** Configure Analog Ports **/ AD1PCFGbits.PCFG5 = HIGH; // disable analog functionality for AN5 (Encoder Pin A) AD1PCFGbits.PCFG0 = HIGH; // disable analog functionality for AN0 (SPI - SS) AD1PCFGbits.PCFG2 = HIGH; // disable analog functionality for AN2 (SPI - SDI) AD1PCFGbits.PCFG4 = HIGH; // disable analog functionality for AN4 (SPI - SCK) /** Configure Pin Directions **/ TRISAbits.TRISA2 = OUTPUT; // *output* Stepper Motor Dir TRISAbits.TRISA4 = OUTPUT; // *output* Red LED Sink TRISBbits.TRISB3 = INPUT; // *input* (Encoder Pin A) ~interrupt TRISBbits.TRISB4 = INPUT; // *input* (Encoder Pin B) TRISBbits.TRISB9 = INPUT; // *input* (Encoder PUSH) ~interrupt TRISAbits.TRISA0 = OUTPUT; // *output* (SS for Thermo) TRISBbits.TRISB0 = INPUT; // *input* (SPI - SDI) TRISBbits.TRISB2 = OUTPUT; // *output* (SPI - SCK) /** Initialize Pin States **/ LATAbits.LATA2 = LOW; // Set direction to CW LATAbits.LATA4 = LOW; // Set Red LED ON (sink current) LATAbits.LATA0 = HIGH; // Set SS high TRISBbits.TRISB2 = LOW; // Set SCK low /** Configure Peripheral Pin Selects **/ __builtin_write_OSCCONL(OSCCON & 0xBF); // unlock registers to configure PPS RPINR0bits.INT1R = 3; // configure RP3 as Ext. Int. 1 RPINR1bits.INT2R = 9; // configure RP9 as Ext. Int. 2 RPOR7bits.RP15R = 18; // configure RP15 as OC1 (PWM for EasyDriver) RPOR5bits.RP10R = 19; // configure RP11 as OC2 (PWM for buzzer) __builtin_write_OSCCONL(OSCCON | 0x40); // lock registers /** Configure PWMs **/ period = ((8000000*60)/(1600*rpm)); // calculate PR based on desired PRM duty = period/2; // duty cycle of 50% initPWM(period, duty); // PWM initialization function initPWMbuzz(); /** Configure PMP & LCD **/ initPMP(); initLCD(); setLCDG(0); putLCD(0b00000); putLCD(0b01100); putLCD(0b01100); putLCD(0b01100); putLCD(0b11110); putLCD(0b11110); putLCD(0b01100); putLCD(0); /** Configure Interrupts **/ INTCON2bits.ALTIVT = 0; //use primary IVT //EXT1 interrupt INTCON2bits.INT1EP = 1; // interrupt on falling edge IPC5bits.INT1IP = 4; //set priority level to 4 IFS1bits.INT1IF = 0; //initialize INT1 flag to zero IEC1bits.INT1IE = 1; //enable the interrupt source //EXT2 interrupt INTCON2bits.INT2EP = 1; // interrupt on falling edge IPC7bits.INT2IP = 7; //set priority level to 4 IFS1bits.INT2IF = 0; //initialize INT2 flag to zero IEC1bits.INT2IE = 1; //enable the interrupt source /** LCD Splash Screen **/ clearLCD(); setCursor(1,0); putsLCD(" Stir Plate "); setCursor(2,0); putsLCD(" 9000 "); delay_ms(3000); clearLCD(); OC2CON = 0x0000; /*------------------INFINITE LOOP------------------*/ while(1) { menuDecision(); } return (EXIT_SUCCESS); }
void write_to_lcd( const char *s ) { while (*s) putLCD(*s++); }