PDA

View Full Version : C18 và P18F458


nhnp0708
31-07-2007, 05:49 PM
Em viết LCD, dùng library xlcd.h nhưng không chạy.sau khi tham khảo và sửa chữa, cuối cùng đã chạy nhưng nó chạy loạn xạ.bác nào có viết và bị có thể chỉ em cách sửa không?

namqn
01-08-2007, 01:27 AM
Em viết LCD, dùng library xlcd.h nhưng không chạy.sau khi tham khảo và sửa chữa, cuối cùng đã chạy nhưng nó chạy loạn xạ.bác nào có viết và bị có thể chỉ em cách sửa không?
Bạn có viết code cho 3 hàm delay như thư viện đã yêu cầu hay không? Phần cứng của bạn có tương ứng với các khai báo trong xlcd.h hay không? Bạn sửa chữa như thế nào thì nên post lên, bạn nói chung chung như vậy thì sẽ nhận được câu trả lời chung chung.

Thân,

nhnp0708
01-08-2007, 04:16 AM
em xin lỗi, code đây ạ

xcld1.h

#ifndef __XLCD1_H
#define __XLCD1_H

/* PIC18 XLCD peripheral routines.
*
* >>>>>>>>>>> MODIFIED BY DWD FOR THE PICDEM 2 PLUS LCD SETUP
*
* Notes:
* - These libraries routines are written to support the
* Hitachi HD44780 LCD controller.
* - The user must define the following items:
* - The LCD interface type (4- or 8-bits)
* - If 4-bit mode
* - whether using the upper or lower nibble
* - The data port
* - The tris register for data port
* - The control signal ports and pins
* - The control signal port tris and pins
* - The user must provide three delay routines:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
*/

/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
/* #define BIT8 */

/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
/* #define UPPER */

/* DATA_PORT defines the port to which the LCD data lines are connected */
/* FOR PICDEM 2 PLUS - USE PORTD */

#define DATA_PORT PORTD
#define TRIS_DATA_PORT TRISD

/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
/* FOR PICDEM 2 PLUS - USE PORTA */
#define RW_PIN LATAbits.LATA2 /* PORT for RW */
#define TRIS_RW TRISAbits.TRISA2 /* TRIS for RW */
#define RS_PIN LATAbits.LATA3 /* PORT for RS */
#define TRIS_RS TRISAbits.TRISA3 /* TRIS for RS */
#define E_PIN LATAbits.LATA1 /* PORT for E */
#define TRIS_E TRISAbits.TRISA1 /* TRIS for E */
/* Adjustment of XLCD Violin*/


/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */

/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00010000 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00010100 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00011000 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00011100 /* Display shifts to the right */

/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters, single line */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#define LINES_5X10 0b00111100 /* 5x10 characters */

#define PARAM_SCLASS auto
#define MEM_MODEL far /* Change this to near for small memory model */

#endif


xlcd1.c

#include <delays.h>

//Delays Function
//10MHz PLL = 40MHz
void DelayFor18TCY(void)
{
Delay10TCYx(2);
}

void DelayPORXLCD(void)
{
Delay10KTCYx(15);
}

void DelayXLCD(void)
{
Delay10KTCYx(5);
}

//Prototype Function
void OpenXLCD(unsigned char lcdtype);
unsigned char BusyXLCD(void);
//void putrsXLCD(const rom char *buffer);
void putsXLCD(char *buffer);
unsigned char ReadAddrXLCD(void);
char ReadDataXLCD(void);
void SetCGRamAddr(unsigned char CGaddr);
void SetDDRamAddr(unsigned char DDaddr);
void WriteCmdXLCD(unsigned char cmd);
void WriteDataXLCD(char data);

/************************************************** ******************
* Function Name: OpenXLCD *
* Return Value: void *
* Parameters: lcdtype: sets the type of LCD (lines) *
* Description: This routine configures the LCD. Based on *
* the Hitachi HD44780 LCD controller. The *
* routine will configure the I/O pins of the *
* microcontroller, setup the LCD for 4- or *
* 8-bit mode and clear the display. The user *
* must provide three delay routines: *
* DelayFor18TCY() provides a 18 Tcy delay *
* DelayPORXLCD() provides at least 15ms delay *
* DelayXLCD() provides at least 5ms delay *
* *
* NOTE: I think there may be some problems with the BIT8 mode *
************************************************** ******************/
void OpenXLCD(unsigned char lcdtype)
{
/*********Violin*********/

// The data bits must be either a 8-bit port or the upper or
// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0xff;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT |= 0xf0;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low
// Delay for 15ms to allow for LCD Power on reset
DelayPORXLCD();

// Setup interface to LCD - First Init Nibble
#ifdef BIT8 // 8-bit mode interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit mode interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= 0b00100000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000010; // Function set cmd(4-bit interface)
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;

// Delay for at least 4.1ms
DelayXLCD();

// Second Init Nibble
#ifdef BIT8 // 8-bit mode interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit mode interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= 0b00100000; // Function set cmd(4-bit interface)
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= 0b00000010; // Function set cmd(4-bit interface)
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;

// Delay for at least 100us
DelayXLCD();
// Third Init Nibble
#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock the cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 4.1ms
DelayXLCD();
// Fourth Init Nibble (Word for 8 bit)
#ifdef BIT8 // 8-bit interface
DATA_PORT = 0b00110000; // Function set cmd(8-bit interface)
// Check lower Nibble for correct bits
// This Init sequence has some issues!
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00100000;
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Function set cmd(4-bit interface)
DATA_PORT |= 0b00000010;
#endif
#endif
E_PIN = 1; // Clock cmd in
DelayFor18TCY();
E_PIN = 0;
// Delay for at least 4.1ms
DelayXLCD();

#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0xff; // Make data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make data nibble input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make data nibble input
#endif
#endif
// From now on, send bytes - (2) nibbles for 4bit
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd

return;
}
/************************************************** ******************
* Function Name: BusyXLCD *
* Return Value: char: busy status of LCD controller *
* Parameters: void *
* Description: This routine reads the busy status of the *
* Hitachi HD44780 LCD controller. *
************************************************** ******************/
unsigned char BusyXLCD(void)
{
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock in the command
DelayFor18TCY();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if(DATA_PORT&0x80)
#else // Lower nibble interface
if(DATA_PORT&0x08)
#endif
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
}

/************************************************** ******************
* Function Name: putrsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
************************************************** ******************/
void putrsXLCD(const rom char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
Delay10KTCYx(10);
}
return;
}


/************************************************** ******************
* Function Name: putsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
************************************************** ******************/
void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
Delay10KTCYx(10);
}
return;
}

/************************************************** *******************
* Function Name: ReadAddrXLCD *
* Return Value: char: address from LCD controller *
* Parameters: void *
* Description: This routine reads an address byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The address*
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
************************************************** *******************/
unsigned char ReadAddrXLCD(void)
{
char data; // Holds the data retrieved from the LCD
#ifdef BIT8 // 8-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}

/************************************************** ******************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
************************************************** ******************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}

/************************************************** ******************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte to the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is written to the character generator RAM or*
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
************************************************** ******************/
void WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port

RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}

/************************************************** ******************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
************************************************** ******************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}

/************************************************** ******************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
************************************************** ******************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}

/************************************************** ******************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
************************************************** ******************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}


main

//Include
#include <p18f458.h>
#include <delays.h>
#include <xlcd1.h>
#include <xlcd1.c>

//Config
#pragma config OSC=HSPLL,WDT=OFF,LVP=OFF,CP0=OFF

unsigned char mybuff1 []="012345";
unsigned char mybuff2 []="abcdef";

//Define
#define line1 0x80
#define line2 0xC0
#define clear 0x01

//Prototype

//Global Variable

//Main Function
void main(void)
{
ADCON1=0x07; //make PORTA digital as control portpins are from PORTA
CMCON = 0x07;

TRISA = 0;
TRISD = 0;

OpenXLCD(FOUR_BIT&LINES_5X7);
while(BusyXLCD());
WriteCmdXLCD(DON&CURSOR_OFF&BLINK_OFF);
while(BusyXLCD());
WriteCmdXLCD(SHIFT_CUR_RIGHT);
while(BusyXLCD());
WriteCmdXLCD(clear);
while(BusyXLCD());
WriteCmdXLCD(line1);
while(BusyXLCD());
putsXLCD(mybuff1);
while(BusyXLCD());
WriteCmdXLCD(line2);
while(BusyXLCD());
putsXLCD(mybuff2);
}

nhnp0708
01-08-2007, 09:07 AM
cho em bổ sung trong xlcd1.c.Func putsXLCD và putrsXLCD.Nếu có hàm delay cuối với thời gian cao thì nó sẽ hiển thị đúng, nhưng lúc đầu nó sẽ chạy từ phải qua trái, sau đó sẽ chạy đúng theo ý mình là từ trái qua phải và quét liên tục
Ví dụ: hiện chữ "hello". nó sẽ chạy h,sau đó e, tiếp l, ... xong hello thì nó lại h, sau e... mặc dù trong hàm đó em không thấy nó hiển thị kiểu quét
còn nếu không có hàm delay hay delay quá nhỏ thì nó không hiển thị quét qua lại liên tục.
em sài mạch PIC Demo 2+ red

namqn
01-08-2007, 06:25 PM
cho em bổ sung trong xlcd1.c.Func putsXLCD và putrsXLCD.Nếu có hàm delay cuối với thời gian cao thì nó sẽ hiển thị đúng, nhưng lúc đầu nó sẽ chạy từ phải qua trái, sau đó sẽ chạy đúng theo ý mình là từ trái qua phải và quét liên tục
Ví dụ: hiện chữ "hello". nó sẽ chạy h,sau đó e, tiếp l, ... xong hello thì nó lại h, sau e... mặc dù trong hàm đó em không thấy nó hiển thị kiểu quét
còn nếu không có hàm delay hay delay quá nhỏ thì nó không hiển thị quét qua lại liên tục.
em sài mạch PIC Demo 2+ red
Với bộ điều khiển HD44780 (và các chip tương thích), sau khi ghi dữ liệu vào CGRAM hay DDRAM, bạn phải cho bộ điều khiển một khoảng thời gian để thực hiện lệnh, trước khi bạn xuất lệnh tiếp theo. Trong hai hàm bạn đã nêu, sau khi xuất dữ liệu ra LCD thì vòng lặp sẽ kiểm tra cờ busy, có nghĩa là vòng lặp có 2 lệnh được thực hiện nối tiếp nhau. Như vậy sau khi xuất dữ liệu vào DDRAM thì phải chờ bộ điều khiển thực hiện xong lệnh này mới được phép kiểm tra cờ busy. Theo datasheet của HD44780 thì khoảng thời gian này khoảng 40 us (ở tần số làm việc của HD44780 là 270 kHz). Do đó, nếu dùng các hàm delay của C18 thì phải đảm bảo delay tối thiểu là 400 chu kỳ máy, ở tốc độ thực thi lệnh là 10 MIPS.

Điều này giải thích việc bạn không có delay hay delay quá nhỏ thì LCD không hiển thị đúng.

Thân,

nhnp0708
02-08-2007, 09:59 AM
dạ.em đã thêm delay.và delay em thêm tốt nhất là 100ms ??? nhưng nó cứ quét liên tục , dùng proteus (mạch PIC2DEMO F18F452) thì nó im ru luôn. em gởi anh đoạn code và phim quay lại, không biết mô tả làm sao.

namqn
03-08-2007, 10:43 PM
dạ.em đã thêm delay.và delay em thêm tốt nhất là 100ms ??? nhưng nó cứ quét liên tục , dùng proteus (mạch PIC2DEMO F18F452) thì nó im ru luôn. em gởi anh đoạn code và phim quay lại, không biết mô tả làm sao.
Chương trình đang chạy đúng theo những gì bạn đã viết. Bạn viết code mà không có điểm dừng (chẳng hạn while (1) ; ), do đó code chạy đến dòng lệnh cuối cùng sẽ tiếp tục chạy những lệnh phía sau nó (thường là các ô mang giá trị 0xFFFF), sau một thời gian thì nó sẽ chạy đến vị trí cuối cùng của bộ nhớ chương trình và thanh ghi đếm chương trình sẽ quay về giá trị 0, và chương trình của bạn sẽ được chạy lại, gần giống như bạn reset chip.

Đoạn code của bạn nên có một lệnh SetDDRamAddr ở phía đầu, trước các lệnh xuất dữ liệu, thì có lẽ mới tránh được hiện tượng lần chạy đầu tiên thông điệp được hiển thị từ bên phải sang bên trái. Cũng có khả năng là một lỗi khác, tôi chưa xem thử sơ đồ nguyên lý của board PICDEM 2+.

Thân,

const_nos
26-03-2010, 10:46 AM
Chương trình đang chạy đúng theo những gì bạn đã viết. Bạn viết code mà không có điểm dừng (chẳng hạn while (1) ; ), do đó code chạy đến dòng lệnh cuối cùng sẽ tiếp tục chạy những lệnh phía sau nó (thường là các ô mang giá trị 0xFFFF), sau một thời gian thì nó sẽ chạy đến vị trí cuối cùng của bộ nhớ chương trình và thanh ghi đếm chương trình sẽ quay về giá trị 0, và chương trình của bạn sẽ được chạy lại, gần giống như bạn reset chip.

Đoạn code của bạn nên có một lệnh SetDDRamAddr ở phía đầu, trước các lệnh xuất dữ liệu, thì có lẽ mới tránh được hiện tượng lần chạy đầu tiên thông điệp được hiển thị từ bên phải sang bên trái. Cũng có khả năng là một lỗi khác, tôi chưa xem thử sơ đồ nguyên lý của board PICDEM 2+.

Thân,
chào anh Nam.
Tại sao em khai báo lại các chân Data post và chân dk cho lcd mà nó vẫn ko thay đổi gì nhỉ.( thay đổi xlcd.h rồi lưu lại trong MCC18\h luôn.hay copy vào project cung thế) anh giúp với.

sit_alone76816
27-03-2010, 12:00 AM
chào anh Nam.
Tại sao em khai báo lại các chân Data post và chân dk cho lcd mà nó vẫn ko thay đổi gì nhỉ.( thay đổi xlcd.h rồi lưu lại trong MCC18\h luôn.hay copy vào project cung thế) anh giúp với.

Đúng như những điều mình đang thắc mắc lâu nay, nhờ có topic này mà mình đã hiểu vì sao khi mình sửa các định nghĩa trong xlcd.h để dữ liệu xuất ra port khác, giả sử như sau:

#define DATA_PORT PORTD
#define TRIS_DATA_PORT TRISD

Thì khi mô phỏng chỉ thấy dữ liệu phát ra từ PORTB mà PORTD không thấy có tín hiệu hiệu gì hết.

theo mình thấy thì cần làm như sau:

1. Mở thư viện xlcd.h trong mcc18/h ra và thay đổi cho phù hợp với phần cứng của mình --> rồi lưu lại với 1 tên khác chẳng hạn xlcd1.h

2. Tạo 1 file .c hoặc mở notepad lên và lưu file thành .c . Nội dụng file này y như file xlcd1.c của nhnp0708 đã post ở trên

3. Khi tạo Project mới, thì ta add cả 2 file này vào trong Header file và Source file . Đồng thời trong Source code cần thêm hàm :
#include <xlcd1.h>
#include <xlcd1.c>

Như vậy là bạn đã thay đổi các định nghĩa phù hợp với phần cứng rồi đó.

Em post nếu có gì sai,mong các anh chị sửa cho !!! Chân thành cảm ơn !

sit_alone76816
27-03-2010, 12:07 AM
Em có đọc 1 tài liệu trên trang này
http://www.electronicfr.com/index.php/Microcontrolers-programing/Memo-and-code-exemples-for-C18-programing.html

Em thấy có chỉ cách rebuild lại thư viện như sau:

How to rebuild the library
• - Create a folder where you while build the C18 library and into copy the header (\mcc18\h\xlcd.h) and any source files (from \mcc18\src\traditional\pmc\XLCD\*)
• - Start MPLAB with a new project
• - Choose a appropriate device
• - Onto menu "Project->Build Options...->Project", select Build library target radio button in MPASM/C17/C18/Suite tab
• - Add all the source code files and the header file to the project.
• - Modify the pin assignment in the xlcd.h file and then build the project
• - Copy the p18fxxx.lib file from \mcc18\lib folder to the project folder (where xxx is the device type)
• - Run this command in a 'cmd' terminal window: for %%i in (*.o) do mplib /r .\p18fxxx.lib %%i . The modified functions will be changed in the library
To use this library, then you can:
Open you main project
• Copy the modifyed header file xlcd.h and the library p18fxxx.lib into the project folder
• Use only local reference of xlcd.h :
#include ".\xlcd.h"
• Remove the reference to the library in the Linker Scripts
• Add the local copy of p18fxxx.lib to the project


Em đọc còn vấp váp, không hiểu lắm, đặc biệt là từ chỗ " Run this command in a 'cmd' terminal window: for %%i in (*.o) do mplib /r .\p18fxxx.lib %%i "

Vậy có anh chị nào biết cách làm,xin chỉ cho em từng bước để Rebuild lại .

Chân thành cảm ơn nhiều !

sit_alone76816
27-03-2010, 02:07 PM
Em có 1 điều như sau, khi em có 1 biến kiểu interger giả sử như là int x=0x01; vậy thì làm sao em hiển thị số 27 đó ra LCD được.

Nếu em đưa x đó ra databus để vào lcd thì lcd không hiển thị cái gì hết. Còn nếu em chuyển nó ra dạng string bằng câu lệnh ltoa(x,y). Và đưa y ra databus để hiện thị thì tương ứng số 0x01 thì nó hiển thị là 16, 0x02 --> 32, 0x03 --> 48.

Vậy làm sao em có thể cho lcd hiển thị trực tiếp luôn, như là số 0x01 thì nó hiện thị là số 1 luôn ...

Mong sự giúp đỡ của các anh chị !!!

PVP
29-04-2010, 02:02 AM
mình cũng dính lỗi như bạn, ko cao nhân nào trợ giupa thía?