[Mong các cao thủ debug lỗi] v/v viết driver cho lcd

cenakhoa

em thích màu hồng
mình viết đoạn code này để dùng msp430 điều khiển lcd 16x2 thông qua spi mất 4 chân là 1.0 để chốt 74595, 1.1,1.2,1.4 lần lượt là master in,master out,clock. Một số code mình chỉnh sửa từ file lcd.c và lcd.h. Mình nghĩ là code đã đúng nhưng thực sự thì nó ko chạy (build ok !) mong các bạn vào xem tham khảo

file lcd.h
PHP:
void spi_a0_init(void);
void lcd_enter(void);
void lcd_init(void);
void lcd_put_byte(unsigned char rs, unsigned char b);
void lcd_putc(char c);
void lcd_gotoxy(unsigned char col, unsigned char row);
void lcd_puts(const char* s);
void lcd_clear();

//###############################################################################################################################

#define DON         0x0F  /* Display on      */
#define DOFF        0x0B  /* Display off     */
#define CURSOR_ON   0x0F  /* Cursor on       */
#define CURSOR_OFF  0x0D  /* Cursor off      */
#define CURSOR_RIGHT   0x14  /* Cursor right       */
#define CURSOR_LEFT    0x10  /* Cursor ledt       */
#define BLINK_ON    0x0F  /* Cursor Blink    */
#define BLINK_OFF   0x0E  /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT    0x04  /* Cursor shifts to the left   */
#define SHIFT_CUR_RIGHT   0x05  /* Cursor shifts to the right  */
#define SHIFT_DISP_LEFT   0x06  /* Display shifts to the left  */
#define SHIFT_DISP_RIGHT  0x07  /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT   0x2C  /* 4-bit Interface               */
#define EIGHT_BIT  0x3C  /* 8-bit Interface               */
#define LINE_5X7   0x30  /* 5x7 characters, single line   */
#define LINE_5X10  0x34  /* 5x10 characters               */
#define LINES_5X7  0x38  /* 5x7 characters, multiple line */

//###############################################################################################################################

typedef union _BYTE_VAL
{
    unsigned char Val;
    struct
    {
        unsigned char b0:1;
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
    } bits;
} BYTE_VAL;
Hàm main

PHP:
#include <msp430g2553.h>
#include "lcd.h"  // SU DUNG MODULE LCD

char LCD_RS,LCD_RW,LCD_EN,LCD_DATA4,LCD_DATA5,LCD_DATA6,LCD_DATA7,LCD_BYTE; // cac bien config lcd

//################################# CHUONG TRINH SETUP MODULE SPI A0 ##############################################################################################

void spi_a0_init(void)
{
	  WDTCTL = WDTPW + WDTHOLD;             		 // tat watch dog timer
	  P1OUT = 0x00;
	  P1DIR |= BIT0;                     			// port 1.0 dung de chot du lieu tren 74595
	  P1SEL = BIT1 + BIT2 + BIT4;					// port 1.1,1.2,1.4 mang chuc nang spi theo thu tu, master in, master out, clk
	  P1SEL2 = BIT1 + BIT2 + BIT4;
	  UCA0CTL0 |= UCCKPL + UCMSB  + UCMST + UCSYNC;  // spi 3-pin, 8-bit SPI master, msb first
	  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
	  UCA0BR0 |= 0x02;                          // divided by 2
	  UCA0BR1 = 0;                              //
	  UCA0MCTL = 0;                             // No modulation
	  UCA0CTL1 &= ~UCSWRST;                     // bat bo spi
}

//################################## CHUONG TRINH NHAP DU LIEU VAO 74595 #############################################################################################

void lcd_enter(void)
{
	LCD_BYTE=LCD_DATA7|(LCD_DATA6<<1)|(LCD_DATA5<<2)|(LCD_DATA4<<3)|(LCD_EN<<4)|(LCD_RW<<5)|(LCD_RS<<6);  // tong hop du lieu truyen di
	UCA0TXBUF = LCD_BYTE;  						// truyen du lieu
	while (UCA0TXIFG==0);              // USCI_A0 TX buffer ready? while (!(IFG2 & UCA0TXIFG));
	  P1OUT &= ~BIT0;                           // Now with SPI signals initialized,
		__delay_cycles(10000);
	  P1OUT |= BIT0;                            // reset slave
}


//################################### CHUONG TRINH KHOI DONG LCD ############################################################################################

void lcd_init(void)
{
	LCD_DATA7=0;			// cac chan data=0
	LCD_DATA6=0;
	LCD_DATA5=0;
	LCD_DATA4=0;
	LCD_EN=0;			//cac chan config =0
	LCD_RS=0;
	LCD_RW=0;
	lcd_enter();		//nhap du lieu vao spi
	__delay_cycles(100000); //delay 100ms

	lcd_put_byte(0,0x30);
	__delay_cycles(50000);
	lcd_put_byte(0,0x30);
	__delay_cycles(50000);
	lcd_put_byte(0,0x32);
	__delay_cycles(300000);

	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,FOUR_BIT & LINES_5X7);			// Set LCD type
	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,DOFF&CURSOR_OFF&BLINK_OFF);		// display off
	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,DON&CURSOR_OFF&BLINK_OFF);		// display on
	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,0x01);							// clear display and move cursor to home
	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,SHIFT_CUR_LEFT);				// cursor shift mode
	__delay_cycles(10000); //delay 10ms
	lcd_put_byte(0,0x01);							// clear display and move cursor to home
	__delay_cycles(10000); //delay 10ms
}

