/* Name: lcd_init_4d Purpose: initialize the LCD module for a 4-bit data interface Entry: equates (LCD instructions) set up for the desired operation Exit: no parameters Notes: uses time delays rather than checking the busy flag */ void lcd_init_4d(void) { // Power-up delay _delay_ms(100); // initial 100 mSec delay // Set up the RS and E lines for the 'lcd_write_4' subroutine. lcd_RS_port &= ~(1<<lcd_RS_bit); // select the Instruction Register (RS low) lcd_E_port &= ~(1<<lcd_E_bit); // make sure E is initially low // Reset the LCD controller lcd_write_4(lcd_FunctionSet8bit); // first part of reset sequence _delay_ms(10); // 4.1 mS delay (min) lcd_write_4(lcd_FunctionSet8bit); // second part of reset sequence _delay_us(200); // 100uS delay (min) lcd_write_4(lcd_FunctionSet8bit); // third part of reset sequence _delay_us(200); // this delay is omitted in the data sheet lcd_write_4(lcd_functionSet4bit); // set 4-bit mode _delay_us(5); // 40uS delay (min) // Function Set instruction lcd_write_instruction_4d(lcd_functionSet4bit); // set mode, lines, and font _delay_us(40); // 40uS delay (min) // Clear Display instruction lcd_write_instruction_4d(lcd_clear); // clear display RAM _delay_ms(5); // 1.64 mS delay (min) // Display On/Off Control instruction lcd_write_instruction_4d(lcd_displayOn); // turn the display ON _delay_us(40); // 40uS delay (min) // ; Entry Mode Set instruction lcd_write_instruction_4d(lcd_entryMode); // set desired shift characteristics _delay_us(40); // 40uS delay (min) }
/* Name: lcd_init_4d Purpose: initialize the LCD module for a 4-bit data interface Entry: equates (LCD instructions) set up for the desired operation Exit: no parameters Notes: uses time delays rather than checking the busy flag */ void lcd_init_4d(void) { // configure the microprocessor pins for the data lines lcd_D7_ddr |= (1<<lcd_D7_bit); // 4 data lines - output lcd_D6_ddr |= (1<<lcd_D6_bit); lcd_D5_ddr |= (1<<lcd_D5_bit); lcd_D4_ddr |= (1<<lcd_D4_bit); // configure the microprocessor pins for the control lines lcd_E_ddr |= (1<<lcd_E_bit); // E line - output lcd_RS_ddr |= (1<<lcd_RS_bit); // RS line - output // lcd_RW_ddr |= (1<<lcd_RW_bit); // RS line - output // lcd_RW_port &= ~(1<<lcd_RW_bit); // Power-up delay _delay_ms(100); // initial 40 mSec delay // IMPORTANT - At this point the LCD module is in the 8-bit mode and it is expecting to receive // 8 bits of data, one bit on each of its 8 data lines, each time the 'E' line is pulsed. // // Since the LCD module is wired for the 4-bit mode, only the upper four data lines are connected to // the microprocessor and the lower four data lines are typically left open. Therefore, when // the 'E' line is pulsed, the LCD controller will read whatever data has been set up on the upper // four data lines and the lower four data lines will be high (due to internal pull-up circuitry). // // Fortunately the 'FunctionReset' instruction does not care about what is on the lower four bits so // this instruction can be sent on just the four available data lines and it will be interpreted // properly by the LCD controller. The 'lcd_write_4' subroutine will accomplish this if the // control lines have previously been configured properly. // Set up the RS and E lines for the 'lcd_write_4' subroutine. lcd_RS_port &= ~(1<<lcd_RS_bit); // select the Instruction Register (RS low) lcd_E_port &= ~(1<<lcd_E_bit); // make sure E is initially low // Reset the LCD controller lcd_write_4(lcd_FunctionReset); // first part of reset sequence _delay_ms(10); // 4.1 mS delay (min) lcd_write_4(lcd_FunctionReset); // second part of reset sequence _delay_us(200); // 100uS delay (min) lcd_write_4(lcd_FunctionReset); // third part of reset sequence _delay_us(200); // this delay is omitted in the data sheet // Preliminary Function Set instruction - used only to set the 4-bit mode. // The number of lines or the font cannot be set at this time since the controller is still in the // 8-bit mode, but the data transfer mode can be changed since this parameter is determined by one // of the upper four bits of the instruction. lcd_write_4(lcd_FunctionSet4bit); // set 4-bit mode _delay_us(80); // 40uS delay (min) // Function Set instruction lcd_write_instruction_4d(lcd_FunctionSet4bit); // set mode, lines, and font _delay_us(80); // 40uS delay (min) // The next three instructions are specified in the data sheet as part of the initialization routine, // so it is a good idea (but probably not necessary) to do them just as specified and then redo them // later if the application requires a different configuration. // Display On/Off Control instruction lcd_write_instruction_4d(lcd_DisplayOff); // turn display OFF _delay_us(80); // 40uS delay (min) // Clear Display instruction lcd_write_instruction_4d(lcd_Clear); // clear display RAM _delay_ms(4); // 1.64 mS delay (min) // ; Entry Mode Set instruction lcd_write_instruction_4d(lcd_EntryMode); // set desired shift characteristics _delay_us(80); // 40uS delay (min) // This is the end of the LCD controller initialization as specified in the data sheet, but the display // has been left in the OFF condition. This is a good time to turn the display back ON. // Display On/Off Control instruction lcd_write_instruction_4d(lcd_DisplayOn); // turn the display ON _delay_us(80); // 40uS delay (min) lcd_write_instruction_4d(lcd_Home); _delay_ms(10); }
/******************************* Main Program Code *************************/ int main(void) { // configure the microprocessor pins for the data lines lcd_D7_ddr |= (1<<lcd_D7_bit); // 4 data lines - output lcd_D6_ddr |= (1<<lcd_D6_bit); lcd_D5_ddr |= (1<<lcd_D5_bit); lcd_D4_ddr |= (1<<lcd_D4_bit); // configure the microprocessor pins for the control lines lcd_E_ddr |= (1<<lcd_E_bit); // E line - output lcd_RS_ddr |= (1<<lcd_RS_bit); // RS line - output // configure the microprocessor pins for the pushbutton pushbutton_ddr &= (1<<pushbutton_bit); pushbutton_port |= (1<<pushbutton_bit); // initialize adc ADMUX = ((1<<REFS0)|(1<<MUX2)|(1<<MUX0)); // Aref = Vcc, select ADC5 ADCSRA = ((1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<ADPS0)); // Prescaler div factor = 128 // initialize the LCD controller as determined by the defines (LCD instructions) lcd_init_4d(); // initialize the LCD display for a 4-bit interface // initialize TWI i2c_init(); // initialize thermometer therm_init(); // display the first line of information lcd_write_string_4d(disp_time); // set cursor to start of second line lcd_write_instruction_4d(lcd_setCursor | lcd_lineTwo); _delay_us(40); // 40 uS delay (min) // Code for interfacing with the serial connection char str[25]; int yy,mm,dd; sei(); // Enable global interrupts uart_init(); // Initialize the USART using baud rate 9600 uart_printstr(sdata); // Print a string from SRAM uart_printstr(fdata); // Print a string from FLASH getDate(&yy,&mm,&dd); // Get date from user sprintf(str,"Date: %d/%d/%d\n",yy,mm,dd); uart_printstr(str); // endless loop while(1) { uart_printstr(sdata); // Print a string from SRAM uart_printstr(fdata); // replace with check for button press function if(bit_is_clear(pushbutton_pin,pushbutton_bit)) { _delay_ms(100); if(bit_is_clear(pushbutton_pin,pushbutton_bit)) mode_new = (mode + 1) % 3; } if(mode_new != mode) { // clear lcd lcd_write_instruction_4d(lcd_clear); // display the first line of information // set cursor to start of first line lcd_write_instruction_4d(lcd_setCursor | lcd_lineOne); _delay_us(40); // 40 uS delay (min lcd_write_string_4d(disp_time); // set cursor to start of second line lcd_write_instruction_4d(lcd_setCursor | lcd_lineTwo); _delay_us(40); // 40 uS delay (min) if (mode_new == 0) { voltage = read_ADC(); lcd_write_string_4d(disp_volt); } else if (mode_new == 1) { frequency = 10 * freq_cntr_get_frequency(); lcd_write_string_4d(disp_freq); } else { temp_calcTemp(); // test thermometer lcd_write_string_4d(disp_temp); } } mode = mode_new; } return 0; }
/******************************* Main Program Code *************************/ int main(void) { // configure the microprocessor pins for the data lines lcd_D7_ddr |= (1<<lcd_D7_bit); // 4 data lines - output lcd_D6_ddr |= (1<<lcd_D6_bit); lcd_D5_ddr |= (1<<lcd_D5_bit); lcd_D4_ddr |= (1<<lcd_D4_bit); // configure the microprocessor pins for the control lines lcd_E_ddr |= (1<<lcd_E_bit); // E line - output lcd_RS_ddr |= (1<<lcd_RS_bit); // RS line - output // configure the microprocessor pins for the pushbutton pushbutton_ddr &= (1<<pushbutton_bit); pushbutton_port |= (1<<pushbutton_bit); // initialize adc ADMUX = ((1<<REFS0)|(1<<MUX2)|(1<<MUX0)); // Aref = Vcc, select ADC5 ADCSRA = ((1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<ADPS0)); // Prescaler div factor = 128 // initialize the LCD controller as determined by the defines (LCD instructions) lcd_init_4d(); // initialize the LCD display for a 4-bit interface // display the first line of information lcd_write_string_4d(disp_time); // set cursor to start of second line lcd_write_instruction_4d(lcd_setCursor | lcd_lineTwo); _delay_us(40); // 40 uS delay (min) if (mode == 0) { lcd_write_string_4d(disp_volt); } else if (mode == 1) { lcd_write_string_4d(disp_freq); } else { lcd_write_string_4d(disp_temp); } // Code for interfacing with the serial connection char str[25]; int yy,mm,dd; sei(); // Enable interrupts usart_init(); // Initialize the USART // Get the date, make a formatted string, and then // send via the USART. getDate(&yy,&mm,&dd); sprintf(str,"Date: %d/%d/%d\n",yy,mm,dd); usart_prints(str); // I2C code //i2c_init(); // initialize I2C library // endless loop while(1) { if(bit_is_clear(pushbutton_pin,pushbutton_bit)) { _delay_ms(10); if(bit_is_clear(pushbutton_pin,pushbutton_bit)) mode_new = (mode + 1) % 3; } if(mode_new != mode) { // set cursor to start of second line lcd_write_instruction_4d(lcd_setCursor | lcd_lineTwo); _delay_us(40); // 40 uS delay (min) if (mode_new == 0) { lcd_write_string_4d(disp_volt); } else if (mode_new == 1) { lcd_write_string_4d(disp_freq); } else { lcd_write_string_4d(disp_temp); } } mode = mode_new; } return 0; }