//reset LCD to 4bit mode void HD44780_Reset(void){ //set initial pin states LCD_BL_TRIS&=(~LCD_BL_PIN);//backlight pin output LCD_BL_LAT|=LCD_BL_PIN; //backlight on //all I/O should be to ground, low to start TRISC&=(~0b11000000); LATC&=(~0b11000000); TRISD&=(~0b11111000); LATD&=(~0b11111000); //# Wait more than 15 msecs after power is applied. delayMS(15); LCD_RS=0;//0 for a command //# Write 0x03 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteNibble(0x03); delayMS(5); //# Write 0x03 to LCD and wait 160 usecs for instruction to complete HD44780_WriteNibble(0x03); delayUS(160); //# Write 0x03 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteNibble(0x03); delayUS(160); //Set the Operating Characteristics of the LCD //* Write 0x02 to the LCD to Enable Four Bit Mode HD44780_WriteNibble(0x02); delayUS(160); }
//reset LCD to 4bit mode void HD44780_Reset(void){ //set initial pin states //LCD_BL_TRIS=0;//backlight pin output //LCD_BL=0; //backlight off //we use open drain with pullup resistors to interface the LCD at 5volts //all I/O should be to ground, low to start PORTB &= (~0b10111111100000); LATB &= (~0b10111111100000); TRISB &= (~0b10111111100000); //# Wait more than 15 msecs after power is applied. delayMS(15); LCD_RS_TRIS=0;//0 for a command //# Write 0x03 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteNibble(0x03); delayMS(5); //# Write 0x03 to LCD and wait 160 usecs for instruction to complete HD44780_WriteNibble(0x03); delayUS(160); //# Write 0x03 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteNibble(0x03); delayUS(160); //Set the Operating Characteristics of the LCD //* Write 0x02 to the LCD to Enable Four Bit Mode HD44780_WriteNibble(0x02); delayUS(160); }
//write byte dat to register reg void HD44780_WriteByte(unsigned char reg, unsigned char dat){ unsigned int i; //TRISD&=(~0b1); //LCD_RW_TRIS=0; //write mode =0 (this is always set from the beginning) if(reg==DATA){ //does RS need to be set? TRISD|=0b10; //LCD_RS_TRIS=1; //set register select flag for text }else{ TRISD&=(~0b10); //LCD_RS_TRIS=0;//0 for a command } //load values on pins //ensure everything starts low elsewhere.... TRISE &=(~0b11111); //clear the E bits (01234) TRISB &=(~0b111); //clear B bits (765) //put lower 5 bits on E01234 i=0; if(dat & 0b1) i|=0b10000; if(dat & 0b10) i|=0b1000; if(dat & 0b100) i|=0b100; if(dat & 0b1000) i|=0b10; if(dat & 0b10000) i|=0b1; TRISE|=i; //put upper 3 bits on B210 TRISB|=(dat>>5); //clock in the data delayUS(LCD_SETUP_DELAY);//optional setup delay (5) TRISE|=0b100000; //LCD_EN_TRIS=1; //raise the EN line to clock in the values delayUS(LCD_HOLD_DELAY);//hold data delay (16) TRISE &=(~0b100000); //LCD_EN_TRIS=0; //lower EN line }
//reset LCD to 8bit mode void HD44780_Reset(void){ //set initial pin states //we use open drain with pullup resistors to interface the LCD at 5volts //all I/O should be to ground, low to start //all to low for ground on TRIS clear PORTB &=(~0b1111); //clear B bits (B765) PORTD &=(~0b11); //clear D bits (RS/RW) PORTE &=(~0b111111); //clear the E bits (E01234) //all start output/low, 0 on HD44780 pins TRISB &=(~0b1111); //clear B bits (B765) TRISD &=(~0b11); //clear D bits (RS/RW) TRISE &=(~0b111111); //clear the E bits (E01234) //# Wait more than 15 msecs after power is applied. delayMS(15); //# Write 0x30 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayMS(5); //# Write 0x30 to LCD and wait 160 usecs for instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayUS(160); //# Write 0x30 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteByte(COMMAND, 0x30); delayUS(160); }
//write byte dat to register reg void HD44780_WriteByte(unsigned char reg, unsigned char dat){ unsigned int i; //D0-3 RB0-3 //D4-7 RA0-3 //RS RC0 //R/W RA5 (ground) //E RA4 //BL RC2 //LCD_RW_TRIS=0; //write mode =0 if(reg==DATA){ //does RS need to be set? LCD_RS=1; //set register select flag for text }else{ LCD_RS=0;//0 for a command } //ensure everything starts low elsewhere.... //load values on pins LATB&=(~0b1111);//clear lower four of B (D0-3) LATB|=(dat & 0x0F);//pound the lower four of dat onto the lower four of PORTB LATA&=(~0b1111);//clear lower four of A (D4-7) LATA|=((dat>>4)&0x0F);//pound the upper four of dat onto the lower four of PORTA delayUS(5);//optional setup delay LCD_EN=1; //raise the EN line to clock in the values delayUS(16);//optional setup delay LCD_EN=0; //lower EN line }
void GPIOPortF_Handler(void) { int tempX = 0; int tempY = 0; int temp = 0; count = 0; xPos = 0; yPos = 0; xTot = 0; yTot = 0; // clear interrupt PORTF[0x41C] = 0x10; PORTF[0x404] = 0x00; // disable interrupt INTERRUPT[0x280/4] = 0x40000000; INTERRUPT[0x180/4] = 0x40000000; //INTERRUPT[0x280/4] = 0x40000000; // get x and y value do{ SPI1[0x008] = 0x90; // get X position SPI1[0x008] = 0x00; SPI1[0x008] = 0x00; SPI1[0x008] = 0xD0; // get Y position SPI1[0x008] = 0x00; SPI1[0x008] = 0x00; delayUS(30); // give microcontroller time to send and recieve bytes temp = SPI1[0x008]; tempX = (SPI1[0x008] << 5); tempX |= (SPI1[0x008] >> 3); temp = SPI1[0x008]; tempY = (SPI1[0x008] << 5); tempY |= (SPI1[0x008] >> 3); // average x and y values count++; xTot += tempX; yTot += tempY; xPos = xTot/count; yPos = yTot/count; } while(!(PORTF[0x3FC] & 0x10)); //check for PF.4 high clickAction(); delayUS(3250); // enable interrupts INTERRUPT[0x280/4] = 0x40000000; // clear any pending interrupts INTERRUPT[0x100/4] = 0x40000000; // re-enable gpioF interrupts PORTF[0x41C] = 0x10; // clear any pending interrupts PORTF[0x404] = 0x10; // re-enable GPIOF.4 interrupts }
//write 4 bits dat to register reg void HD44780_WriteNibble(unsigned char dat){ unsigned int i; //ensure everything starts low elsewhere.... //load values on pins LATD&=(~0b11110000); i=dat; LATD|=(i<<4); delayUS(5);//optional setup delay LCD_EN=1; //raise the EN line to clock in the values delayUS(16);//optional setup delay LCD_EN=0; //lower EN line }
//backlight control //the LED draws a lot of power when it comes on //and it messes with the pull-up resistors on the data pins //#define LCD_BL_TRIS TRISB //#define LCD_BL_LAT LATB //#define LCD_BL_PIN 0b1000 void LCD_Backlight(unsigned char c){ unsigned char i; LCD_BL_TRIS &= (~LCD_BL_PIN); //backlight pin output if(c){ //turn on slowly with PWM for(i=0; i<255; i++){ LCD_BL_LAT |=LCD_BL_PIN; //backlight ON delayUS(i);//on for increasing us LCD_BL_LAT &= (~LCD_BL_PIN); //backlight OFF delayUS((255-i));//off for decreasing us } LCD_BL_LAT |=LCD_BL_PIN; //exit with light ON }else{ LCD_BL_LAT &= (~LCD_BL_PIN); //backlight off } }
//backlight control //the LED draws a lot of power when it comes on void LCD_Backlight(unsigned char c){ unsigned char i; if(c){ //turn on slowly with PWM for(i=0; i<255; i++){ LCD_BL=1; //backlight ON delayUS(i);//on for increasing us LCD_BL=0; //backlight OFF delayUS((255-i));//off for decreasing us } LCD_BL=1; //exit with light ON }else{ LCD_BL=0; //backlight off } }
//same as LCD_BlinkCursor(), different bit void LCD_UnderlineCursor(unsigned char cursor){ LCDdisplayControl.cursor=cursor; cursor=CMD_DISPLAYCONTROL + DISPLAYON; if(LCDdisplayControl.cursor) cursor+=CURSORON; if(LCDdisplayControl.blink) cursor+=BLINKON; HD44780_WriteByte(COMMAND, cursor); delayUS(40);//delay }
//blink and underline share a command byte, //we need to remember them so we can keep the correct setting on one when we update the other void LCD_BlinkCursor(unsigned char blink){ LCDdisplayControl.blink=blink; //store the setting blink=CMD_DISPLAYCONTROL + DISPLAYON; //setup the command if(LCDdisplayControl.cursor) blink+=CURSORON; //set cursor bit if(LCDdisplayControl.blink) blink+=BLINKON; //set blink bit HD44780_WriteByte(COMMAND, blink); //send command delayUS(40);//delay }
//delay in MS void delayMS(const unsigned char delay){ volatile unsigned int i; volatile unsigned char c; for(c=0;c<delay;c++){ for(i=0;i<4;i++) delayUS(250); } }
void HD44780_FastText(unsigned char dat){ //load values on pins //ensure everything starts low elsewhere.... TRISE &=(~0b11111); //clear the E bits (01234) TRISB &=(~0b111); //clear B bits (765) //put upper 3 bits on B210 TRISB|=(dat>>5); //put lower 5 bits on E01234 dat&=(~0b11100000); //clear the upper bits so they don't interfere with other pins TRISE|=HD44780_lookup[dat];//use lookup table to locate the inverse of the 5bit value //clock in the data delayUS(LCD_SETUP_DELAY);//optional setup delay (5) TRISE|=0b100000; //LCD_EN_TRIS=1; //raise the EN line to clock in the values delayUS(LCD_HOLD_DELAY);//hold data delay (16) TRISE &=(~0b100000); //LCD_EN_TRIS=0; //lower EN line }
// //functions // //reset LCD to 8bit mode void HD44780_Reset(void){ //set initial pin states //we use open drain with pullup resistors to interface the LCD at 5volts //all I/O should be to ground, low to start //all to low for ground on TRIS clear LCD_PIN_SETUP(); //# Wait more than 15 msecs after power is applied. delayMS(15); //# Write 0x30 to LCD and wait 5 msecs for the instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayMS(5); //# Write 0x30 to LCD and wait 160 usecs for instruction to complete HD44780_WriteByte(COMMAND, 0x30); delayUS(160); //# Write 0x30 AGAIN to LCD and wait 160 usecs (or poll the Busy Flag) HD44780_WriteByte(COMMAND, 0x30); delayUS(160); }
/** * @brief This function is executed in case of error occurrence. * @param None * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler */ /* User can add his own implementation to report the HAL error return state */ while (1) { // Led frequency 10hz delayUS(100); toggleLedNucleo(); } /* USER CODE END Error_Handler */ }
//no cursor compensation, for CGRAM void LCD_WriteRAM(char c){ HD44780_WriteByte(DATA, c); delayUS(46); }
//write to character generator RAM void LCD_WriteCGRAM(char c){ c*=8; HD44780_WriteByte(COMMAND, CMD_SETCGRAMADDR + c); delayUS(46); }
int main (void) { uint32_t analogValue; //Set LED1-LED8 pins as outputs GPIOSetDir( LED1_PORT, LED1_PIN, GPIO_OUTPUT); GPIOSetValue( LED1_PORT, LED1_PIN, LED_OFF); GPIOSetDir( LED2_PORT, LED2_PIN, GPIO_OUTPUT); GPIOSetValue( LED2_PORT, LED2_PIN, LED_OFF); GPIOSetDir( LED3_PORT, LED3_PIN, GPIO_OUTPUT); GPIOSetValue( LED3_PORT, LED3_PIN, LED_OFF); GPIOSetDir( LED4_PORT, LED4_PIN, GPIO_OUTPUT); GPIOSetValue( LED4_PORT, LED4_PIN, LED_OFF); GPIOSetDir( LED5_PORT, LED5_PIN, GPIO_OUTPUT); GPIOSetValue( LED5_PORT, LED5_PIN, LED_OFF); GPIOSetDir( LED6_PORT, LED6_PIN, GPIO_OUTPUT); GPIOSetValue( LED6_PORT, LED6_PIN, LED_OFF); GPIOSetDir( LED7_PORT, LED7_PIN, GPIO_OUTPUT); GPIOSetValue( LED7_PORT, LED7_PIN, LED_OFF); GPIOSetDir( LED8_PORT, LED8_PIN, GPIO_OUTPUT); GPIOSetValue( LED8_PORT, LED8_PIN, LED_OFF); //Set SW2/SW3 pins as inputs GPIOSetDir( SW2_PORT, SW2_PIN, GPIO_INPUT); GPIOSetDir( SW3_PORT, SW3_PIN, GPIO_INPUT); //Extra, turn buzzer off GPIOSetDir( BUZZ_PORT, BUZZ_PIN, GPIO_OUTPUT); GPIOSetValue( BUZZ_PORT, BUZZ_PIN, BUZZ_OFF); //Initialize ADC peripheral and pin-mixing ADCInit(4500000); //4.5MHz ADC clock //get initial value analogValue = getADC(AIN0); //AIN0 = trimming pot for intensity LED1 analogValue = getADC(AIN1); //AIN1 = trimming pot for intensity LED2 while(1) { uint8_t wantedDutyCycle0, wantedDutyCycle1; uint8_t loopCounter; uint16_t adcCounter; //check if time to read analog input if (adcCounter++ > 100) { adcCounter = 0; //Set wanted duty cycle - valid numbers: 0..100 (low number = LED on more) wantedDutyCycle0 = getADC(AIN0) / 10; //trimming pot wantedDutyCycle1 = getADC(AIN1) / 10; //trimming pot //extra check to that range is valid if (wantedDutyCycle0 > 99) wantedDutyCycle0 = 99; if (wantedDutyCycle1 > 99) wantedDutyCycle1 = 99; } //Set outputs high GPIOSetValue( LED1_PORT, LED1_PIN, 1); GPIOSetValue( LED2_PORT, LED2_PIN, 1); //Enter duty cycle generating loop for (loopCounter=0; loopCounter<100; loopCounter++) { //10 corresponds to 1kHz (100*10us), LED flickering starts at around 30-40Hz PWM frequency delayUS(10); if (loopCounter == wantedDutyCycle0) //Set output low GPIOSetValue( LED1_PORT, LED1_PIN, 0); if (loopCounter == wantedDutyCycle1) //Set output low GPIOSetValue( LED2_PORT, LED2_PIN, 0); } } return 0; }
int main (void) { uint32_t analogValue; uint8_t wantedDutyCycle, wantedDutyCycleB=100; uint8_t state = 0; //Set LED1-LED8 pins as outputs GPIOSetDir( LED1_PORT, LED1_PIN, GPIO_OUTPUT); GPIOSetValue( LED1_PORT, LED1_PIN, LED_OFF); GPIOSetDir( LED2_PORT, LED2_PIN, GPIO_OUTPUT); GPIOSetValue( LED2_PORT, LED2_PIN, LED_OFF); GPIOSetDir( LED3_PORT, LED3_PIN, GPIO_OUTPUT); GPIOSetValue( LED3_PORT, LED3_PIN, LED_OFF); GPIOSetDir( LED4_PORT, LED4_PIN, GPIO_OUTPUT); GPIOSetValue( LED4_PORT, LED4_PIN, LED_OFF); GPIOSetDir( LED5_PORT, LED5_PIN, GPIO_OUTPUT); GPIOSetValue( LED5_PORT, LED5_PIN, LED_OFF); GPIOSetDir( LED6_PORT, LED6_PIN, GPIO_OUTPUT); GPIOSetValue( LED6_PORT, LED6_PIN, LED_OFF); GPIOSetDir( LED7_PORT, LED7_PIN, GPIO_OUTPUT); GPIOSetValue( LED7_PORT, LED7_PIN, LED_OFF); GPIOSetDir( LED8_PORT, LED8_PIN, GPIO_OUTPUT); GPIOSetValue( LED8_PORT, LED8_PIN, LED_OFF); //Set SW2/SW3 pins as inputs GPIOSetDir( SW2_PORT, SW2_PIN, GPIO_INPUT); GPIOSetDir( SW3_PORT, SW3_PIN, GPIO_INPUT); //Extra, turn buzzer off GPIOSetDir( BUZZ_PORT, BUZZ_PIN, GPIO_OUTPUT); GPIOSetValue( BUZZ_PORT, BUZZ_PIN, BUZZ_OFF); //Set RGB-LED pins as outputs GPIOSetDir( LEDB_PORT, LEDB_PIN, GPIO_OUTPUT); GPIOSetValue( LEDB_PORT, LEDB_PIN, LED_OFF); initPWM(1000); //1000us = 1kHz PWM frequency updatePWM(0, 100); //set 100% duty cycle for channel #0 (RED LED will be off) updatePWM(1, 100); //set 100% duty cycle for channel #1 (GREEN LED will be off) startPWM(); //Initialize ADC peripheral and pin-mixing ADCInit(4500000); //4.5MHz ADC clock //get initial value analogValue = getADC(AIN0); //AIN0 = trimming pot for intensity wantedDutyCycleB = 100; state = 0; while(1) { uint8_t loopCounter; uint16_t adcCounter; //Set BLUE LED output high GPIOSetValue( LEDB_PORT, LEDB_PIN, 1); //check if time to read analog input if (adcCounter++ > 100) { adcCounter = 0; //check push-button SW2 if (GPIOGetValue(SW2_PORT, SW2_PIN) == SW_PRESSED) { state++; if (state > 2) state = 0; //wait until push-button is released while(GPIOGetValue(SW2_PORT, SW2_PIN) == SW_PRESSED) ; } //Set wanted duty cycle - valid numbers: 0..100 (low number = LED on more) wantedDutyCycle = getADC(AIN0) / 10; //trimming pot //extra check to that range is valid if (wantedDutyCycle > 99) wantedDutyCycle = 99; switch(state) { case 0: updatePWM(0, wantedDutyCycle); break; case 1: updatePWM(1, wantedDutyCycle); break; case 2: wantedDutyCycleB = wantedDutyCycle; break; default: state = 0; } } //Enter duty cycle generating loop for (loopCounter=0; loopCounter<100; loopCounter++) { //10 corresponds to 1kHz (100*10us), LED flickering starts at around 30-40Hz PWM frequency delayUS(10); if (loopCounter == wantedDutyCycleB) GPIOSetValue( LEDB_PORT, LEDB_PIN, 0); //Set output low } } return 0; }