//################################ CHUONG TRINH DAT GIA TRI VAO LCD ###############################################################################################

void lcd_put_byte(unsigned char rs, unsigned char b)
{
	BYTE_VAL temp; // bien temp duoc dinh nghia truoc co 8 bit rieng biet, xem them trong file lcd.h

	if(rs) LCD_RS = 1;
	__delay_cycles(20);
	LCD_RW=0;
	__delay_cycles(20);
	LCD_EN=0;

	temp.Val = b;
	// send the high nibble
	LCD_DATA4 = temp.bits.b4;
	LCD_DATA5 = temp.bits.b5;
	LCD_DATA6 = temp.bits.b6;
	LCD_DATA7 = temp.bits.b7;
	lcd_enter();				// send 4 bit cao do lcd hoat dong o che do 4bit
	__delay_cycles(20);
	LCD_EN =  1;
	lcd_enter();
	LCD_EN =  0;
	lcd_enter();
	__delay_cycles(20);
	LCD_DATA4 = temp.bits.b0;
	LCD_DATA5 = temp.bits.b1;
	LCD_DATA6 = temp.bits.b2;
	LCD_DATA7 = temp.bits.b3;
	lcd_enter();              	//send 4 bit thap
	__delay_cycles(20);
	LCD_EN =  1;
	lcd_enter();
	__delay_cycles(20);
	LCD_EN = 0;
	lcd_enter();
}

//########################## DAT MOT KI TU LEN LCD #####################################################################################################

void lcd_putc(char c)
{
	switch(c)
	{
		case '\f':
			lcd_put_byte(0, 1);
			__delay_cycles(10000);
			break;
		case '\n':
			__delay_cycles(10000);
			break;
		default:
			if(isprint(c)) //KIEM TRA XEM C CO PHAI LA KI TU IN DUOC HAY KHONG
			{
				lcd_put_byte(1, c);
				__delay_cycles(10000);
			}
			break;
	}
}

//########################### DICH CHUYEN VI TRI CON TRO LCD ####################################################################################################

void lcd_gotoxy(unsigned char col, unsigned char row)
{
	unsigned char address;

	if(row!=0)
		address=0x40;
	else
		address=0;
	address += col;
	lcd_put_byte(0,0x80|address);
	__delay_cycles(10000);
}

//######################### GHI MOT CHUOI KI TU LEN LCD ######################################################################################################

void lcd_puts(const char* s)
{
	while(*s){
		lcd_putc(*s++);
	}
}

//############################ XOA LCD ###################################################################################################

void lcd_clear()
{
	lcd_put_byte(0,1);		// display off
	__delay_cycles(10000);
}

//######################## CHUONG TRINH CHINH #######################################################################################################

void main(void)
{
	spi_a0_init();     //khoi dong module spi
//	lcd_init();
//	lcd_puts("CENAKHOA");
	LCD_DATA7=1;			// cac chan data=0
	LCD_DATA6=0;
	LCD_DATA5=1;
	LCD_DATA4=0;
	LCD_EN=1;			//cac chan config =0
	LCD_RW=0;
	LCD_RS=1;
	lcd_enter();		//nhap du lieu vao spi
	while(1);

}
 

cenakhoa

em thích màu hồng
problem solved 99%

còn 1 bug nhỏ sẽ sửa lại càng sớm càng tốt

PHP:
#include <msp430g2553.h>
#include "lcd.h"  // SU DUNG MODULE LCD

char LCD_RS,LCD_RW,LCD_EN,LCD_DATA4,LCD_DATA5,LCD_DATA6,LCD_DATA7,LCD_BYTE; // cac bien config lcd

//################################# CHUONG TRINH SETUP MODULE SPI A0 ##############################################################################################

void spi_a0_init(void)
{
      WDTCTL = WDTPW + WDTHOLD;                      // tat watch dog timer
      P1OUT = 0x00;
      P1DIR |= BIT0;                                 // port 1.0 dung de chot du lieu tren 74595
      P1SEL = BIT1 + BIT2 + BIT4;                    // port 1.1,1.2,1.4 mang chuc nang spi theo thu tu, master in, master out, clk
      P1SEL2 = BIT1 + BIT2 + BIT4;
      UCA0CTL0 |= UCCKPL + UCMST + UCSYNC;  // spi 3-pin, 8-bit SPI master, lsb first
      UCA0CTL1 |= UCSSEL_2;                     // SMCLK
      UCA0BR0 |= 0x02;                          // divided by 2
      UCA0BR1 = 0;                              //
      UCA0MCTL = 0;                             // No modulation
      UCA0CTL1 &= ~UCSWRST;                     // bat bo spi

}

//################################## CHUONG TRINH NHAP DU LIEU VAO 74595 #############################################################################################

void lcd_enter(void)
{
    LCD_BYTE=LCD_DATA7|(LCD_DATA6<<1)|(LCD_DATA5<<2)|(LCD_DATA4<<3)|(LCD_EN<<4)|(LCD_RW<<5)|(LCD_RS<<6);  // tong hop du lieu truyen di
    UCA0TXBUF = LCD_BYTE;                          // truyen du lieu
    while (UCA0TXIFG==0);              // USCI_A0 TX buffer ready?
    P1OUT &= ~0x01;
    __delay_cycles(1250);
    P1OUT |= 0x01;
}


//################################### CHUONG TRINH KHOI DONG LCD ############################################################################################

void lcd_init(void)
{
    LCD_DATA7=0;            // cac chan data=0
    LCD_DATA6=0;
    LCD_DATA5=0;
    LCD_DATA4=0;
    LCD_EN=0;            //cac chan config =0
    LCD_RS=0;
    LCD_RW=0;
    lcd_enter();        //nhap du lieu vao spi
    __delay_cycles(100000); //delay 100ms

    lcd_put_byte(0,0x30);
    __delay_cycles(50000);
    lcd_put_byte(0,0x30);
    __delay_cycles(50000);
    lcd_put_byte(0,0x32);
    __delay_cycles(300000);

    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,FOUR_BIT & LINES_5X7);            // Set LCD type
    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,DOFF&CURSOR_OFF&BLINK_OFF);        // display off
    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,DON&CURSOR_OFF&BLINK_OFF);        // display on
    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,0x01);                            // clear display and move cursor to home
    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,SHIFT_CUR_LEFT);                // cursor shift mode
    __delay_cycles(10000); //delay 10ms
    lcd_put_byte(0,0x01);                            // clear display and move cursor to home
    __delay_cycles(10000); //delay 10ms
}

//################################ CHUONG TRINH DAT GIA TRI VAO LCD ###############################################################################################

void lcd_put_byte(unsigned char rs, unsigned char b)
{
    BYTE_VAL temp; // bien temp duoc dinh nghia truoc co 8 bit rieng biet, xem them trong file lcd.h

    if(rs) LCD_RS = 1;
    __delay_cycles(20);
    LCD_RW=0;
    __delay_cycles(20);
    LCD_EN=0;

    temp.Val = b;
    // send the high nibble
    LCD_DATA4 = temp.bits.b4;
    LCD_DATA5 = temp.bits.b5;
    LCD_DATA6 = temp.bits.b6;
    LCD_DATA7 = temp.bits.b7;
    lcd_enter();                // send 4 bit cao do lcd hoat dong o che do 4bit
    __delay_cycles(20);
    LCD_EN =  1;
    lcd_enter();
    LCD_EN =  0;
    lcd_enter();
    __delay_cycles(20);
    LCD_DATA4 = temp.bits.b0;
    LCD_DATA5 = temp.bits.b1;
    LCD_DATA6 = temp.bits.b2;
    LCD_DATA7 = temp.bits.b3;
    lcd_enter();                  //send 4 bit thap
    __delay_cycles(20);
    LCD_EN =  1;
    lcd_enter();
    __delay_cycles(20);
    LCD_EN = 0;
    lcd_enter();
}

//########################## DAT MOT KI TU LEN LCD #####################################################################################################

void lcd_putc(char c)
{
    switch(c)
    {
        case '\f':
            lcd_put_byte(0, 1);
            __delay_cycles(10000);
            break;
        case '\n':
            __delay_cycles(10000);
            break;
        default:
                lcd_put_byte(1, c);
                __delay_cycles(10000);
                break;
    }
}

//########################### DICH CHUYEN VI TRI CON TRO LCD ####################################################################################################

void lcd_gotoxy(unsigned char col, unsigned char row)
{
    unsigned char address;

    if(row!=0)
        address=0x40;
    else
        address=0;
    address += col;
    lcd_put_byte(0,0x80|address);
    __delay_cycles(10000);
}

//######################### GHI MOT CHUOI KI TU LEN LCD ######################################################################################################

void lcd_puts(const char* s)
{
    while(*s){
        lcd_putc(*s++);
    }
}

//############################ XOA LCD ###################################################################################################

void lcd_clear()
{
    lcd_put_byte(0,1);        // display off
    __delay_cycles(10000);
}

//######################## CHUONG TRINH CHINH #######################################################################################################

void main(void)
{
    spi_a0_init();     //khoi dong module spi
    lcd_init();
    lcd_puts("qwertyuifgh123");
    /*LCD_DATA7=1;            // cac chan data=0
    LCD_DATA6=0;
    LCD_DATA5=1;
    LCD_DATA4=0;
    LCD_EN=1;            //cac chan config =0
    LCD_RW=0;
    LCD_RS=1;
    lcd_enter();        //nhap du lieu vao spi*/
    while(1);

}
 
Top