Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- ** lab19.c
- **
- ** Dislay a scrolling message to the LCD screen (assumed to be
- ** plugged in to port A (JA) and port C (JB bottom).
- **
- ** Program is incomplete - will need to be modified based
- ** on information learned in lab 19.
- */
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include "lcd.h"
- /* Function prototypes */
- /* Print Ready on start
- */
- char message[30] = "Ready, Connor Walker s42355362";
- void setLcd(void)
- {
- uint8_t i;
- /* Wait 20ms = 20000us */
- delay(20000);
- /* Make port bits connected to LCD control lines be outputs.
- ** RS bit is port C, bit 4
- ** R/W bit is port C, bit 5
- ** E bit is port C, bit 6
- */
- DDRG = 0x70; /* FIX THIS VALUE */
- /* Send "Function Set" instruction to specify the
- ** LCD panel configuration: 2 lines, 8 bit 5x8 chars
- */
- write_lcd_instruction(0x38); /* FIX THIS VALUE */
- /* Turn the display on */
- write_lcd_instruction(0x0C); /* FIX THIS VALUE */
- /* Clear the display */
- write_lcd_instruction(0x01); /* FIX THIS VALUE */
- /* Set data address to 0 (top left) */
- write_lcd_instruction(0x80); /* FIX THIS VALUE */
- /* Output the string - we iterate over the string
- ** until we reach the null character at the end. */
- for(i=0; message[i] != 0; i++) {
- write_lcd_data(message[i]);
- }
- /* Repeatedly scroll the message left - with a half
- ** second delay between each movement. We implement
- ** our half second delay as 10 x 50000us delays.
- */
- while(PINA == 0x00) {
- for(i=0; i< 10; i++) {
- delay(50000);
- }
- /* Issue command to scroll message left */
- write_lcd_instruction(0x18); /* FIX THIS VALUE */
- }
- }
- /* Delay for at least us microseconds.
- ** us is assumed to be greater than 0. max value is 65535
- ** We use timer/counter 3 to do this. We do not consider
- ** the overhead of calling the function or setting up
- ** the timer so if this function is called with very small
- ** values of us, the delay will not be that accurate.
- */
- void delay(uint16_t us)
- {
- /* Set up timer/counter 3. We will make the timer
- ** counter every microsecond (clk/8) and just set
- ** the target (output compare A) to be the given
- ** number of microseconds.
- ** We assume the timer is off (not counting) at
- ** the start of this function. We also assume
- ** that TCCR3A has its default value (0).
- */
- /* Set target */
- OCR3A = us;
- /* Set current count */
- TCNT3 = 0;
- /* Ensure the output compare A flag is clear. To do this
- ** we write a 1 to the OCF3A bit of ETIFR
- */
- ETIFR |= (1<<OCF3A);
- /* Set the timer going - normal mode, divide by 8 */
- TCCR3B = 0x02;
- /* Wait until the OCF3A bit of ETIFR is 1 */
- while((ETIFR & (1 << OCF3A)) == 0) {
- /* Do nothing */
- }
- /* We've reached the target - we stop the timer */
- TCCR3B = 0;
- return;
- }
- void write_lcd_instruction(uint8_t instn)
- {
- wait_if_lcd_busy();
- /* Write 0 to RS, R/W and E bits */
- PORTG = 0;
- /* Make port A an output port */
- DDRC = 0xFF;
- /* Write 1 to E bit */
- PORTG |= (1<<6);
- /* Write instn to port A */
- PORTC = instn;
- /* Delay - one more clock cycle, to ensure we have
- ** a write pulse width of at least 220ns. (Two clock
- ** cycles are 250ns.) */
- asm("nop"::);
- /* Write 0 to E bit */
- PORTG = 0;
- /* Make port A an input port */
- DDRC = 0;
- }
- void write_lcd_data(uint8_t data)
- {
- wait_if_lcd_busy();
- /* Write 0 to E bit, 1 to RS and 0 to R/W */
- PORTG = 0x10;
- /* Make port A be an output port */
- DDRC = 0xFF;
- /* Write 1 to E bit */
- PORTG |= (1<<6);
- /* Write data to port A */
- PORTC = data;
- /* Delay one more clock cycle */
- asm("nop"::);
- /* Write 0 to E bit */
- PORTG = 0x10;
- /* Write 0 to RS bit */
- PORTG = 0;
- /* Make port A be an input port */
- DDRC = 0;
- }
- void writeToLcd(char *writeLcd){
- for (int index=0; writeLcd[index] !=0; index++) {
- write_lcd_data(writeLcd[index]);
- }
- }
- uint8_t read_lcd_status(void)
- {
- uint8_t data;
- /* Write 0 to E bit, 1 to R/W, 0 to RS,
- ** i.e. 00100000
- */
- PORTG = 0x20;
- /* NOTE, port A is an input */
- /* Write 1 to E bit */
- PORTG |= (1<<6);
- /* Delay two clock cycles */
- asm("nop"::);
- asm("nop"::);
- /* Read the data */
- data = PINC;
- /* Write 0 to E bit */
- PORTG = 0x20;
- /* Write 0 to R/W bit */
- PORTG = 0;
- return data;
- }
- void wait_if_lcd_busy(void)
- {
- /* While bit 7 of the LCD status is 1 - just wait */
- while(read_lcd_status() & 0x80) {
- /* Do nothing */
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement