How to write a C Program to Displays "Hello World!" and "Pac-Man!" on LCD in C Programming Language ?
- #include <msp430.h>
- //#include "LCD.h"
- //#include "CLK.h"
- // Port 1 defines
- #define BTN BIT3
- #define DB4 BIT4
- #define DB5 BIT5
- #define DB6 BIT6
- #define DB7 BIT7
- // Port 2 defines
- #define RS BIT0
- #define RW BIT1
- #define E BIT2
- // CGRAM character defines
- #define PacMan 0x00
- #define Ghost 0x01
- #define Dot 0x02
- /*
- * main.c
- *
- * Title: Project 1 Hello World
- *
- * Authors: Daniel Hodges & Omar Arriaga
- *
- * Description: Displays "Hello World!" on LCD. Press BTN -> displays "Pac-Man!",
- * after 5 seconds displays a Pac-Man animation.
- *
- * I/O Ports: (x = no connect)
- *
- * MSP: P1.[0 1 2 3 4 5 6 7]
- * LCD: DB[x x x x 4 5 6 7]
- *
- * MSP: P2.[ 0 1 2 3 4 5 6 7]
- * LCD: RS R/W E x x x x x
- *
- */
- // function and variable declarations
- void lcd_wrt_cmd_nibble(unsigned short cmd);
- void lcd_wrt_data_nibble(unsigned short data);
- void lcd_init_seq_nibble();
- void lcd_clear_display();
- void lcd_set_DDRAM(unsigned short address);
- void lcd_create_characters();
- void lcd_display_HelloWorld();
- void lcd_display_PacMan();
- void lcd_animation_PacMan();
- void clk_set_16MHZ();
- void delay_clk_s(int sec);
- void delay_clk_ms(int ms);
- void delay_clk_us(int us);
- char toggle_message = 0x00;
- int main(void) {
- WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
- clk_set_16MHZ(); // set clock to 16MHz
- P1DIR |= (DB4 + DB5 + DB6 + DB7); // sets ports P1.4-7 to outputs
- P2DIR |= (RS + RW + E); // sets ports P2.0-2 to outputs (RS, R/W, E)
- P1IE |= BTN; // P1.3 interrupt enabled
- P1REN |= BTN; // add internal pullup to P1.3
- P1OUT |= BTN; // selects pullup for P1.3
- P1IES |= BTN; // P1.3 interrupt low to high enable
- P1IFG &= ~BTN; // P1.3 IFG cleared
- _enable_interrupts();
- lcd_init_seq_nibble(); // initialize sequence for LCD nibble mode (2-line mode, 5x8 dots, cursor off, increment, no shifting)
- lcd_create_characters(); // creates characters and stores into CGRAM
- // infinite loop waiting for button press to toggle between messages
- for(;;){
- if (toggle_message == 0x00){
- lcd_display_HelloWorld();
- toggle_message |= 0x02;
- }
- else if (toggle_message == 0x01){
- lcd_display_PacMan();
- delay_clk_s(5); // wait for 5s
- lcd_animation_PacMan();
- }
- else{
- }
- }
- }
- //write instruction to LCD in nibble mode (writes one nibble at a time)
- void lcd_wrt_cmd_nibble(unsigned short cmd){
- _disable_interrupts();
- P2OUT = 0x00; // clear RS, R/W, E
- P2OUT = 0x04; // set E
- P1OUT &= 0x0F;
- P1OUT |= (cmd << 4) & 0xF0; // write command data
- delay_clk_us(1); // wait for more than 220ns
- P2OUT = 0x00; // clear E
- delay_clk_us(80); // wait for more than 39us
- _enable_interrupts();
- }
- // write data to LCD in nibble mode (writes both nibbles at same time)
- void lcd_wrt_data_nibble(unsigned short data){
- _disable_interrupts();
- // write upper 4-bits
- P2OUT = 0x01; // Set RS; clear R/W, E
- P2OUT = 0x05; // set E and RS
- P1OUT &= 0x0F;
- P1OUT |= data & 0xF0; // write command data
- delay_clk_us(1); // wait for more than 220ns
- P2OUT = 0x01; // clear E; Set RS
- delay_clk_us(80); // wait for more than 39us
- // write lower 4-bits
- P2OUT = 0x01; // Set RS; clear R/W, E
- P2OUT = 0x05; // set E and RS
- P1OUT &= 0x0F;
- P1OUT |= (data << 4) & 0xF0; // write command data
- delay_clk_us(1); // wait for more than tw = 220ns
- P2OUT = 0x01; // clear E; Set RS
- delay_clk_us(80); // wait for more than 39us
- _enable_interrupts();
- }
- // initialize sequence for LCD nibble mode (2-line mode, 5x8 dots, cursor off, increment, no shifting)
- void lcd_init_seq_nibble(){
- _disable_interrupts();
- delay_clk_ms(60); // wait for more than 30ms after power on
- //function set w/ 2-line mode and 5x8 dots
- lcd_wrt_cmd_nibble(0b0010);
- lcd_wrt_cmd_nibble(0b0010);
- lcd_wrt_cmd_nibble(0b1100);
- // Display On/Off Control w/ cursor off
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b1100);
- // Display Clear
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b0001);
- delay_clk_ms(5); // wait for more than 1.53ms after function set
- // Entry Mode Set w/ increment and no shifting
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b0110);
- _enable_interrupts();
- }
- // clears lcd display
- void lcd_clear_display(){
- _disable_interrupts();
- // Display Clear
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b0001);
- delay_clk_ms(5);
- _enable_interrupts();
- }
- // sets DDRAM address for line 1
- void lcd_set_DDRAM_address(unsigned short address){
- lcd_wrt_cmd_nibble((BIT7 + (address & 0x70)) >> 4);
- lcd_wrt_cmd_nibble(address & 0x0F);
- }
- // creates characters and stores them in CGRAM
- void lcd_create_characters(){
- _disable_interrupts();
- // put PacMan into CGRAM address 0
- lcd_wrt_cmd_nibble(0b0100);
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00001110);
- lcd_wrt_data_nibble(0b00011011);
- lcd_wrt_data_nibble(0b00011110);
- lcd_wrt_data_nibble(0b00011100);
- lcd_wrt_data_nibble(0b00011110);
- lcd_wrt_data_nibble(0b00011111);
- lcd_wrt_data_nibble(0b00001110);
- // put Ghost into CGRAM address 1
- lcd_wrt_cmd_nibble(0b0100);
- lcd_wrt_cmd_nibble(0b1000);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00001110);
- lcd_wrt_data_nibble(0b00011111);
- lcd_wrt_data_nibble(0b00010101);
- lcd_wrt_data_nibble(0b00011111);
- lcd_wrt_data_nibble(0b00011111);
- lcd_wrt_data_nibble(0b00010101);
- lcd_wrt_data_nibble(0b00000000);
- // put Dot into CGRAM address 2
- lcd_wrt_cmd_nibble(0b0101);
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00001110);
- lcd_wrt_data_nibble(0b00001110);
- lcd_wrt_data_nibble(0b00001110);
- lcd_wrt_data_nibble(0b00000000);
- lcd_wrt_data_nibble(0b00000000);
- _enable_interrupts();
- }
- // displays "Hello World!" on display
- void lcd_display_HelloWorld(){
- _disable_interrupts();
- lcd_clear_display();
- lcd_set_DDRAM_address(0x04); // Set DDRAM address to 4 (line 1)
- lcd_wrt_data_nibble('H'); // Set DDRAM to H
- lcd_wrt_data_nibble('e'); // Set DDRAM to e
- lcd_wrt_data_nibble('l'); // Set DDRAM to l
- lcd_wrt_data_nibble('l'); // Set DDRAM to l
- lcd_wrt_data_nibble('o'); // Set DDRAM to o
- lcd_wrt_data_nibble(' '); // Set DDRAM to ' '
- lcd_wrt_data_nibble('W'); // Set DDRAM to W
- lcd_wrt_data_nibble('o'); // Set DDRAM to o
- lcd_wrt_data_nibble('r'); // Set DDRAM to r
- lcd_wrt_data_nibble('l'); // Set DDRAM to l
- lcd_wrt_data_nibble('d'); // Set DDRAM to d
- lcd_wrt_data_nibble('!'); // Set DDRAM to !
- _enable_interrupts();
- }
- // displays "Pac-Man!" on display
- void lcd_display_PacMan(){
- _disable_interrupts();
- lcd_clear_display();
- lcd_set_DDRAM_address(0x04); // Set DDRAM address to 4 (line 1)
- lcd_wrt_data_nibble('P'); // Set DDRAM to P
- lcd_wrt_data_nibble('a'); // Set DDRAM to a
- lcd_wrt_data_nibble('c'); // Set DDRAM to c
- lcd_wrt_data_nibble('-'); // Set DDRAM to -
- lcd_wrt_data_nibble('M'); // Set DDRAM to M
- lcd_wrt_data_nibble('a'); // Set DDRAM to a
- lcd_wrt_data_nibble('n'); // Set DDRAM to n
- lcd_wrt_data_nibble('!'); // Set DDRAM to !
- _enable_interrupts();
- }
- // displays a Pac-Man animation
- void lcd_animation_PacMan(){
- _disable_interrupts();
- lcd_clear_display();
- // Display On/Off Control w/ cursor on and blinking
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b1111);
- lcd_set_DDRAM_address(0x03); // Set DDRAM address to 4 (line 1)
- lcd_wrt_data_nibble(' '); // Set DDRAM to ' '
- delay_clk_s(1);
- lcd_wrt_data_nibble(PacMan); // Set DDRAM to PacMan
- delay_clk_ms(750);
- // for loop puts 10 dots in a row
- unsigned short i;
- for (i=0; i<9; i++){
- lcd_wrt_data_nibble(Dot); // Set DDRAM to Dot
- delay_clk_ms(750);
- }
- lcd_wrt_data_nibble(Ghost); // Set DDRAM to Ghost
- // Display On/Off Control w/ cursor off
- lcd_wrt_cmd_nibble(0b0000);
- lcd_wrt_cmd_nibble(0b1100);
- delay_clk_ms(750);
- // PacMan eats dots
- for (i=4; i<14; i++){
- lcd_set_DDRAM_address(i);
- lcd_wrt_data_nibble(' '); // Set DDRAM to ' '
- lcd_wrt_data_nibble(PacMan); // Set DDRAM to PacMan
- delay_clk_ms(500);
- }
- // PacMan hits ghost and dies (blinks on and off)
- for (;;){
- lcd_set_DDRAM_address(14);
- lcd_wrt_data_nibble(' '); // Set DDRAM to ' '
- delay_clk_ms(500);
- lcd_set_DDRAM_address(14);
- lcd_wrt_data_nibble(PacMan); // Set DDRAM to PacMan
- delay_clk_ms(500);
- }
- }
- // sets clock to 16MHz
- void clk_set_16MHZ(){
- //16Mhz
- if (CALBC1_16MHZ==0xFF) // If calibration constant erased
- {
- while(1); // do not load, trap CPU!!
- }
- DCOCTL = 0; // Select lowest DCOx and MODx settings
- BCSCTL1 = CALBC1_16MHZ; // Set range
- DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation
- }
- // delay clock by # of seconds
- void delay_clk_s(int sec){
- int i;
- for (i=0; i< sec; i++){
- _delay_cycles(16000000);
- }
- }
- // delay clock by # of milliseconds
- void delay_clk_ms(int ms){
- int i;
- for (i=0; i< ms; i++){
- _delay_cycles(16000);
- }
- }
- // delay clock by # of microseconds
- void delay_clk_us(int us){
- int i;
- for (i=0; i< us; i++){
- _delay_cycles(16);
- }
- }
- // Port 1 interrupt service routine
- #pragma vector=PORT1_VECTOR
- __interrupt void Port_1(void)
- {
- delay_clk_ms(100);
- toggle_message &= BIT0;
- toggle_message ^= BIT0;
- P1IFG &= ~BTN; // P1.3 IFG cleared
- delay_clk_ms(100);
- }
Learn More :
hello world