các cao thủ giúp em với, em thử giao tiếp chế độ 4 bit theo cách anh Bắc bảo nưng trên con 16f877a, nhưng mãi ko chạy. các cao thủ xin giúp em với:
Code:
#include<pic.h>
__CONFIG(HS & PWRTEN & BOREN & LVPDIS & WDTDIS );
/*======================================================================================
Define LCD_PORT
======================================================================================*/
#define LCD_DATA_PORT PORTB // Port on which LCD data lines are connected
#define LCD_TRIS_PORT TRISB // Need to specify the corresponding TRIS
#define LCD_RS RB1
#define LCD_RW RB2
#define LCD_E RB0
#define LCD_TRIS_RS TRISB1
#define LCD_TRIS_RW TRISB2
#define LCD_TRIS_E TRISB0
#define LCD_TRIS_DATAMASK (0b11110000) // Define the bitmask used to read/write the data bits
#define LCD_D4_BIT 4
#define LCD_FUNCTION_SET ((unsigned char)(0b00101000))
#define LCD_DISPLAY_CONTROL ((unsigned char)(0b00001100))
#define LCD_ENTRY_MODE ((unsigned char)(0b00000110))
#define LCD_COMMAND_CLEAR ((unsigned char)(0x01)) //1.53 ms // Clear screen, home cursor, unshift display
#define LCD_COMMAND_HOME ((unsigned char)(0x02)) //1.53 ms // Home cursor, unshift display
// ==================== Declare some functions
void delay_us (unsigned char us);
void delay_ms(unsigned char ms);
unsigned char LCD_getByte (void);
void LCD_PrByte (unsigned char c);
//void LCD_Command(unsigned char c);
void LCD_PrChar (unsigned char c);
//void LCD_gotoXY(unsigned char row, unsigned char col);
//unsigned char LCD_getChar (void); // Read character at cursor
void LCD_Init(void);
void LCD_PrString (const char *message);
void lcd_putnybble (unsigned char c);
/*=====================================================================================
Main function
=====================================================================================*/
void main()
{
TRISB = 0x00;
PORTB = 0xFF;
LCD_Init();
LCD_PrString("I Love You");
while(1);
}
//==========================================================================================
void delay_us (unsigned char us){
while(us--){
asm("nop");
asm("nop");
};
}
//==========================================================================================
void delay_ms(unsigned char ms){
unsigned char i, j;
while(ms--){
for (i = 0; i < 20; i++)
for (j = 0; j < 100; j++)
asm("nop");
};
}
//==========================================================================================
void LCD_Init(void)
{
LCD_TRIS_PORT &= ~LCD_TRIS_DATAMASK; // Set data bus to output
LCD_TRIS_E = 0;
LCD_TRIS_RW = 0;
LCD_TRIS_RS = 0;
LCD_E = 0 ;
LCD_RS = 0;
LCD_RW = 0;
delay_ms (15); // Tao tre 15ms cho LCD khoi dong
lcd_putnybble(0b0010); // Set LCD into 4-bit mode
delay_ms(10);
lcd_putnybble(0b0010);
//delay_ms(10);
LCD_PrByte (LCD_FUNCTION_SET); //Function set ; DL = 0(4 bits) , N = 1 (2 lines), F = 0 (5x8 dots)
LCD_PrByte (LCD_DISPLAY_CONTROL); // Display on/off control
LCD_PrByte (LCD_ENTRY_MODE); // Entry mode set
LCD_PrByte(LCD_COMMAND_CLEAR);
delay_ms (2);
LCD_PrByte(LCD_COMMAND_HOME);
delay_ms (2);
}
//====================================================================================================
void LCD_PrByte (unsigned char c)
{
unsigned char RS_Status; // Write byte to port in current RS mode
RS_Status = LCD_RS; // Get old pin state
LCD_RS = 0; // Force into command mode to read state
while (LCD_getByte () & 0x80); // Wait for read state
if (RS_Status)
LCD_RS = 1; // Restore RS to old state
delay_us (1);
LCD_RW = 0; // Set to write mode
delay_us (1);
lcd_putnybble (c >> 4); // Send the character out
lcd_putnybble (c);
}
//================================================================================================
unsigned char LCD_getByte (void)
{
unsigned char retval; // Return value
unsigned char highbits ;
LCD_TRIS_PORT = LCD_TRIS_DATAMASK; // Set port to read mode for data pins
LCD_RW = 1; // Tell LCD we want to read
delay_ms (1);
LCD_E = 1;
highbits = (((LCD_DATA_PORT & LCD_TRIS_DATAMASK) >> LCD_D4_BIT) << 4);// Grab high bits and shift to right place
LCD_E = 0;
delay_ms (1);
LCD_E = 1;
delay_ms (1);
retval = ((LCD_DATA_PORT & LCD_TRIS_DATAMASK) >> LCD_D4_BIT); // Grab low bits
LCD_E = 0;
retval |= highbits;
LCD_TRIS_PORT =0x00;//&= ~LCD_TRIS_DATAMASK; // Set port back to output mode
return (retval);
}
//====================================================================================================
void lcd_putnybble (unsigned char c) // Write nybble to port in current RS mode
{
c = c << LCD_D4_BIT; // Shift over to correct bit column
c &= LCD_TRIS_DATAMASK; // Remove any extraneous bits
LCD_DATA_PORT = (LCD_DATA_PORT & ~LCD_TRIS_DATAMASK) | c; // Write data bits to port
delay_us (1);
LCD_E = 1; // Start to write it
delay_us (1);
LCD_E = 0; // Finish write cycle
}
//============================================================================
void LCD_PrString (const char *message){ // Write message to LCD (C string type)
while (*message) // Look for end of string
LCD_PrChar (*message++); // Show and bump
}
//============================================================================
/*Ham yeu cau goi du lieu hien thi len LCD*/
void LCD_PrChar (unsigned char c){ // Write character to LCD
LCD_RS = 1 ;
LCD_PrByte(c);
}
//============================================================================