Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*********************************************************************************************
- * *
- * Nigel Johnson's Grand Universal Master Program (GUMP) for the FRDM-K64F board to *
- * show you how to access the LCD screen on the K64F board using 4-bit transfers *
- * *
- * This is version 2.0 dated 2017 03 05 *
- * *
- **********************************************************************************************
- Edit history
- 2017 02 22 NWJ converted to use on K64F
- 2011 01 25 NWJ changes and adds
- 2009 10 29 NWJ original program
- This program does the following:
- Initialises the LCD screen
- Prints a welcome screen
- Outputs the data to the screen in hex format (each byte is two characters)
- This may be useful for any future projects, such as the personal assignment for this course and Capstone!
- LCD connections:
- The LCD is connected to the K64F as follows:
- PTC7 goes to LCD DB4, pin 11 of the LCD )
- PTC8 goes to LCD DB5, pin 12 of the LCD )
- PTC9 goes to LCD DB6, pin 13 of the LCD )
- PTC10 goes to LCD DB7, pin 14 of the LCD ) I know these assignments mean data will have to be shifted
- ) before storing, but that is life in the real world!
- PTC0 goes to LCD RS, pin 4 of the LCD )
- PTC2 goes to LCD E, pin 6 of the LCD )
- PTC1 goes to LCD R/-W, pin 5 of the LCD )
- ***********************************************************************************************/
- #include "MK64F12.h"
- #include "GUMP.h"
- #include "stdlib.h"
- #include "stdio.h"
- #include "String.h"
- #define INIT 1 // arguments for the lcd routine
- #define UPDATE 2 //
- char line1[]="";
- char line2[]="";
- #pragma section m_data
- char RAM_line1[16];
- char RAM_line2[16];
- unsigned char a[16];
- char *pointer;
- char temp;
- int char_Pos; // where we are in LCD line
- int dest;
- int i;
- void main(void)
- {
- while(1)
- {
- delay(2000); // Delay ~15-20 mS from power-up based on 8us delay
- pointer=strncpy(&RAM_line1[0],&line1[0],16); //Before we start, we copy down the intro screen from
- pointer=strncpy(&RAM_line2[0],&line2[0],16); // flash into the RAM buffer used for the LCD
- initPorts();
- lcd(INIT); // initialise the lcd for 4 line, 4 bit mode
- while(1)
- {
- randomise(); // create a 16 byte buffer with random data
- delay(10000); // this time way beyond spec but it seems to need it
- lcd(UPDATE); // output 4 lines of text
- delay(1000000); // give the user a chance to see turn-on banner
- lcd(UPDATE); // output 4 lines of text
- delay(1250); // wait 10 ms
- bubble(&a[0],16); // do a bubble sort
- ascii(); // copy the numbers and convert to ascii
- while(1){}; // Wait forever to leave display static after bubble finishes
- }
- }
- }
- /********************************************************************************
- *
- * LCD DRIVER
- *
- * All lcd contact done through this function.
- *
- * Calling convention:
- *
- * Type = 1, initialise the lcd for 4 line mode, 4 bit transfers
- * Type = 2, output 4 lines of text from buffer lline1,line2 etc
- *
- *************************************************************************************
- All accesses to the LCD must be done in pairs since we are in 4 bit mode and
- only the top 4 bits are connected to the LCD and used
- so: nothing can be in the lower nibble
- and: if we don't do it in pairs we will always be out by half a byte in following
- commands since the LCD will be waiting for a second write cycle
- *************************************************************************************/
- void lcd(int type)
- {
- if (type==INIT)
- {
- GPIOC_PCOR |= (1 << 0); // Clear RS to put in command mode
- GPIOC_PCOR |= (1 << 1); // drop R/W low
- e();
- /***************************************************************************
- *
- * First of all, send 0x30 three time to ensure chip is reset per data sheet
- *
- * The LCD based on the HD44780 will power up into 8 bit mode but
- * only the most significant bits of the device are connected to the K64F.
- * Fortunately, the reset and main functions are controlled in the upper bits
- *
- ***************************************************************************/
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- GPIOC_PSOR |= (0x03 << 7); // Send command $03
- e();
- delay(513); // Delay 4.1 ms per data sheet
- GPIOC_PSOR |= (0x03 << 7); // Send command $03 again
- e();
- delay(13); // Delay 100 us per data sheet
- GPIOC_PSOR |= (0x03 << 7); // Send command $03 again
- e();
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- delay(20);
- /**************************************************************************************************
- *
- * Then send 0x20. This is the last instruction that will be sent with the HD44780 in 8-bit mode.
- * This command will switch it into 4-bit mode. From here on, all bytes must be sent as 4-bit
- * nibbles, with an E pulse in between and after them,left shifted into the upper bits if necessary.
- *
- **************************************************************************************************/
- GPIOC_PSOR |= (0x02 << 7); // Command is 0x02 each nibble shifted left 7 bits
- e();
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- delay(5); // Delay 40us (data sheet says 37us)
- /**************************************************************************************************
- *
- * Next send the command 0x28 which sets the display on and puts it into 2 line mode
- *
- **************************************************************************************************/
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- GPIOC_PSOR |= (0x02 << 7); //
- e(); // Command is 0x28 each nibble shifted left 7 bits (function set)
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- GPIOC_PSOR |= (0x08 << 7); //
- e(); // Command is 0x28 each nibble shifted left 7 bits (function set)
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- /**************************************************************************************************
- *
- * Next send the command 0x0F which sets the display on and gives blinking cursor
- *
- **************************************************************************************************/
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- e();
- GPIOC_PSOR |= (0x0F << 7); //
- e(); // Command is 0x0F each nibble shifted left 7 bits (function set)
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- /*************************************************************************************************
- *
- * Then send 0x01 to Clear display and set cursor to home position
- *
- **************************************************************************************************/
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- e();
- GPIOC_PSOR |= (0x01 << 7); // Clear display and set cursor to location 0
- e(); // Command is 0x01 each nibble shifted left 7 bits (display on)
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- delay(1250); // Delay 10ms per data sheet
- /*************************************************************************************************
- *
- * Next send command 0x0F
- *
- ************************************************************************************************/
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- e();
- GPIOC_PSOR |= (0x0F << 7); //
- e();
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- /*************************************************************************************************
- *
- * Now we set the Register Select line to go back into data mode. Anything sent from here on
- * will be 'painted' as a character on the display
- *
- *************************************************************************************************/
- GPIOC_PSOR |= (1 << 0); // Set RS to put in data mode
- /*************************************************************************************************/
- delay(200);
- }
- else if (type ==UPDATE)
- {
- out_Line(1);
- out_Line(2);
- }
- return;
- }
- /*********************************************************************************/
- void initPorts()
- {
- SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; //Enable Port C Clock Gate Control
- // PCR bit definitions:
- // 31 30 29 28 26 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // <=Reserved R/O=====> ISF<Reserved=><===IRQC===> LK <=Reserved=><=MUX==><=R=>DSE ODE PFE Res SRE PE PS
- //
- // R = reserved
- // R/O = Read Only
- // ISF = interrupt status flag
- // IRQC = interrupt configuration
- // LK = Lock bits 15:0 cannot be changed until next reset
- // MUX = 000 Disabled
- // MUX = 001 Alt 0 (GPIO)
- // MUX = 010 to 111 Chip-specific
- // DSE = drive strength enable, 1= High drive strength
- // OPE = Open Drain Enable - removes upper driver transistor for pin
- // PFE = Passive Filter Enable
- // SRE = Slew Rate Enable
- // PE = Pull Enable - connects pull-up or pull-down resistor internally
- // PS = Pull Select - a 1 gives pull-up if PE is selected
- PORTC_PCR0 = 0x0100; // PORTC bit 0 is connected to LCD RS pin 4 : GPIO
- PORTC_PCR1 = 0x0100; // PORTC bit 1 is connected to LCD R/-W pin 5 : GPIO
- PORTC_PCR2 = 0x0100; // PORTC bit 2 is connected to LCD E pin 6 : GPIO
- PORTC_PCR3 = 0x0100; // PORTC bit 3 is connected to trigger for logic analyser : GPIO
- PORTC_PCR7 = 0x0100; // PORTC bit 7 is connected to LCD DB4 pin 11 : GPIO
- PORTC_PCR8 = 0x0100; // PORTC bit 8 is connected to LCD DB5 pin 12 : GPIO
- PORTC_PCR9 = 0x0100; // PORTC bit 9 is connected to LCD DB6 pin 13 : GPIO
- PORTC_PCR10 = 0x0100; // PORTC bit 10 is connected to LCD DB7 pin 14 : GPIO
- //
- // Bit map for general registers
- // 31 30 29 38 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1 | 8 4 2 1
- //
- GPIOC_PDDR |= 0x078F; // Setting bits 10, 9, 8, 7, 3, 2, 1, 0 of Port C as Outputs
- return;
- }
- /*********************************************************************************/
- void e(void) // send the E pulse to the lcd
- {
- delay(20);
- GPIOC_PSOR |= (1 << 2);
- delay(20);
- GPIOC_PCOR |= (1 << 2);
- delay(20);
- return; // you have to write this!
- }
- /*********************************************************************************/
- void delay(int microsecs)
- {
- for(i = 0; i < microsecs; i++)
- {
- __asm("NOP");
- }
- return; // you have to write this!
- }
- /*********************************************************************************/
- void out_Line(int line)
- {
- switch (line)
- {
- case 1:
- GPIOC_PCOR |= (1 << 0); // access control register
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- GPIOC_PSOR |= (0x08 << 7); // Command is 0x80 to move to line 1 column 0 shifted left 7 places
- e(); // This sends the upper nibble (0x8)
- GPIOC_PCOR |= (0xFF << 7); // Remove output just sent
- e(); // This sends the lower nibble (0x0)
- GPIOC_PSOR |= (1 << 0); // access data register, ready to send characters
- delay(20);
- pointer=&RAM_line1[0];
- goto common;
- case 2:
- GPIOC_PCOR |= (1 << 0); // access control register
- GPIOC_PSOR |= (0x0C << 7);
- e();
- GPIOC_PCOR |= (0x0F << 7); // Command is 0xC0 to move to line 1 column 0 shifted left 7 places
- e();
- GPIOC_PSOR |= (1 << 0); // access data register
- delay(20);
- pointer=&RAM_line2[0];
- goto common;
- common:
- for (char_Pos=0;char_Pos<16;char_Pos++)
- {
- // Process the byte to store one nibble at a time and write into data bits 7-4 of the LCD which are
- // connected to PORTC bits 10 - 7
- //
- temp = pointer[char_Pos]; // Get byte to process first nibble
- temp &= 0xF0; // Get the upper nibble only
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- GPIOC_PSOR |= (temp << 3); // MSB already in bit 7, therefore only needs to be shifted 3 to left
- e(); // Note: Temp is an 8 bit value, and we only need to output 4 bits of it
- // Upper nibble will go into bits 10 - 7, lower nibble will go into bit 6-3
- // Normally we would not interfere with the wrong bits, but we know that these
- // bits are not use in this register. This is lazy programming and may lead to
- // bugs later. We must AND off the lower nibble before writing to PORTC
- GPIOC_PCOR |= (0x0F << 7); //delete nibble
- // Now process the second nibble
- temp = pointer[char_Pos]; // Get byte to process second nibble
- GPIOC_PCOR |= (0x0F << 7); // Clear all bits in the data register
- temp <<= 4;
- temp &= 0xF0; // Make sure we only have the upper nibble
- GPIOC_PSOR |= (temp << 3); // MSB already in bit 7, therefore only needs to be shifted 3 to left
- e();
- GPIOC_PCOR |= (0x0F << 7); // delete nibble
- delay(20); // manual says wait 40us after sending a character
- // 160 used as an experiment when that didn't work!
- }
- }
- }
- /*********************************************************************************/
- void bubble(unsigned char a[],int n) // you have to write this!
- {
- for(int i = 0; i < (n-1); i++)
- {
- for(int t = 0; t < (n - t - 1); t++)
- {
- if(a[t] > a[t+1])
- {
- swap(a[t], a[t+1]);
- }
- ascii();
- lcd(UPDATE);
- }
- }
- }
- /*********************************************************************************/
- void swap (unsigned char *px, unsigned char *py) // you have to write this! - it is called from bubble
- {
- char temp = &px;
- px = &py;
- py = temp;
- }
- /*********************************************************************************/
- void randomise(void) // you have to write this!
- {
- char r = 0;
- for(int g = 0; i < 16; g++)
- {
- a[g] = rand();
- }
- }
- /*********************************************************************************/
- void ascii(void) // this function takes the binary values in the 16 bytes
- // of a[], converts each byte into two right-justified
- // nibbles, converts them into ASCII, and stores them
- // in the 2 x 16 LCD buffer
- {
- int lo,hi;
- for(i=0;i<8;i+2) // process data for first line of lcd
- {
- lo = a[i] & 0x0f;
- hi = (a[i] >> 4) & 0x0f;
- line1[i]= lo;
- line1[i+1] = hi;
- lcd(UPDATE);
- }
- for(i=8;i<16;i+2) // process data for second line of lcd
- {
- lo = a[i] & 0x0f;
- hi = (a[i] >> 4) & 0x0f;
- line2[i] = lo;
- line2[i+1] = hi;
- lcd(UPDATE);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement