加我模型论坛

标题: c8051的LCD1602液晶驱动程序范例很有参考价值 [打印本页]

作者: joyrus    时间: 2012-7-9 00:36
标题: c8051的LCD1602液晶驱动程序范例很有参考价值
本帖最后由 joyrus 于 2012-7-9 12:04 编辑

C/C++ code

//==============================================//
// Filename:   C8051f320_SMC1602A_Display.c     //
//                                              //
// Prozessor:  C8051f320                        //
// Compiler:   Keil C51 7.06                    //
//                                              //
// Author:     Paul.Jia                         //
// QQ:         79974439                         //
// Copyright:  MKL PSC TSD                      //
//==============================================//

//================================================
//1. SYSCLK is unlimited here
//2. Display by SMC1602A
//
//Use 3 ports for control
//Use 8 ports for data communications
//And initialize them right in the Main
//
//Need ms delay function from the Main
//    extern void delay_ms(unsigned short ms);
//
//Need initialize before use the diaplay function
//    void LCMInit(void);
//
//Export these 2 function
//    void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
//    void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
//================================================

//----------------------------
// Include Files
//----------------------------

#include <c8051f320.h>
#include <intrins.h>



//----------------------------
// Global Constants
//----------------------------

// Define control ports and data ports
// P0.5 - digital    push-pull    (1602)RS
// P0.6 - digital    push-pull    (1602)RW
// P0.7 - digital    push-pull    (1602)E
// P1.x - digital    push-pull    (1602)DATA
// Have to initalize these ports in the Main
//
sbit RS1602 = P0 ^ 5;                             // Register select signal port
sbit RW1602 = P0 ^ 6;                             // Data read/write port
sbit E1602  = P0 ^ 7;                             // Enable signal port
#define DATA1602 P1                               // Data port

// Define macro definition basic the selected ports
//
#define W_D_IN   P1MDOUT &= 0x00                  // Change Data port to open-drain
#define W_D_OUT  P1MDOUT |= 0xFF                  // Change Data port to push-pull

// Define device busy flag
//
#define Busy     0x80



//----------------------------
// Function Prototypes
//----------------------------

// Write data to SMC1602A
//
void WriteDataLCM(unsigned char WDLCM);

// Write command to SMC1602A
//
void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC);

// Read data from SMC1602A
//
unsigned char ReadDataLCM(void);

// Read command from SMC602A
//
unsigned char ReadStatusLCM(void);

// Initalize SMC1602A
//
void LCMInit(void);

// Display a char at the specified position
//
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);

// Display a string at the specified position
//
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);

// Call a extern ms delay function
//
extern void delay_ms(unsigned short ms);



//----------------------------
// Subroutines
//----------------------------

//-----------------Write Data---------------------
void WriteDataLCM(unsigned char WDLCM)
//------------------------------------------------
{
    ReadStatusLCM();          // Detect Busy
    W_D_OUT;                    // Change Data port to push-pull
    DATA1602 = WDLCM;     // Write data
    RS1602 = 1;                  // LCM_RS = 1;
    RW1602 = 0;                 // LCM_RW = 0;
    E1602 = 0;     // LCM_E = 0; If SYSCLK is high, add a small delay into here
    delay_ms(4);
    E1602 = 1;                    // LCM_E = 1;
}

//----------------Write Command-------------------
void WriteCommandLCM(unsigned char WCLCM, unsigned char BusyC)
//------------------------------------------------
{
    if(BusyC)                      // Decide if detect Busy from parameter
    {
        ReadStatusLCM();         // Detect Busy
    }
    W_D_OUT;                  // Change Data port to push-pull
    DATA1602 = WCLCM;     // Write command
    RS1602 = 0;                // LCM_RS = 0;
    RW1602 = 0;               // LCM_RW = 0;
    E1602 = 0;                  // LCM_E = 0; If SYSCLK is high, add a small delay into here
    delay_ms(4);
    E1602 = 1;                  // LCM_E = 1;
}

/*
//------------------Read Data---------------------
unsigned char ReadDataLCM(void)
//------------------------------------------------
{
    RS1602 = 1;          // LCM_RS = 1;
    RW1602 = 1;        // LCM_RW = 1;
    E1602 = 0;           // LCM_E = 0; If SYSCLK is high, add a small delay into here
    delay_ms(4);
    E1602 = 1;           // LCM_E = 1;
    W_D_IN;              // Change Data port to open-drain
    return DATA1602; // Return data
}
*/

//-----------------Read Command-------------------
unsigned char ReadStatusLCM(void)
//------------------------------------------------
{
    W_D_IN;          // Change Data port to open-drain
    RS1602 = 0;     // LCM_RS = 0;
    RW1602 = 1;    // LCM_RW = 1;
    E1602 = 0;      // LCM_E = 0; If SYSCLK is high, add a small delay into here
    delay_ms(4);
    E1602 = 1;        // LCM_E = 1;
    while(DATA1602 & Busy);    // Detect Busy
    return DATA1602;            // Return data
}

//------------------Initalize---------------------
void LCMInit(void)
//------------------------------------------------
{
    DATA1602 = 0;
      WriteCommandLCM(0x38, 0);      // Set display mode 3 times, no detect Busy
    delay_ms(5);
    WriteCommandLCM(0x38, 0);
    delay_ms(5);
    WriteCommandLCM(0x38, 0);
    delay_ms(5);
    // Keep above code

    WriteCommandLCM(0x38, 1);   // Set display mode(8 bits, 2 rows, 5x7), begin detect Busy everytime
    WriteCommandLCM(0x08, 1);    // Close display
    WriteCommandLCM(0x01, 1);    // Clear screen
    WriteCommandLCM(0x06, 1);    // Show the position of cursor move
    WriteCommandLCM(0x0C, 1);    // Show boot-strap cursor setting
    WriteCommandLCM(0x80, 1);    // The first position is row 1 line 1
}

//----------------Display one char----------------
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
//------------------------------------------------
{
    Y &= 0x1;
    X &= 0xF;         // Revise X<=15 Y<=1
    if(Y)                  // Add 0x40 to address for display row 2
    {
        X |= 0x40;
    }
    X |= 0x80;        // Count the address
    WriteCommandLCM(X, 0);    // Send the address to SMC1602A
    WriteDataLCM(DData);       // Write the char to SMC1602A
}

//----------------Display list char---------------
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
//------------------------------------------------
{
    unsigned char ListLength = 0;
    Y &= 0x1;
    X &= 0xF;       // Revise X<=15 Y<=1
    while(DData[ListLength] >= 0x20)     // If the string end, quit
    {
        if(X <= 0xF)
        {
            DisplayOneChar(X, Y, DData[ListLength]); // Display one char
            ListLength++;
            X++;
        }
    }
}




欢迎光临 加我模型论坛 (http://joyrus.com/) Powered by Discuz! X3.2